Power System Platform  2026w34a-beta
Loading...
Searching...
No Matches
Transformer Class Reference

Two-winding transformer power element with OLTC support. More...

#include <Transformer.h>

Inheritance diagram for Transformer:
Collaboration diagram for Transformer:

Public Member Functions

 Transformer (wxString name)
 
virtual Element * GetCopy ()
 Get a the element copy.
 
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, so the parent must be a bus. The element basic points are calculated in this method, so apply this when the element is being inserted.
 
virtual bool Contains (wxPoint2DDouble position) const
 Checks if the element contains a position.
 
virtual void DrawDC (GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
 Draw the element using GDI+.
 
virtual void DrawDC (GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxDC &dc) const
 Draw the element using wxDC.
 
virtual bool Intersects (wxRect2DDouble rect) const
 Check if the element's rect intersects other rect.
 
virtual void Rotate (bool clockwise=true)
 Rotate the element.
 
virtual void Move (wxPoint2DDouble position)
 Move the element other position.
 
virtual void AlignToGrid (double gridSize=20.0) override
 
virtual void MoveNode (Element *parent, wxPoint2DDouble position)
 Move a node. StartMove(wxPoint2DDouble position) before start moving.
 
virtual void StartMove (wxPoint2DDouble position)
 Update the element attributes related to the movement.
 
virtual bool GetContextMenu (wxMenu &menu)
 Get the element contex menu.
 
virtual wxString GetTipText () const
 Get the tip text.
 
virtual void RotateNode (Element *parent, bool clockwise)
 Rotate a node.
 
virtual bool SetNodeParent (Element *parent)
 Set a perent to the node. If all conditions are met, a new parent are added to the element and the points related to the nodes will be calculated.
 
virtual void SetPowerFlowDirection (PowerFlowDirection pfDirection)
 Set the direction of the power flow.
 
virtual bool ShowForm (wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
 Show element data form.
 
virtual TransformerElectricalData GetElectricalData () const
 
virtual TransformerElectricalData & GetElectricalDataRef ()
 
virtual TransformerElectricalData GetPUElectricalData (double systemBasePower) const
 
virtual void SetElectricaData (TransformerElectricalData electricalData)
 
virtual void SetNominalVoltage (std::vector< double > nominalVoltage, std::vector< ElectricalUnit > nominalVoltageUnit)
 Set nominal voltage of the element.
 
virtual void SetBestPositionAndRotation ()
 
virtual rapidxml::xml_node * SaveElement (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementListNode)
 
virtual bool OpenElement (rapidxml::xml_node<> *elementNode, std::vector< Element * > parentList)
 
- Public Member Functions inherited from Branch
virtual bool NodeContains (wxPoint2DDouble position)
 Check if a node contains a point. If contains, set the attributes related to node movement.
 
virtual void RemoveParent (Element *parent)
 Remove a parent.
 
virtual void UpdateNodes ()
 Update the nodes according to the parents. If a parent is removed, use this method.
 
virtual wxCursor GetBestPickboxCursor () const
 Get the best cursor to shown to the user when the mouse is above a pickbox.
 
virtual void MovePickbox (wxPoint2DDouble position)
 Move the pickbox.
 
virtual bool PickboxContains (wxPoint2DDouble position)
 Check if a pickbox contains a point. If contains the attributes related to pickbox movement will be calculated.
 
virtual void AddPoint (wxPoint2DDouble point)
 Add point to the list of points that connect the element to the bus.
 
virtual void UpdateSwitchesPosition ()
 
virtual void UpdateSwitches ()
 Update the switch position.
 
- Public Member Functions inherited from PowerElement
 PowerElement ()
 Constructor.
 
virtual ~PowerElement ()
 Destructor.
 
virtual wxPoint2DDouble GetSwitchPoint (Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
 Get the correct switch position.
 
virtual bool SwitchesContains (wxPoint2DDouble position) const
 Check if switch contains position.
 
virtual void DrawDCSwitches (GUIColour *guiColour, wxGraphicsContext *gc) const
 Draw switch.
 
virtual void DrawDCSwitches (GUIColour *guiColour, wxDC &dc) const
 
virtual void CalculatePowerFlowPts (std::vector< wxPoint2DDouble > edges)
 Calculate the points of the power flow arrows.
 
virtual void DrawDCPowerFlowPts (GUIColour *guiColour, wxGraphicsContext *gc) const
 Draw power flow arrows.
 
virtual void DrawDCPowerFlowPts (GUIColour *guiColour, wxDC &dc) const
 
virtual void SetSwitchingData (SwitchingData data)
 Set the switching data of the element.
 
virtual SwitchingData GetSwitchingData ()
 Returns the switching data of the element.
 
virtual PowerFlowDirection GetPowerFlowDirection () const
 Return the direction of the power flow.
 
virtual bool GetPlotData (ElementPlotData &plotData, PlotStudy study=PlotStudy::STABILITY)
 Fill the plot data.
 
virtual bool HaveDynamicEvent () const
 Check if the power element have dynamic event.
 
virtual void SetDynamicEvent (bool dynEvent=true)
 Set if the power element have dynamic event.
 
virtual double GetValueFromUnit (double value, ElectricalUnit valueUnit) const
 
virtual void SaveCADProperties (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementNode)
 
virtual void SaveSwitchingData (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *electricalNode)
 
virtual bool OpenCADProperties (rapidxml::xml_node<> *elementNode, std::vector< Element * > parentList)
 
virtual bool OpenSwitchingData (rapidxml::xml_node<> *electricalNode)
 
- Public Member Functions inherited from Element
 Element ()
 Constructor.
 
virtual ~Element ()
 Destructor.
 
void SetDragging (bool dragging=true)
 Set if the element are being dragged.
 
void SetHeight (double height)
 Set element height.
 
void SetPosition (const wxPoint2DDouble position)
 Set the element position and update the rectangle.
 
void SetSelected (bool selected=true)
 Set element selection.
 
void SetWidth (double width)
 Set element width.
 
void SetAngle (double angle)
 Set element angle.
 
void ShowPickbox (bool showPickbox=true)
 Set if the pickbox is shown.
 
void SetBorderSize (double borderSize)
 Set the size of the border (shown in selected elements).
 
bool SetOnline (bool online=true)
 Set if the element is online or offline.
 
virtual void SetPointList (std::vector< wxPoint2DDouble > pointList)
 Set the list of points that connect the element to the bus.
 
ElementType GetElementType ()
 
wxRect2DDouble GetRect () const
 Get the element rectangle.
 
wxPoint2DDouble GetPosition () const
 Get the element position.
 
bool IsDragging () const
 Checks if the element is being dragged.
 
double GetHeight () const
 Get the element height.
 
bool IsSelected () const
 Checks if the element is selected.
 
double GetWidth () const
 Get the element width.
 
double GetAngle () const
 Get the element angle.
 
double GetRotationAngle () const
 Get the angle of rotation.
 
bool IsPickboxShown () const
 Checks if the pickbox is shown.
 
bool IsOnline () const
 Checks if the element is online or offline.
 
virtual std::vector< wxPoint2DDouble > GetPointList () const
 Get the list of points that connect the element to bus.
 
virtual std::vector< wxPoint2DDouble > & GetPointListRef ()
 
virtual void AddParent (Element *parent)
 Add a parent to the element.
 
virtual void SetID (int id)
 Set the element ID.
 
virtual int GetID () const
 Get the element ID.
 
virtual void AddChild (Element *child)
 Add a child to the child list.
 
virtual void RemoveChild (Element *child)
 Remove a child from the list.
 
virtual void ReplaceChild (Element *oldChild, Element *newChild)
 Replace a child from the list.
 
void SetParent (Element *parent, int num)
 
void SetChild (Element *child, int num)
 
virtual void ReplaceParent (Element *oldParent, Element *newParent)
 Replace a parent.
 
virtual void ResetPickboxes ()
 Remove the pickboxes.
 
virtual void ResetNodes ()
 Remove the active nodes.
 
virtual wxPoint2DDouble WorldToScreen (wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
 Convert the element position to screen position.
 
virtual wxPoint2DDouble WorldToScreen (wxPoint2DDouble position, wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
 Convert a generic position to screen position.
 
virtual bool RotatedRectanglesIntersects (wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
 Check if two roteted rectangles intersect.
 
virtual void DrawDCRectangle (wxPoint2DDouble position, double width, double height, double angle, wxDC &dc) const
 Draw a circle.
 
virtual void DrawDCRoundedRectRotated (wxDC &dc, const wxPoint2DDouble &center, double width, double height, double radius, double angleDeg, int arcSegments=8) const
 
virtual void DrawDCCircle (wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
 Draw a circle using device context.
 
virtual void DrawDCCircle (wxPoint2DDouble position, double radius, wxDC &dc) const
 
virtual void DrawDCArc (wxPoint2DDouble position, double radius, double initAngle, double finalAngle, int numSegments, wxGraphicsContext *gc) const
 
virtual void DrawDCArc (wxPoint2DDouble position, double radius, double initAngle, double finalAngle, wxDC &dc) const
 
virtual void DrawDCTriangle (std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
 Draw rectangle.
 
virtual void DrawDCTriangle (std::vector< wxPoint > points, wxDC &dc) const
 
virtual void DrawStabilityEventGC (wxGraphicsContext *gc, wxPoint2DDouble translation, double scale, GUIColour *guiColour, bool rotateAnchor=false, wxPoint2DDouble iconPosition=wxPoint2DDouble(-1, -1)) const
 
virtual void DrawDCPickbox (wxPoint2DDouble position, wxGraphicsContext *gc) const
 Draw a point.
 
virtual wxPoint2DDouble RotateAtPosition (wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
 Rotate a point as element position being the origin.
 
virtual wxPoint2DDouble RotateLocal (wxPoint2DDouble local, double angleDeg) const
 
virtual wxPoint RotateAround (const wxPoint2DDouble &p, const wxPoint2DDouble &center, double angleDeg) const
 
virtual std::vector< Element * > GetParentList () const
 Get the parent list.
 
virtual std::vector< Element * > GetChildList () const
 Get the Child list.
 
virtual wxPoint2DDouble GetMoveStartPosition () const
 
virtual wxPoint2DDouble GetMovePosition () const
 
virtual void CalculateBoundaries (wxPoint2DDouble &leftUp, wxPoint2DDouble &rightBottom) const
 Calculate the element boundaries.
 
virtual void GeneralMenuItens (wxMenu &menu)
 Insert general itens to context menu.
 
virtual double PointToLineDistance (wxPoint2DDouble point, int *segmentNumber=nullptr) const
 Calculate the distance between a line (formed by point list) and a point.
 
bool IsInserted () const
 Check if the element is properly inserted in the workspace.
 
void SetInserted (bool inserted=true)
 Set if the element is properly inserted in the workspace.
 
virtual bool OpenElement (rapidxml::xml_node<> *elementNode)
 
void SaveCADProperties (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementNode)
 
bool OpenCADProperties (rapidxml::xml_node<> *elementNode)
 

Protected Member Functions

void UpdatePowerFlowArrowsPosition ()
 

Protected Attributes

TransformerElectricalData m_electricalData
 
- Protected Attributes inherited from PowerElement
SwitchingData m_swData
 
std::vector< std::vector< wxPoint2DDouble > > m_powerFlowArrow
 
PowerFlowDirection m_pfDirection = PowerFlowDirection::PF_NONE
 
wxColour m_busColour
 
wxColour m_onlineElementColour
 
wxColour m_offlineElementColour
 
wxColour m_closedSwitchColour
 
wxColour m_openedSwitchColour
 
wxColour m_powerFlowArrowColour
 
wxColour m_dynamicEventColour
 
bool m_dynEvent = false
 
- Protected Attributes inherited from Element
ElementType m_elementType = ElementType::TYPE_NONE
 
int m_elementID = 0
 
std::vector< Element * > m_parentList
 
std::vector< Element * > m_childList
 
wxRect2DDouble m_rect
 
wxPoint2DDouble m_position
 
double m_width = 0.0
 
double m_height = 0.0
 
double m_angle = 0.0
 
double m_borderSize = 2.0
 
double m_rotationAngle = 45.0
 
double m_switchSize = 10.0
 
std::vector< wxRect2DDouble > m_switchRect
 
bool m_selected = false
 
bool m_dragging = false
 
bool m_showPickbox = false
 
bool m_inserted = false
 
int m_activePickboxID = ID_PB_NONE
 
int m_activeNodeID = 0
 
std::vector< wxPoint2DDouble > m_pointList
 
std::vector< wxPoint2DDouble > m_movePts
 
wxPoint2DDouble m_moveStartPt
 
wxPoint2DDouble m_movePos
 
bool m_online = true
 

Additional Inherited Members

- Static Public Member Functions inherited from Element
static bool DoubleFromString (wxWindow *parent, wxString strValue, double &value, wxString errorMsg)
 Get a double value from a string. Show a error message if the conversion fail.
 
static bool IntFromString (wxWindow *parent, wxString strValue, int &value, wxString errorMsg)
 Convert a string to int. Show a error message if the conversion fail.
 
static wxString StringFromDouble (double value, int minDecimal=1, int maxDecimals=13)
 Convert a double value to string.
 

Detailed Description

Two-winding transformer power element with OLTC support.

Author
Thales Lima Oliveira thale.nosp@m.s@uf.nosp@m.u.br
Luiz Gonzaga Rocha Junior luizg.nosp@m.rj@g.nosp@m.mail..nosp@m.com
Date
06/10/2017

Definition at line 95 of file Transformer.h.

Constructor & Destructor Documentation

◆ Transformer() [1/2]

Transformer::Transformer ( )

Definition at line 21 of file Transformer.cpp.

21 : Branch()
22{
23 m_elementType = TYPE_TRANSFORMER;
24 for (int i = 0; i < 2; i++) {
25 for (int j = 0; j < 3; j++) { m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0); }
26 }
27}
Abstract class for branch power elements.
Definition Branch.h:32

◆ Transformer() [2/2]

Transformer::Transformer ( wxString  name)

Definition at line 28 of file Transformer.cpp.

28 : Branch()
29{
30 m_elementType = TYPE_TRANSFORMER;
31 for (int i = 0; i < 2; i++) {
32 for (int j = 0; j < 3; j++) { m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0); }
33 }
34 m_electricalData.name = name;
35}

◆ ~Transformer()

Transformer::~Transformer ( )
virtual

Definition at line 36 of file Transformer.cpp.

36{}

Member Function Documentation

◆ AddParent()

bool Transformer::AddParent ( Element *  parent,
wxPoint2DDouble  position,
bool  isOpening = false 
)
virtual

Add a parent to the element. This method must be used on power elements that connect to a bus, so the parent must be a bus. The element basic points are calculated in this method, so apply this when the element is being inserted.

Parameters
parentElement parent.
positionNode position in the parent.

Reimplemented from Element.

Definition at line 38 of file Transformer.cpp.

39{
40 if (parent) {
41 // First bus.
42 if (m_parentList.size() == 0) {
43 m_position = position;
44 m_parentList.push_back(parent);
45 parent->AddChild(this);
46
47 wxPoint2DDouble parentPt = parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position
48 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
49 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
50
51 m_pointList.push_back(parentPt); // First point
52 m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
53
54 wxRect2DDouble genRect(0, 0, 0, 0);
55 m_switchRect.push_back(genRect);
56
57 return false;
58 }
59
60 // Second bus.
61 else if (parent != m_parentList[0]) {
62 m_parentList.push_back(parent);
63 parent->AddChild(this);
64
65 wxPoint2DDouble parentPt = parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
66 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
67
68 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
69
70 if (isOpening) {
71 m_width = 70.0;
72 m_height = 40.0;
73
74 m_position = wxPoint2DDouble(
75 (m_pointList[0].m_x + parentPt.m_x) / 2.0,
76 (m_pointList[0].m_y + parentPt.m_y) / 2.0);
77
78 SetPosition(m_position);
79
80 wxPoint2DDouble term1 =
81 m_position +
82 RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
83
84 wxPoint2DDouble term2 =
85 m_position +
86 RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
87
88 m_pointList.push_back(term1);
89 m_pointList.push_back(term2);
90
91 m_pointList[1] =
93 m_parentList[0],
94 m_pointList[0],
95 term1);
96
97 m_pointList.push_back(
99 parent,
100 parentPt,
101 term2));
102
103 m_pointList.push_back(parentPt);
104 m_inserted = true;
105
106 wxRect2DDouble genRect(0, 0, 0, 0);
107 m_switchRect.push_back(genRect);
108
110 UpdatePowerFlowArrowsPosition();
111
112 return true;
113 }
114
115 // Normal insertion: determine position and rotation automatically.
116 wxPoint2DDouble p1 = m_pointList[0];
117 wxPoint2DDouble p2 = parentPt;
118
119 double dx = p2.m_x - p1.m_x;
120 double dy = p2.m_y - p1.m_y;
121
122 // Determine orientation based on bus separation.
123 if (std::abs(dy) > std::abs(dx)) {
124 m_angle = (dy >= 0.0) ? 90.0 : 270.0;
125 }
126 else {
127 m_angle = (dx >= 0.0) ? 0.0 : 180.0;
128 }
129
130 // Get the midpoint between the two bus points.
131 m_position = wxPoint2DDouble((p1.m_x + p2.m_x) / 2.0, (p1.m_y + p2.m_y) / 2.0);
132
133 // Snap position to grid alignment.
134 if (std::abs(dx) < 1.0) {
135 m_position.m_x = p1.m_x;
136 m_position.m_y = std::round(m_position.m_y / 20.0) * 20.0;
137 }
138 else if (std::abs(dy) < 1.0) {
139 m_position.m_y = p1.m_y;
140 m_position.m_x = std::round(m_position.m_x / 20.0) * 20.0;
141 }
142 else {
143 m_position.m_x = std::round(m_position.m_x / 20.0) * 20.0;
144 m_position.m_y = std::round(m_position.m_y / 20.0) * 20.0;
145 }
146
147 // Check whether a point belongs to the rotated bus rectangle.
148 //
149 // The point is first transformed into the local coordinate
150 // system of the bus. In that system:
151 // X -> bus width
152 // Y -> bus height
153 //
154 // This makes the test independent of the bus rotation.
155 auto IsPointInsideBus = [](Element* bus, const wxPoint2DDouble& point) -> bool {
156 wxPoint2DDouble delta(
157 point.m_x - bus->GetPosition().m_x,
158 point.m_y - bus->GetPosition().m_y);
159
160 wxPoint2DDouble local =
161 bus->RotateLocal(delta, -bus->GetAngle());
162
163 double halfWidth = bus->GetWidth() / 2.0 + 2.0;
164 double halfHeight = bus->GetHeight() / 2.0 + 2.0;
165
166 return std::abs(local.m_x) <= halfWidth &&
167 std::abs(local.m_y) <= halfHeight;
168 };
169
170 if (std::abs(dy) > std::abs(dx)) {
171 // Transformer is vertically oriented.
172 // Keep the connection points aligned in X.
173 wxPoint2DDouble candidate1(m_position.m_x, m_parentList[0]->GetPosition().m_y);
174
175 wxPoint2DDouble candidate2(m_position.m_x, parent->GetPosition().m_y);
176
177 if (IsPointInsideBus(m_parentList[0], candidate1) && IsPointInsideBus(parent, candidate2)) {
178 m_pointList[0].m_x = m_position.m_x;
179 parentPt.m_x = m_position.m_x;
180 }
181 }
182 else {
183 // Transformer is horizontally oriented.
184 // Keep the connection points aligned in Y.
185 wxPoint2DDouble candidate1(m_parentList[0]->GetPosition().m_x, m_position.m_y);
186
187 wxPoint2DDouble candidate2(parent->GetPosition().m_x, m_position.m_y);
188
189 if (IsPointInsideBus(m_parentList[0], candidate1) &&
190 IsPointInsideBus(parent, candidate2)) {
191
192 m_pointList[0].m_y = m_position.m_y;
193 parentPt.m_y = m_position.m_y;
194 }
195 }
196
197 // Set the transformer rectangle.
198 m_width = 70.0;
199 m_height = 40.0;
200
201 SetPosition(m_position); // This method calculates the rectangle properly.
202
203 // Set the terminals at 40.0 units offset (2 grid cells),
204 // rotated by m_angle.
205 wxPoint2DDouble term1 = m_position + RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
206
207 wxPoint2DDouble term2 = m_position + RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
208
209 term1.m_x = std::round(term1.m_x);
210 term1.m_y = std::round(term1.m_y);
211
212 term2.m_x = std::round(term2.m_x);
213 term2.m_y = std::round(term2.m_y);
214
215 m_pointList.push_back(term1);
216 m_pointList.push_back(term2);
217
218 // Set first switch point.
219 m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], term1);
220
221 // Set the second switch point.
222 m_pointList.push_back(GetSwitchPoint(parent, parentPt, term2));
223
224 m_pointList.push_back(parentPt); // Last point.
225 m_inserted = true;
226
227 wxRect2DDouble genRect(0, 0, 0, 0);
228 m_switchRect.push_back(genRect);
229
231 UpdatePowerFlowArrowsPosition();
232
233 return true;
234 }
235 }
236
237 return false;
238}
virtual void UpdateSwitches()
Update the switch position.
Definition Branch.cpp:179
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:115
double GetWidth() const
Get the element width.
Definition Element.h:209
wxPoint2DDouble GetPosition() const
Get the element position.
Definition Element.h:189
double GetAngle() const
Get the element angle.
Definition Element.h:214
double GetHeight() const
Get the element height.
Definition Element.h:199
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
Definition Element.cpp:33
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition Element.cpp:298
virtual void AddChild(Element *child)
Add a child to the child list.
Definition Element.cpp:581
virtual wxPoint2DDouble GetSwitchPoint(Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
Get the correct switch position.
Here is the call graph for this function:

◆ AlignToGrid()

void Transformer::AlignToGrid ( double  gridSize = 20.0)
overridevirtual

Reimplemented from Element.

Definition at line 540 of file Transformer.cpp.

541{
542 if (gridSize <= 0.0)
543 gridSize = 20.0;
544
545 // 1. Snap center position to grid.
546 m_position.m_x = std::round(m_position.m_x / gridSize) * gridSize;
547 m_position.m_y = std::round(m_position.m_y / gridSize) * gridSize;
548
549 SetPosition(m_position);
550
551 // 2. Rigidly attach terminals at 40.0 units offset.
552 if (m_pointList.size() >= 4) {
553 wxPoint2DDouble t1 = m_position + RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
554 wxPoint2DDouble t2 = m_position + RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
555 m_pointList[2] = wxPoint2DDouble(std::round(t1.m_x), std::round(t1.m_y));
556 m_pointList[3] = wxPoint2DDouble(std::round(t2.m_x), std::round(t2.m_y));
557 }
558
559 // Transformer orientation.
560 bool isVertical = (std::abs(m_angle - 90.0) < 1.0 || std::abs(m_angle - 270.0) < 1.0);
561
562 // Check whether a point belongs to the rotated bus rectangle.
563 auto IsPointInsideBus =
564 [](Element* bus, const wxPoint2DDouble& point) -> bool
565 {
566 wxPoint2DDouble delta(point.m_x - bus->GetPosition().m_x, point.m_y - bus->GetPosition().m_y);
567
568 // Transform the point into the local coordinate
569 // system of the bus.
570 wxPoint2DDouble local = bus->RotateLocal(delta, -bus->GetAngle());
571
572 double halfWidth = bus->GetWidth() / 2.0 + 2.0;
573 double halfHeight = bus->GetHeight() / 2.0 + 2.0;
574
575 return std::abs(local.m_x) <= halfWidth && std::abs(local.m_y) <= halfHeight;
576 };
577
578 // 3. Align first bus contact point.
579 if (m_parentList.size() > 0 && m_parentList[0] && !m_pointList.empty()) {
580
581 Element* bus1 = m_parentList[0];
582
583 if (isVertical) {
584 // Candidate point obtained by aligning X with the
585 // transformer center.
586 wxPoint2DDouble candidate(m_position.m_x, bus1->GetPosition().m_y);
587
588 if (IsPointInsideBus(bus1, candidate)) {
589 m_pointList[0].m_x = m_position.m_x;
590 }
591
592 // Snap the longitudinal coordinate to the grid.
593 m_pointList[0].m_y = std::round(m_pointList[0].m_y / gridSize) * gridSize;
594 }
595 else {
596 // Candidate point obtained by aligning Y with the
597 // transformer center.
598 wxPoint2DDouble candidate(bus1->GetPosition().m_x, m_position.m_y);
599
600 if (IsPointInsideBus(bus1, candidate)) {
601 m_pointList[0].m_y = m_position.m_y;
602 }
603
604 // Snap the longitudinal coordinate to the grid.
605 m_pointList[0].m_x = std::round(m_pointList[0].m_x / gridSize) * gridSize;
606 }
607 }
608 else if (!m_pointList.empty()) {
609 m_pointList[0].m_x = std::round(m_pointList[0].m_x / gridSize) * gridSize;
610
611 m_pointList[0].m_y = std::round(m_pointList[0].m_y / gridSize) * gridSize;
612 }
613
614 // 4. Align second bus contact point.
615 if (m_parentList.size() > 1 &&
616 m_parentList[1] &&
617 !m_pointList.empty()) {
618
619 Element* bus2 = m_parentList[1];
620
621 if (isVertical) {
622 // Candidate point obtained by aligning X with the
623 // transformer center.
624 wxPoint2DDouble candidate(m_position.m_x, bus2->GetPosition().m_y);
625
626 if (IsPointInsideBus(bus2, candidate)) {
627 m_pointList.back().m_x = m_position.m_x;
628 }
629
630 // Snap the longitudinal coordinate to the grid.
631 m_pointList.back().m_y = std::round(m_pointList.back().m_y / gridSize) * gridSize;
632 }
633 else {
634 // Candidate point obtained by aligning Y with the
635 // transformer center.
636 wxPoint2DDouble candidate(bus2->GetPosition().m_x, m_position.m_y);
637
638 if (IsPointInsideBus(bus2, candidate)) {
639 m_pointList.back().m_y = m_position.m_y;
640 }
641
642 // Snap the longitudinal coordinate to the grid.
643 m_pointList.back().m_x = std::round(m_pointList.back().m_x / gridSize) * gridSize;
644 }
645 }
646 else if (m_pointList.size() > 1) {
647 m_pointList.back().m_x = std::round(m_pointList.back().m_x / gridSize) * gridSize;
648
649 m_pointList.back().m_y = std::round(m_pointList.back().m_y / gridSize) * gridSize;
650 }
651
652 UpdateSwitchesPosition();
653 UpdatePowerFlowArrowsPosition();
654}

◆ Contains()

bool Transformer::Contains ( wxPoint2DDouble  position) const
virtual

Checks if the element contains a position.

Parameters
positionPosition to be checked.

Reimplemented from Branch.

Definition at line 240 of file Transformer.cpp.

241{
242 wxPoint2DDouble ptR = RotateAtPosition(position, -m_angle);
243 return m_rect.Contains(ptR);
244}
Here is the call graph for this function:

◆ DrawDC() [1/2]

void Transformer::DrawDC ( GUIColour *  guiColour,
wxPoint2DDouble  translation,
double  scale,
wxDC &  dc 
) const
virtual

Draw the element using wxDC.

Parameters
guiColourColours of the system defined in properties.
translationTranslation of the system.
scaleScale of the system.
dcDevice context.

Reimplemented from Element.

Definition at line 414 of file Transformer.cpp.

415{
416 wxColour elementColour;
417 if (m_online) {
418 if (m_dynEvent)
419 elementColour = guiColour->eventElement;
420 else
421 elementColour = guiColour->enabled;
422 }
423 else
424 elementColour = guiColour->disable;
425
426 std::vector<wxPoint> pointList;
427 for (auto& pt : m_pointList) { pointList.emplace_back(static_cast<int>(pt.m_x), static_cast<int>(pt.m_y)); }
428
429 if (m_inserted) {
430 // Draw selection (layer 1).
431 if (m_selected) {
432 dc.SetPen(wxPen(wxColour(guiColour->selection), 2 + m_borderSize * 2.0));
433 dc.SetBrush(*wxTRANSPARENT_BRUSH);
434 dc.DrawLines(pointList.size(), &pointList[0]);
435
436 dc.SetPen(*wxTRANSPARENT_PEN);
437 dc.SetBrush(wxBrush(guiColour->selection));
438 //DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(20.0, 20.0), 20 + (m_borderSize + 1.5) / scale, dc);
439 //DrawDCCircle(m_rect.GetPosition() + wxPoint2DDouble(50.0, 20.0), 20 + (m_borderSize + 1.5) / scale, dc);
440 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(15.0, 0.0), m_angle), 20 + (m_borderSize + 1.5) / scale, dc);
441 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(-15.0, 0.0), m_angle), 20 + (m_borderSize + 1.5) / scale, dc);
442
443 // Draw nodes selection.
444 dc.SetPen(*wxTRANSPARENT_PEN);
445 dc.SetBrush(wxBrush(guiColour->selection));
446 if (pointList.size() > 0) {
447 DrawDCCircle(pointList[0], 5.0 + m_borderSize / scale, dc);
448 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, dc); }
449 }
450 }
451
452 // Draw transformer (layer 2).
453 // Transformer line
454 dc.SetPen(wxPen(elementColour, 2));
455 dc.SetBrush(*wxTRANSPARENT_BRUSH);
456 dc.DrawLines(pointList.size(), &pointList[0]);
457
458 // Draw nodes.
459 dc.SetPen(*wxTRANSPARENT_PEN);
460 dc.SetBrush(wxBrush(elementColour));
461 if (pointList.size() > 0) {
462 DrawDCCircle(pointList[0], 5.0, dc);
463 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0, dc); }
464 }
465
466 DrawDCSwitches(guiColour, dc);
467 DrawDCPowerFlowPts(guiColour, dc);
468
469 dc.SetPen(*wxTRANSPARENT_PEN);
470 dc.SetBrush(wxBrush(guiColour->background));
471 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(15.0, 0.0), m_angle), 20, dc);
472 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(-15.0, 0.0), m_angle), 20, dc);
473
474 dc.SetPen(wxPen(elementColour, 2));
475 dc.SetBrush(*wxTRANSPARENT_BRUSH);
476 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(15.0, 0.0), m_angle), 20, dc);
477 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(-15.0, 0.0), m_angle), 20, dc);
478
479 // Point
480 dc.SetPen(*wxTRANSPARENT_PEN);
481 dc.SetBrush(wxBrush(elementColour));
482 DrawDCCircle(m_position + RotateLocal(wxPoint2DDouble(-35, -20), m_angle), 4, dc);
483 }
484}
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Definition Element.cpp:173
virtual void DrawDCPowerFlowPts(GUIColour *guiColour, wxGraphicsContext *gc) const
Draw power flow arrows.
virtual void DrawDCSwitches(GUIColour *guiColour, wxGraphicsContext *gc) const
Draw switch.
Here is the call graph for this function:

◆ DrawDC() [2/2]

void Transformer::DrawDC ( GUIColour *  guiColour,
wxPoint2DDouble  translation,
double  scale,
wxGraphicsContext *  gc 
) const
virtual

Draw the element using GDI+.

Parameters
guiColourColours of the system defined in properties.
translationTranslation of the system.
scaleScale of the system.
gcGraphics context

Reimplemented from Element.

Definition at line 324 of file Transformer.cpp.

325{
326 wxColour elementColour;
327 if (m_online) {
328 //if (m_dynEvent)
329 // elementColour = guiColour->eventElement;
330 //else
331 elementColour = guiColour->enabled;
332 }
333 else
334 elementColour = guiColour->disable;
335
336 if (m_inserted) {
337 // Draw selection (layer 1).
338 if (m_selected) {
339 gc->SetPen(wxPen(guiColour->selection, 2 + m_borderSize * 2.0));
340 gc->SetBrush(*wxTRANSPARENT_BRUSH);
341 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
342
343 // Push the current matrix on stack.
344 gc->PushState();
345 // Rotate the matrix around the object position.
346 gc->Translate(m_position.m_x, m_position.m_y);
347 gc->Rotate(wxDegToRad(m_angle));
348 gc->Translate(-m_position.m_x, -m_position.m_y);
349
350 gc->SetPen(*wxTRANSPARENT_PEN);
351 gc->SetBrush(wxBrush(guiColour->selection));
352 DrawDCCircle(m_position + wxPoint2DDouble(-15.0, 0.0), 20 + (m_borderSize + 1.5) / scale, 20, gc);
353 DrawDCCircle(m_position + wxPoint2DDouble(15.0, 0.0), 20 + (m_borderSize + 1.5) / scale, 20, gc);
354
355 gc->PopState();
356
357 // Draw nodes selection.
358 gc->SetPen(*wxTRANSPARENT_PEN);
359 gc->SetBrush(wxBrush(guiColour->selection));
360 if (m_pointList.size() > 0) {
361 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
362 if (m_inserted) { DrawDCCircle(m_pointList[m_pointList.size() - 1], 5.0 + m_borderSize / scale, 10, gc); }
363 }
364 }
365
366 // Draw transformer (layer 2).
367 // Transformer line
368 gc->SetPen(wxPen(elementColour, 2));
369 gc->SetBrush(*wxTRANSPARENT_BRUSH);
370 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
371
372 // Draw nodes.
373 gc->SetPen(*wxTRANSPARENT_PEN);
374 gc->SetBrush(wxBrush(elementColour));
375 if (m_pointList.size() > 0) {
376 DrawDCCircle(m_pointList[0], 5.0, 10, gc);
377 if (m_inserted) { DrawDCCircle(m_pointList[m_pointList.size() - 1], 5.0, 10, gc); }
378 }
379
380 DrawDCSwitches(guiColour, gc);
381 DrawDCPowerFlowPts(guiColour, gc);
382
383 // Push the current matrix on stack.
384 gc->PushState();
385 // Rotate the matrix around the object position.
386 gc->Translate(m_position.m_x, m_position.m_y);
387 gc->Rotate(wxDegToRad(m_angle));
388 gc->Translate(-m_position.m_x, -m_position.m_y);
389
390 //glColor4d(1.0, 1.0, 1.0, 1.0);
391 gc->SetPen(*wxTRANSPARENT_PEN);
392 gc->SetBrush(wxBrush(guiColour->background));
393 DrawDCCircle(m_position + wxPoint2DDouble(-15.0, 0.0), 20, 20, gc);
394 DrawDCCircle(m_position + wxPoint2DDouble(15.0, 0.0), 20, 20, gc);
395
396 gc->SetPen(wxPen(elementColour, 2));
397 gc->SetBrush(*wxTRANSPARENT_BRUSH);
398 DrawDCCircle(m_position + wxPoint2DDouble(-15.0, 0.0), 20, 20, gc);
399 DrawDCCircle(m_position + wxPoint2DDouble(15.0, 0.0), 20, 20, gc);
400
401 // Point
402 gc->SetPen(*wxTRANSPARENT_PEN);
403 gc->SetBrush(wxBrush(elementColour));
404 DrawDCCircle(m_rect.GetPosition(), 4, 10, gc);
405
406 gc->PopState();
407
408 if (m_dynEvent) {
409 DrawStabilityEventGC(gc, translation, scale, guiColour);
410 }
411 }
412}
Here is the call graph for this function:

◆ GetContextMenu()

bool Transformer::GetContextMenu ( wxMenu &  menu)
virtual

Get the element contex menu.

Parameters
menumenu that will be inserted the element itens.
Returns
True if was possible to build the menu, false otherwise.

Reimplemented from Branch.

Definition at line 699 of file Transformer.cpp.

700{
701 menu.Append(ID_EDIT_ELEMENT, _("Edit tranformer"));
702
703 wxString busName[2] = { "?", "?" };
704 if (m_parentList.size() == 2) {
705 int i = 0;
706 for (Element* element : m_parentList) {
707 if (element) {
708 Bus* bus = static_cast<Bus*>(element);
709 busName[i] = bus->GetElectricalData().name;
710 }
711 i++;
712 }
713 }
714
715 wxMenu* textMenu = new wxMenu();
716
717 textMenu->Append(ID_TXT_NAME, _("Name"));
718 textMenu->Append(ID_TXT_BRANCH_ACTIVE_POWER_1_2, _("Active power (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
719 textMenu->Append(ID_TXT_BRANCH_ACTIVE_POWER_2_1, _("Active power (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
720 textMenu->Append(ID_TXT_BRANCH_REACTIVE_POWER_1_2, _("Reactive power (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
721 textMenu->Append(ID_TXT_BRANCH_REACTIVE_POWER_2_1, _("Reactive power (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
722 textMenu->Append(ID_TXT_BRANCH_LOSSES, _("Losses"));
723 textMenu->Append(ID_TXT_BRANCH_CURRENT_1_2, _("Current (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
724 textMenu->Append(ID_TXT_BRANCH_CURRENT_2_1, _("Current (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
725 textMenu->Append(ID_TXT_BRANCH_FAULT_CURRENT_1_2, _("Fault current (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
726 textMenu->Append(ID_TXT_BRANCH_FAULT_CURRENT_2_1, _("Fault current (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
727 textMenu->Append(ID_TXT_TAP, _("Tap"));
728 textMenu->SetClientData(menu.GetClientData());
729 menu.AppendSubMenu(textMenu, _("Add text"));
730
731 GeneralMenuItens(menu);
732 return true;
733}
@ ID_EDIT_ELEMENT
Definition Element.h:77
Node for power elements. All others power elements are connected through this.
Definition Bus.h:87
virtual void GeneralMenuItens(wxMenu &menu)
Insert general itens to context menu.
Definition Element.cpp:475
Here is the call graph for this function:

◆ GetCopy()

Element * Transformer::GetCopy ( )
virtual

Get a the element copy.

Returns
Copy of the element.

Reimplemented from Element.

Definition at line 864 of file Transformer.cpp.

865{
866 Transformer* copy = new Transformer();
867 *copy = *this;
868 return copy;
869}
Two-winding transformer power element with OLTC support.
Definition Transformer.h:96

◆ GetElectricalData()

virtual TransformerElectricalData Transformer::GetElectricalData ( ) const
inlinevirtual

Definition at line 120 of file Transformer.h.

120{ return m_electricalData; }

◆ GetElectricalDataRef()

virtual TransformerElectricalData & Transformer::GetElectricalDataRef ( )
inlinevirtual

Definition at line 121 of file Transformer.h.

121{ return m_electricalData; }

◆ GetPUElectricalData()

TransformerElectricalData Transformer::GetPUElectricalData ( double  systemBasePower) const
virtual

Definition at line 940 of file Transformer.cpp.

941{
943
944 data.name = m_electricalData.name;
945
946 data.nominalPower = m_electricalData.nominalPower;
947 data.nominalPowerUnit = m_electricalData.nominalPowerUnit;
948
949 data.primaryNominalVoltage = m_electricalData.primaryNominalVoltage;
950 data.primaryNominalVoltageUnit = m_electricalData.primaryNominalVoltageUnit;
951
952 data.secondaryNominalVoltage = m_electricalData.secondaryNominalVoltage;
953 data.secondaryNominalVoltageUnit = m_electricalData.secondaryNominalVoltageUnit;
954
955 data.useTransformerPower = m_electricalData.useTransformerPower;
956
957 data.baseVoltage = m_electricalData.baseVoltage;
958
959 data.resistance = m_electricalData.resistance;
960 data.resistanceUnit = m_electricalData.resistanceUnit;
961
962 data.indReactance = m_electricalData.indReactance;
963 data.indReactanceUnit = m_electricalData.indReactanceUnit;
964
965 data.connection = m_electricalData.connection;
966 data.turnsRatio = m_electricalData.turnsRatio;
967 data.phaseShift = m_electricalData.phaseShift;
968
969 data.hasTapChanger = m_electricalData.hasTapChanger;
970 data.nominalTurnsRatio = m_electricalData.nominalTurnsRatio;
971 data.oltcControlledBus = m_electricalData.oltcControlledBus;
972 data.oltcTargetVoltage = m_electricalData.oltcTargetVoltage;
973 data.oltcVoltageDeadband = m_electricalData.oltcVoltageDeadband;
974 data.oltcMinTap = m_electricalData.oltcMinTap;
975 data.oltcMaxTap = m_electricalData.oltcMaxTap;
976 data.oltcTapStep = m_electricalData.oltcTapStep;
977 data.oltcIsDiscrete = m_electricalData.oltcIsDiscrete;
978
979 data.zeroResistance = m_electricalData.zeroResistance;
980 data.zeroIndReactance = m_electricalData.zeroIndReactance;
981
982 data.primaryGrndResistance = m_electricalData.primaryGrndResistance;
983 data.primaryGrndReactance = m_electricalData.primaryGrndReactance;
984
985 data.secondaryGrndResistance = m_electricalData.secondaryGrndResistance;
986 data.secondaryGrndReactance = m_electricalData.secondaryGrndReactance;
987
988 data.powerFlow[0] = m_electricalData.powerFlow[0];
989 data.powerFlow[1] = m_electricalData.powerFlow[1];
990
991 data.faultCurrent[0][0] = m_electricalData.faultCurrent[0][0];
992 data.faultCurrent[0][1] = m_electricalData.faultCurrent[0][1];
993 data.faultCurrent[0][2] = m_electricalData.faultCurrent[0][2];
994 data.faultCurrent[1][0] = m_electricalData.faultCurrent[1][0];
995 data.faultCurrent[1][1] = m_electricalData.faultCurrent[1][1];
996 data.faultCurrent[1][2] = m_electricalData.faultCurrent[1][2];
997
998
999 data.harmonicOrder = m_electricalData.harmonicOrder;
1000 data.harmonicCurrent[0] = m_electricalData.harmonicCurrent[0];
1001 data.harmonicCurrent[1] = m_electricalData.harmonicCurrent[1];
1002
1003 double transformerBasePower = GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
1004 double baseVoltage = 0.0;
1005 if (data.baseVoltage == 0) {
1006 baseVoltage = GetValueFromUnit(data.primaryNominalVoltage, data.primaryNominalVoltageUnit);
1007 }
1008 else {
1009 baseVoltage = GetValueFromUnit(data.secondaryNominalVoltage, data.secondaryNominalVoltageUnit);
1010 }
1011 double systemBaseImpedance = (baseVoltage * baseVoltage) / systemBasePower;
1012 double transformerBaseImpedance = (baseVoltage * baseVoltage) / transformerBasePower;
1013
1014 // Resistance
1015 double r = data.resistance;
1016 if (data.resistanceUnit == ElectricalUnit::UNIT_PU) {
1017 if (data.useTransformerPower) data.resistance = (r * transformerBaseImpedance) / systemBaseImpedance;
1018 }
1019 else {
1020 data.resistance = r / systemBaseImpedance;
1021 }
1022 data.resistanceUnit = ElectricalUnit::UNIT_PU;
1023
1024 // Indutive reactance
1025 double x = data.indReactance;
1026 if (data.indReactanceUnit == ElectricalUnit::UNIT_PU) {
1027 if (data.useTransformerPower) data.indReactance = (x * transformerBaseImpedance) / systemBaseImpedance;
1028 }
1029 else {
1030 data.indReactance = x / systemBaseImpedance;
1031 }
1032 data.indReactanceUnit = ElectricalUnit::UNIT_PU;
1033
1034 // Fault
1035
1036 // Zero seq. resistance
1037 double r0 = data.zeroResistance;
1038 if (data.useTransformerPower) data.zeroResistance = (r0 * transformerBaseImpedance) / systemBaseImpedance;
1039
1040 // Zero seq. ind. reactance
1041 double x0 = data.zeroIndReactance;
1042 if (data.useTransformerPower) data.zeroIndReactance = (x0 * transformerBaseImpedance) / systemBaseImpedance;
1043
1044 // Primary ground resistance
1045 double rgp = data.primaryGrndResistance;
1046 if (data.useTransformerPower) data.primaryGrndResistance = (rgp * transformerBaseImpedance) / systemBaseImpedance;
1047
1048 // Primary ground ind reactance
1049 double xgp = data.primaryGrndReactance;
1050 if (data.useTransformerPower) data.primaryGrndReactance = (xgp * transformerBaseImpedance) / systemBaseImpedance;
1051
1052 // Secondary ground resistance
1053 double rgs = data.secondaryGrndResistance;
1054 if (data.useTransformerPower) data.secondaryGrndResistance = (rgs * transformerBaseImpedance) / systemBaseImpedance;
1055
1056 // Secondary ground ind reactance
1057 double xgs = data.secondaryGrndReactance;
1058 if (data.useTransformerPower) data.secondaryGrndReactance = (xgs * transformerBaseImpedance) / systemBaseImpedance;
1059
1060 if (!m_online) {
1061 data.powerFlow[0] = std::complex<double>(0, 0);
1062 data.powerFlow[1] = std::complex<double>(0, 0);
1063 data.faultCurrent[0][0] = std::complex<double>(0, 0);
1064 data.faultCurrent[0][1] = std::complex<double>(0, 0);
1065 data.faultCurrent[0][2] = std::complex<double>(0, 0);
1066 data.faultCurrent[1][0] = std::complex<double>(0, 0);
1067 data.faultCurrent[1][1] = std::complex<double>(0, 0);
1068 data.faultCurrent[1][2] = std::complex<double>(0, 0);
1069 }
1070
1071 return data;
1072}

◆ GetTipText()

wxString Transformer::GetTipText ( ) const
virtual

Get the tip text.

Returns
Tip text.

Reimplemented from Element.

Definition at line 871 of file Transformer.cpp.

872{
873 wxString tipText = m_electricalData.name;
874 wxString primVoltage = StringFromDouble(m_electricalData.primaryNominalVoltage);
875 switch (m_electricalData.primaryNominalVoltageUnit) {
876 case ElectricalUnit::UNIT_V: {
877 primVoltage += _(" V");
878 } break;
879 case ElectricalUnit::UNIT_kV: {
880 primVoltage += _(" kV");
881 } break;
882 default:
883 break;
884 }
885 wxString secVoltage = StringFromDouble(m_electricalData.secondaryNominalVoltage);
886 switch (m_electricalData.secondaryNominalVoltageUnit) {
887 case ElectricalUnit::UNIT_V: {
888 secVoltage += _(" V");
889 } break;
890 case ElectricalUnit::UNIT_kV: {
891 secVoltage += _(" kV");
892 } break;
893 default:
894 break;
895 }
896
897 tipText += "\n" + primVoltage + " / " + secVoltage;
898
899 if (m_online) {
900 tipText += "\n";
901 int busNumber[2];
902 busNumber[0] = static_cast<Bus*>(m_parentList[0])->GetElectricalData().number + 1;
903 busNumber[1] = static_cast<Bus*>(m_parentList[1])->GetElectricalData().number + 1;
904
905 tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
906 wxString::FromDouble(m_electricalData.powerFlow[0].real(), 5) + _(" p.u.");
907 tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
908 wxString::FromDouble(m_electricalData.powerFlow[0].imag(), 5) + _(" p.u.");
909 tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
910 wxString::FromDouble(m_electricalData.powerFlow[1].real(), 5) + _(" p.u.");
911 tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
912 wxString::FromDouble(m_electricalData.powerFlow[1].imag(), 5) + _(" p.u.");
913
914 if (m_electricalData.hasTapChanger) {
915 tipText += _("\nOLTC: Enabled (Vset = ") +
916 wxString::FromDouble(m_electricalData.oltcTargetVoltage, 3) +
917 _(" p.u., Tap = ") +
918 wxString::FromDouble(m_electricalData.turnsRatio, 4) +
919 _(" p.u.)");
920 }
921
922 if (!m_electricalData.harmonicOrder.empty()) {
923 tipText += _("\n\nHarmonic currents:");
924 int i = 0;
925 for (auto& hCurrent1 : m_electricalData.harmonicCurrent[0]) {
926 auto& hCurrent2 = m_electricalData.harmonicCurrent[1][i];
927 wxString i1, i2;
928 i1.Printf(_("\nIh(%d)(%d-%d) = %.5e%s%.2f%s p.u."), m_electricalData.harmonicOrder[i], busNumber[0], busNumber[1], std::abs(hCurrent1), wxString(L'\u2220'), wxRadToDeg(std::arg(hCurrent1)), wxString(L'\u00B0'));
929 i2.Printf(_("\nIh(%d)(%d-%d) = %.5e%s%.2f%s p.u."), m_electricalData.harmonicOrder[i], busNumber[1], busNumber[0], std::abs(hCurrent2), wxString(L'\u2220'), wxRadToDeg(std::arg(hCurrent2)), wxString(L'\u00B0'));
930
931 tipText += i1 + i2;
932 i++;
933 }
934 }
935 }
936
937 return tipText;
938}
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
Definition Element.cpp:548
Here is the call graph for this function:

◆ Intersects()

bool Transformer::Intersects ( wxRect2DDouble  rect) const
virtual

Check if the element's rect intersects other rect.

Parameters
rectRect to check intersection.

Reimplemented from Branch.

Definition at line 486 of file Transformer.cpp.

487{
488 if (m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
489 return RotatedRectanglesIntersects(m_rect, rect, m_angle, 0.0);
490}
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
Definition Element.cpp:377
Here is the call graph for this function:

◆ Move()

void Transformer::Move ( wxPoint2DDouble  position)
virtual

Move the element other position.

Parameters
positionPosition that the element will be moved. Use StartMove(wxPoint2DDouble position) before start moving.

Reimplemented from Branch.

Definition at line 519 of file Transformer.cpp.

520{
521 SetPosition(m_movePos + position - m_moveStartPt);
522
523 // Update terminals rigidly attached to transformer body at 40.0 units offset
524 if (m_pointList.size() >= 4) {
525 wxPoint2DDouble t1 = m_position + RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
526 wxPoint2DDouble t2 = m_position + RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
527 m_pointList[2] = wxPoint2DDouble(std::round(t1.m_x), std::round(t1.m_y));
528 m_pointList[3] = wxPoint2DDouble(std::round(t2.m_x), std::round(t2.m_y));
529 }
530
531 if (!m_parentList[0]) { m_pointList[0] = m_movePts[0] + position - m_moveStartPt; }
532 if (!m_parentList[1]) {
533 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
534 }
535
536 UpdateSwitchesPosition();
537 UpdatePowerFlowArrowsPosition();
538}
Here is the call graph for this function:

◆ MoveNode()

void Transformer::MoveNode ( Element *  parent,
wxPoint2DDouble  position 
)
virtual

Move a node. StartMove(wxPoint2DDouble position) before start moving.

Parameters
parentNode's parent.
positionNew node position.

Reimplemented from Branch.

Definition at line 656 of file Transformer.cpp.

657{
658 if (parent) {
659 // First bus.
660 if (parent == m_parentList[0]) {
661 m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
662 }
663 // Second bus.
664 else if (parent == m_parentList[1]) {
665 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
666 }
667 }
668 else {
669 if (m_activeNodeID == 1) {
670 m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
671 if (m_parentList[0]) {
672 m_parentList[0]->RemoveChild(this);
673 m_parentList[0] = nullptr;
674 m_online = false;
675 }
676 }
677 else if (m_activeNodeID == 2) {
678 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
679 if (m_parentList[1]) {
680 m_parentList[1]->RemoveChild(this);
681 m_parentList[1] = nullptr;
682 m_online = false;
683 }
684 }
685 }
686
687 // Recalculate switches positions
688 UpdateSwitchesPosition();
689 UpdatePowerFlowArrowsPosition();
690}

◆ OpenElement()

bool Transformer::OpenElement ( rapidxml::xml_node<> *  elementNode,
std::vector< Element * >  parentList 
)
virtual

Reimplemented from PowerElement.

Definition at line 1183 of file Transformer.cpp.

1184{
1185 auto cadPropNode = elementNode->first_node("CADProperties");
1186 if (!cadPropNode) return false;
1187
1188 auto position = cadPropNode->first_node("Position");
1189 double posX = XMLParser::GetNodeValueDouble(position, "X");
1190 double posY = XMLParser::GetNodeValueDouble(position, "Y");
1191 auto size = cadPropNode->first_node("Size");
1192 m_width = XMLParser::GetNodeValueDouble(size, "Width");
1193 m_height = XMLParser::GetNodeValueDouble(size, "Height");
1194 m_angle = XMLParser::GetNodeValueDouble(cadPropNode, "Angle");
1195
1196 // Get nodes points
1197 std::vector<wxPoint2DDouble> ptsList;
1198 auto nodePosList = cadPropNode->first_node("NodeList");
1199 if (!nodePosList) return false;
1200 auto nodePos = nodePosList->first_node("Node");
1201 while (nodePos) {
1202 double nodePosX = XMLParser::GetNodeValueDouble(nodePos, "X");
1203 double nodePosY = XMLParser::GetNodeValueDouble(nodePos, "Y");
1204 ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
1205 nodePos = nodePos->next_sibling("Node");
1206 }
1207
1208 // Get parents IDs
1209 auto parentIDList = cadPropNode->first_node("ParentIDList");
1210 if (!parentIDList) return false;
1211 auto parentNode = parentIDList->first_node("ParentID");
1212 long parentID[2] = { -1, -1 };
1213 while (parentNode) {
1214 long index = 0;
1215 wxString(parentNode->first_attribute("ID")->value()).ToLong(&index);
1216 wxString(parentNode->value()).ToCLong(&parentID[index]);
1217 parentNode = parentNode->next_sibling("ParentID");
1218 }
1219
1220 std::vector<wxPoint2DDouble> nodePtsList; // List of node points
1221 nodePtsList.push_back(ptsList[0]); // First point on the list
1222 nodePtsList.push_back(ptsList[ptsList.size() - 1]); // Last point on the list
1223
1224 // List of dummy buses to set not connected nodes properly
1225 std::vector<Bus*> dummyBusList;
1226 // Set parents (if have)
1227 for (unsigned int i = 0; i < 2; ++i) {
1228 if (parentID[i] == -1) // No parent connected
1229 {
1230 Bus* dummyBus = new Bus(nodePtsList[i]);
1231 dummyBusList.push_back(dummyBus);
1232 AddParent(dummyBus, nodePtsList[i], true);
1233 }
1234 else { // Parent connected (necessarily a bus, get from bus list)
1235 AddParent(parentList[parentID[i]], nodePtsList[i], true);
1236 }
1237 }
1238
1239 StartMove(m_position);
1240 Move(wxPoint2DDouble(posX, posY));
1241
1242 // Remove dummy buses
1243 for (auto it = dummyBusList.begin(), itEnd = dummyBusList.end(); it != itEnd; ++it) {
1244 RemoveParent(*it);
1245 delete* it;
1246 }
1247 dummyBusList.clear();
1248
1249 // Set rotation properly.
1250 //int numRot = angle / GetRotationAngle();
1251 //bool clockwise = true;
1252 //if (numRot < 0) {
1253 // numRot = std::abs(numRot);
1254 // clockwise = false;
1255 //}
1256 //for (int i = 0; i < numRot; i++) Rotate(clockwise);
1257
1258 auto electricalProp = elementNode->first_node("ElectricalProperties");
1259 if (!electricalProp) return false;
1260
1261 SetOnline(XMLParser::GetNodeValueInt(electricalProp, "IsOnline"));
1262 m_electricalData.name = electricalProp->first_node("Name")->value();
1263 m_electricalData.primaryNominalVoltage = XMLParser::GetNodeValueDouble(electricalProp, "PrimaryNominalVoltage");
1264 m_electricalData.primaryNominalVoltageUnit =
1265 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "PrimaryNominalVoltage", "UnitID"));
1266 m_electricalData.secondaryNominalVoltage = XMLParser::GetNodeValueDouble(electricalProp, "SecondaryNominalVoltage");
1267 m_electricalData.secondaryNominalVoltageUnit = static_cast<ElectricalUnit>(
1268 XMLParser::GetAttributeValueInt(electricalProp, "SecondaryNominalVoltage", "UnitID"));
1269 m_electricalData.nominalPower = XMLParser::GetNodeValueDouble(electricalProp, "NominalPower");
1270 m_electricalData.nominalPowerUnit =
1271 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "NominalPower", "UnitID"));
1272 m_electricalData.resistance = XMLParser::GetNodeValueDouble(electricalProp, "Resistance");
1273 m_electricalData.resistanceUnit =
1274 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "Resistance", "UnitID"));
1275 m_electricalData.indReactance = XMLParser::GetNodeValueDouble(electricalProp, "IndReactance");
1276 m_electricalData.indReactanceUnit =
1277 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "IndReactance", "UnitID"));
1278 m_electricalData.connection = (TransformerConnection)XMLParser::GetNodeValueInt(electricalProp, "Connection");
1279 m_electricalData.turnsRatio = XMLParser::GetNodeValueDouble(electricalProp, "TurnsRatio");
1280 m_electricalData.phaseShift = XMLParser::GetNodeValueDouble(electricalProp, "PhaseShift");
1281 m_electricalData.useTransformerPower = XMLParser::GetNodeValueInt(electricalProp, "UseTransfomerPower");
1282
1283 auto oltcNode = electricalProp->first_node("TapChanger");
1284 if (oltcNode) {
1285 m_electricalData.hasTapChanger = XMLParser::GetNodeValueInt(oltcNode, "Enabled") == 1;
1286 auto nomNode = oltcNode->first_node("NominalTurnsRatio");
1287 if (nomNode) wxString(nomNode->value()).ToCDouble(&m_electricalData.nominalTurnsRatio);
1288 else m_electricalData.nominalTurnsRatio = m_electricalData.turnsRatio;
1289 auto ctrlBusNode = oltcNode->first_node("ControlledBus");
1290 if (ctrlBusNode) {
1291 long cb = 1;
1292 wxString(ctrlBusNode->value()).ToCLong(&cb);
1293 m_electricalData.oltcControlledBus = (int)cb;
1294 }
1295 auto targetVNode = oltcNode->first_node("TargetVoltage");
1296 if (targetVNode) wxString(targetVNode->value()).ToCDouble(&m_electricalData.oltcTargetVoltage);
1297 auto deadbandNode = oltcNode->first_node("VoltageDeadband");
1298 if (deadbandNode) wxString(deadbandNode->value()).ToCDouble(&m_electricalData.oltcVoltageDeadband);
1299 auto minTapNode = oltcNode->first_node("MinTap");
1300 if (minTapNode) wxString(minTapNode->value()).ToCDouble(&m_electricalData.oltcMinTap);
1301 auto maxTapNode = oltcNode->first_node("MaxTap");
1302 if (maxTapNode) wxString(maxTapNode->value()).ToCDouble(&m_electricalData.oltcMaxTap);
1303 auto tapStepNode = oltcNode->first_node("TapStep");
1304 if (tapStepNode) wxString(tapStepNode->value()).ToCDouble(&m_electricalData.oltcTapStep);
1305 m_electricalData.oltcIsDiscrete = XMLParser::GetNodeValueInt(oltcNode, "IsDiscrete") == 1;
1306 }
1307 else {
1308 m_electricalData.hasTapChanger = false;
1309 m_electricalData.nominalTurnsRatio = m_electricalData.turnsRatio;
1310 m_electricalData.oltcControlledBus = 1;
1311 m_electricalData.oltcTargetVoltage = 1.0;
1312 m_electricalData.oltcVoltageDeadband = 0.005;
1313 m_electricalData.oltcMinTap = 0.90;
1314 m_electricalData.oltcMaxTap = 1.10;
1315 m_electricalData.oltcTapStep = 0.00625;
1316 m_electricalData.oltcIsDiscrete = false;
1317 }
1318
1319 auto fault = electricalProp->first_node("Fault");
1320 m_electricalData.zeroResistance = XMLParser::GetNodeValueDouble(fault, "ZeroResistance");
1321 m_electricalData.zeroIndReactance = XMLParser::GetNodeValueDouble(fault, "ZeroIndReactance");
1322 m_electricalData.primaryGrndResistance = XMLParser::GetNodeValueDouble(fault, "PrimaryGrndResistance");
1323 m_electricalData.primaryGrndReactance = XMLParser::GetNodeValueDouble(fault, "PrimaryGrndReactance");
1324 m_electricalData.secondaryGrndResistance = XMLParser::GetNodeValueDouble(fault, "SecondaryGrndResistance");
1325 m_electricalData.secondaryGrndReactance = XMLParser::GetNodeValueDouble(fault, "SecondaryGrndReactance");
1326
1327 if (!OpenSwitchingData(electricalProp)) return false;
1328 if (m_swData.swTime.size() != 0) SetDynamicEvent(true);
1329
1330 return true;
1331}
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition Branch.cpp:105
bool SetOnline(bool online=true)
Set if the element is online or offline.
Definition Element.cpp:465
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
virtual void Move(wxPoint2DDouble position)
Move the element other 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,...
std::vector< double > swTime

◆ Rotate()

void Transformer::Rotate ( bool  clockwise = true)
virtual

Rotate the element.

Parameters
clockwiseTrue to rotate clockwise, false to rotate counter-clockwise.

Reimplemented from Element.

Definition at line 492 of file Transformer.cpp.

493{
494 double rotAngle = m_rotationAngle;
495 if (!clockwise) rotAngle = -m_rotationAngle;
496
497 m_angle += rotAngle;
498 while (m_angle >= 360.0) m_angle -= 360.0;
499 while (m_angle < 0.0) m_angle += 360.0;
500
501 // Clean up floating point precision for cardinal angles
502 if (std::abs(m_angle - 90.0) < 1e-4) m_angle = 90.0;
503 else if (std::abs(m_angle - 180.0) < 1e-4) m_angle = 180.0;
504 else if (std::abs(m_angle - 270.0) < 1e-4) m_angle = 270.0;
505 else if (std::abs(m_angle - 0.0) < 1e-4 || std::abs(m_angle - 360.0) < 1e-4) m_angle = 0.0;
506
507 // Update terminals rigidly attached to transformer body at 40.0 units offset
508 if (m_pointList.size() >= 4) {
509 wxPoint2DDouble t1 = m_position + RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
510 wxPoint2DDouble t2 = m_position + RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
511 m_pointList[2] = wxPoint2DDouble(std::round(t1.m_x), std::round(t1.m_y));
512 m_pointList[3] = wxPoint2DDouble(std::round(t2.m_x), std::round(t2.m_y));
513 }
514
515 UpdateSwitchesPosition();
516 UpdatePowerFlowArrowsPosition();
517}

◆ RotateNode()

void Transformer::RotateNode ( Element *  parent,
bool  clockwise 
)
virtual

Rotate a node.

Parameters
parentNode's parent.
clockwiseTrue to rotate clockwise, false to rotate counter-clockwise.

Reimplemented from Branch.

Definition at line 778 of file Transformer.cpp.

779{
780 double rotAngle = m_rotationAngle;
781 if (!clockwise) rotAngle = -m_rotationAngle;
782
783 if (parent == m_parentList[0]) {
784 m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle);
785 }
786 else if (parent == m_parentList[1]) {
787 m_pointList[m_pointList.size() - 1] = parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], rotAngle);
788 }
789 UpdateSwitchesPosition();
790 UpdatePowerFlowArrowsPosition();
791}
Here is the call graph for this function:

◆ SaveElement()

rapidxml::xml_node * Transformer::SaveElement ( rapidxml::xml_document<> &  doc,
rapidxml::xml_node<> *  elementListNode 
)
virtual

Reimplemented from Element.

Definition at line 1074 of file Transformer.cpp.

1075{
1076 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Transfomer");
1077 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
1078 auto cadProp = XMLParser::AppendNode(doc, elementNode, "CADProperties");
1079 auto position = XMLParser::AppendNode(doc, cadProp, "Position");
1080 auto posX = XMLParser::AppendNode(doc, position, "X");
1081 XMLParser::SetNodeValue(doc, posX, m_position.m_x);
1082 auto posY = XMLParser::AppendNode(doc, position, "Y");
1083 XMLParser::SetNodeValue(doc, posY, m_position.m_y);
1084 auto size = XMLParser::AppendNode(doc, cadProp, "Size");
1085 auto width = XMLParser::AppendNode(doc, size, "Width");
1086 XMLParser::SetNodeValue(doc, width, m_width);
1087 auto height = XMLParser::AppendNode(doc, size, "Height");
1088 XMLParser::SetNodeValue(doc, height, m_height);
1089 auto angle = XMLParser::AppendNode(doc, cadProp, "Angle");
1090 XMLParser::SetNodeValue(doc, angle, m_angle);
1091 auto nodeList = XMLParser::AppendNode(doc, cadProp, "NodeList");
1092 auto nodePos1 = XMLParser::AppendNode(doc, nodeList, "Node");
1093 XMLParser::SetNodeAttribute(doc, nodePos1, "ID", 0);
1094 auto nodePosX1 = XMLParser::AppendNode(doc, nodePos1, "X");
1095 XMLParser::SetNodeValue(doc, nodePosX1, m_pointList[0].m_x);
1096 auto nodePosY1 = XMLParser::AppendNode(doc, nodePos1, "Y");
1097 XMLParser::SetNodeValue(doc, nodePosY1, m_pointList[0].m_y);
1098 auto nodePos2 = XMLParser::AppendNode(doc, nodeList, "Node");
1099 XMLParser::SetNodeAttribute(doc, nodePos2, "ID", 1);
1100 auto nodePosX2 = XMLParser::AppendNode(doc, nodePos2, "X");
1101 XMLParser::SetNodeValue(doc, nodePosX2, m_pointList[m_pointList.size() - 1].m_x);
1102 auto nodePosY2 = XMLParser::AppendNode(doc, nodePos2, "Y");
1103 XMLParser::SetNodeValue(doc, nodePosY2, m_pointList[m_pointList.size() - 1].m_y);
1104
1105 auto parentIDList = XMLParser::AppendNode(doc, cadProp, "ParentIDList");
1106 for (unsigned int i = 0; i < m_parentList.size(); i++) {
1107 Element* parent = m_parentList[i];
1108 if (parent) {
1109 auto parentID = XMLParser::AppendNode(doc, parentIDList, "ParentID");
1110 XMLParser::SetNodeAttribute(doc, parentID, "ID", static_cast<int>(i));
1111 XMLParser::SetNodeValue(doc, parentID, parent->GetID());
1112 }
1113 }
1114
1115 auto electricalProp = XMLParser::AppendNode(doc, elementNode, "ElectricalProperties");
1116 auto isOnline = XMLParser::AppendNode(doc, electricalProp, "IsOnline");
1117 XMLParser::SetNodeValue(doc, isOnline, m_online);
1118 auto name = XMLParser::AppendNode(doc, electricalProp, "Name");
1119 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
1120 auto primaryNominalVoltage = XMLParser::AppendNode(doc, electricalProp, "PrimaryNominalVoltage");
1121 XMLParser::SetNodeValue(doc, primaryNominalVoltage, m_electricalData.primaryNominalVoltage);
1122 XMLParser::SetNodeAttribute(doc, primaryNominalVoltage, "UnitID", static_cast<int>(m_electricalData.primaryNominalVoltageUnit));
1123 auto secondaryNominalVoltage = XMLParser::AppendNode(doc, electricalProp, "SecondaryNominalVoltage");
1124 XMLParser::SetNodeValue(doc, secondaryNominalVoltage, m_electricalData.secondaryNominalVoltage);
1125 XMLParser::SetNodeAttribute(doc, secondaryNominalVoltage, "UnitID", static_cast<int>(m_electricalData.secondaryNominalVoltageUnit));
1126 auto nominalPower = XMLParser::AppendNode(doc, electricalProp, "NominalPower");
1127 XMLParser::SetNodeValue(doc, nominalPower, m_electricalData.nominalPower);
1128 XMLParser::SetNodeAttribute(doc, nominalPower, "UnitID", static_cast<int>(m_electricalData.nominalPowerUnit));
1129 auto resistance = XMLParser::AppendNode(doc, electricalProp, "Resistance");
1130 XMLParser::SetNodeValue(doc, resistance, m_electricalData.resistance);
1131 XMLParser::SetNodeAttribute(doc, resistance, "UnitID", static_cast<int>(m_electricalData.resistanceUnit));
1132 auto indReactance = XMLParser::AppendNode(doc, electricalProp, "IndReactance");
1133 XMLParser::SetNodeValue(doc, indReactance, m_electricalData.indReactance);
1134 XMLParser::SetNodeAttribute(doc, indReactance, "UnitID", static_cast<int>(m_electricalData.indReactanceUnit));
1135 auto connection = XMLParser::AppendNode(doc, electricalProp, "Connection");
1136 XMLParser::SetNodeValue(doc, connection, m_electricalData.connection);
1137 auto turnsRatio = XMLParser::AppendNode(doc, electricalProp, "TurnsRatio");
1138 XMLParser::SetNodeValue(doc, turnsRatio, m_electricalData.turnsRatio);
1139 auto phaseShift = XMLParser::AppendNode(doc, electricalProp, "PhaseShift");
1140 XMLParser::SetNodeValue(doc, phaseShift, m_electricalData.phaseShift);
1141 auto useTransformerPower = XMLParser::AppendNode(doc, electricalProp, "UseTransfomerPower");
1142 XMLParser::SetNodeValue(doc, useTransformerPower, m_electricalData.useTransformerPower);
1143
1144 auto oltcNode = XMLParser::AppendNode(doc, electricalProp, "TapChanger");
1145 auto hasTapChanger = XMLParser::AppendNode(doc, oltcNode, "Enabled");
1146 XMLParser::SetNodeValue(doc, hasTapChanger, m_electricalData.hasTapChanger ? 1 : 0);
1147 auto nominalTurnsRatio = XMLParser::AppendNode(doc, oltcNode, "NominalTurnsRatio");
1148 XMLParser::SetNodeValue(doc, nominalTurnsRatio, m_electricalData.nominalTurnsRatio);
1149 auto oltcControlledBus = XMLParser::AppendNode(doc, oltcNode, "ControlledBus");
1150 XMLParser::SetNodeValue(doc, oltcControlledBus, m_electricalData.oltcControlledBus);
1151 auto oltcTargetVoltage = XMLParser::AppendNode(doc, oltcNode, "TargetVoltage");
1152 XMLParser::SetNodeValue(doc, oltcTargetVoltage, m_electricalData.oltcTargetVoltage);
1153 auto oltcVoltageDeadband = XMLParser::AppendNode(doc, oltcNode, "VoltageDeadband");
1154 XMLParser::SetNodeValue(doc, oltcVoltageDeadband, m_electricalData.oltcVoltageDeadband);
1155 auto oltcMinTap = XMLParser::AppendNode(doc, oltcNode, "MinTap");
1156 XMLParser::SetNodeValue(doc, oltcMinTap, m_electricalData.oltcMinTap);
1157 auto oltcMaxTap = XMLParser::AppendNode(doc, oltcNode, "MaxTap");
1158 XMLParser::SetNodeValue(doc, oltcMaxTap, m_electricalData.oltcMaxTap);
1159 auto oltcTapStep = XMLParser::AppendNode(doc, oltcNode, "TapStep");
1160 XMLParser::SetNodeValue(doc, oltcTapStep, m_electricalData.oltcTapStep);
1161 auto oltcIsDiscrete = XMLParser::AppendNode(doc, oltcNode, "IsDiscrete");
1162 XMLParser::SetNodeValue(doc, oltcIsDiscrete, m_electricalData.oltcIsDiscrete ? 1 : 0);
1163
1164 auto fault = XMLParser::AppendNode(doc, electricalProp, "Fault");
1165 auto zeroResistance = XMLParser::AppendNode(doc, fault, "ZeroResistance");
1166 XMLParser::SetNodeValue(doc, zeroResistance, m_electricalData.zeroResistance);
1167 auto zeroIndReactance = XMLParser::AppendNode(doc, fault, "ZeroIndReactance");
1168 XMLParser::SetNodeValue(doc, zeroIndReactance, m_electricalData.zeroIndReactance);
1169 auto primaryGrndResistance = XMLParser::AppendNode(doc, fault, "PrimaryGrndResistance");
1170 XMLParser::SetNodeValue(doc, primaryGrndResistance, m_electricalData.primaryGrndResistance);
1171 auto primaryGrndReactance = XMLParser::AppendNode(doc, fault, "PrimaryGrndReactance");
1172 XMLParser::SetNodeValue(doc, primaryGrndReactance, m_electricalData.primaryGrndReactance);
1173 auto secondaryGrndResistance = XMLParser::AppendNode(doc, fault, "SecondaryGrndResistance");
1174 XMLParser::SetNodeValue(doc, secondaryGrndResistance, m_electricalData.secondaryGrndResistance);
1175 auto secondaryGrndReactance = XMLParser::AppendNode(doc, fault, "SecondaryGrndReactance");
1176 XMLParser::SetNodeValue(doc, secondaryGrndReactance, m_electricalData.secondaryGrndReactance);
1177
1178 SaveSwitchingData(doc, electricalProp);
1179
1180 return elementNode;
1181}
virtual int GetID() const
Get the element ID.
Definition Element.h:275

◆ SetBestPositionAndRotation()

void Transformer::SetBestPositionAndRotation ( )
virtual

Definition at line 1333 of file Transformer.cpp.

1334{
1335 wxPoint2DDouble p1 = m_pointList[0];
1336 wxPoint2DDouble p2 = m_pointList[m_pointList.size() - 1];
1337 double dx = p2.m_x - p1.m_x;
1338 double dy = p2.m_y - p1.m_y;
1339
1340 if (std::abs(dy) > std::abs(dx)) {
1341 m_angle = (dy >= 0.0) ? 90.0 : 270.0;
1342 }
1343 else {
1344 m_angle = (dx >= 0.0) ? 0.0 : 180.0;
1345 }
1346
1347 wxPoint2DDouble mid = (p1 + p2) / 2.0;
1348 if (std::abs(dx) < 1.0) {
1349 mid.m_x = p1.m_x;
1350 mid.m_y = std::round(mid.m_y / 20.0) * 20.0;
1351 }
1352 else if (std::abs(dy) < 1.0) {
1353 mid.m_y = p1.m_y;
1354 mid.m_x = std::round(mid.m_x / 20.0) * 20.0;
1355 }
1356 else {
1357 mid.m_x = std::round(mid.m_x / 20.0) * 20.0;
1358 mid.m_y = std::round(mid.m_y / 20.0) * 20.0;
1359 }
1360
1361 SetPosition(mid);
1362
1363 if (m_parentList.size() > 0 && m_parentList[0] && m_parentList.size() > 1 && m_parentList[1]) {
1364 Element* bus1 = m_parentList[0];
1365 Element* bus2 = m_parentList[1];
1366 if (std::abs(dy) > std::abs(dx)) {
1367 wxPoint2DDouble loc1 = bus1->RotateAtPosition(wxPoint2DDouble(m_position.m_x, bus1->GetPosition().m_y), -bus1->GetAngle());
1368 wxPoint2DDouble loc2 = bus2->RotateAtPosition(wxPoint2DDouble(m_position.m_x, bus2->GetPosition().m_y), -bus2->GetAngle());
1369 double halfW1 = bus1->GetWidth() / 2.0 + 2.0;
1370 double halfW2 = bus2->GetWidth() / 2.0 + 2.0;
1371 if (std::abs(loc1.m_x - bus1->GetPosition().m_x) <= halfW1 &&
1372 std::abs(loc2.m_x - bus2->GetPosition().m_x) <= halfW2) {
1373 m_pointList[0].m_x = m_position.m_x;
1374 m_pointList.back().m_x = m_position.m_x;
1375 }
1376 }
1377 else {
1378 wxPoint2DDouble loc1 = bus1->RotateAtPosition(wxPoint2DDouble(bus1->GetPosition().m_x, m_position.m_y), -bus1->GetAngle());
1379 wxPoint2DDouble loc2 = bus2->RotateAtPosition(wxPoint2DDouble(bus2->GetPosition().m_x, m_position.m_y), -bus2->GetAngle());
1380 double halfW1 = bus1->GetWidth() / 2.0 + 2.0;
1381 double halfW2 = bus2->GetWidth() / 2.0 + 2.0;
1382 if (std::abs(loc1.m_x - bus1->GetPosition().m_x) <= halfW1 &&
1383 std::abs(loc2.m_x - bus2->GetPosition().m_x) <= halfW2) {
1384 m_pointList[0].m_y = m_position.m_y;
1385 m_pointList.back().m_y = m_position.m_y;
1386 }
1387 }
1388 }
1389
1390 if (m_pointList.size() >= 4) {
1391 wxPoint2DDouble t1 = m_position + RotateLocal(wxPoint2DDouble(-40.0, 0.0), m_angle);
1392 wxPoint2DDouble t2 = m_position + RotateLocal(wxPoint2DDouble(40.0, 0.0), m_angle);
1393 m_pointList[2] = wxPoint2DDouble(std::round(t1.m_x), std::round(t1.m_y));
1394 m_pointList[3] = wxPoint2DDouble(std::round(t2.m_x), std::round(t2.m_y));
1395 }
1396 UpdateSwitchesPosition();
1397 UpdatePowerFlowArrowsPosition();
1398}

◆ SetElectricaData()

virtual void Transformer::SetElectricaData ( TransformerElectricalData  electricalData)
inlinevirtual

Definition at line 123 of file Transformer.h.

123{ m_electricalData = electricalData; }

◆ SetNodeParent()

bool Transformer::SetNodeParent ( Element *  parent)
virtual

Set a perent to the node. If all conditions are met, a new parent are added to the element and the points related to the nodes will be calculated.

Parameters
parentNode parent.
Returns
True if was possible to set the parent.

Reimplemented from Branch.

Definition at line 793 of file Transformer.cpp.

794{
795 if (m_activeNodeID == 1 && parent == m_parentList[0]) return false;
796 if (m_activeNodeID == 2 && parent == m_parentList[1]) return false;
797
798 if (parent && m_activeNodeID != 0) {
799 wxRect2DDouble nodeRect(0, 0, 0, 0);
800 if (m_activeNodeID == 1) {
801 nodeRect = wxRect2DDouble(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
802 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
803 }
804 if (m_activeNodeID == 2) {
805 nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
806 m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
807 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
808 }
809
810 if (parent->Intersects(nodeRect)) {
811 if (m_activeNodeID == 1) {
812 // Check if the user is trying to connect the same bus.
813 if (m_parentList[1] == parent) {
814 m_activeNodeID = 0;
815 return false;
816 }
817
818 m_parentList[0] = parent;
819
820 // Centralize the node on bus.
821 wxPoint2DDouble parentPt = parent->RotateAtPosition(
822 m_pointList[0], -parent->GetAngle()); // Rotate click to horizontal position.
823 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
824 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
825 m_pointList[0] = parentPt;
826
827 UpdateSwitchesPosition();
828 UpdatePowerFlowArrowsPosition();
829 return true;
830 }
831 if (m_activeNodeID == 2) {
832 if (m_parentList[0] == parent) {
833 m_activeNodeID = 0;
834 return false;
835 }
836
837 m_parentList[1] = parent;
838
839 wxPoint2DDouble parentPt =
840 parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], -parent->GetAngle());
841 parentPt.m_y = parent->GetPosition().m_y;
842 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
843 m_pointList[m_pointList.size() - 1] = parentPt;
844
845 UpdateSwitchesPosition();
846 UpdatePowerFlowArrowsPosition();
847 return true;
848 }
849 }
850 else {
851 if (m_activeNodeID == 1) m_parentList[0] = nullptr;
852 if (m_activeNodeID == 2) m_parentList[1] = nullptr;
853 }
854 }
855 return false;
856}
virtual bool Intersects(wxRect2DDouble rect) const =0
Check if the element's rect intersects other rect.
Here is the call graph for this function:

◆ SetNominalVoltage()

void Transformer::SetNominalVoltage ( std::vector< double >  nominalVoltage,
std::vector< ElectricalUnit >  nominalVoltageUnit 
)
virtual

Set nominal voltage of the element.

Parameters
nominalVoltageValue of the nominal voltage.
nominalVoltageUnitUnit of the nominal voltage.

Reimplemented from PowerElement.

Definition at line 745 of file Transformer.cpp.

746{
747 if (nominalVoltage.size() == 1) {
748 m_electricalData.primaryNominalVoltage = nominalVoltage[0];
749 m_electricalData.primaryNominalVoltageUnit = nominalVoltageUnit[0];
750 }
751 else if (nominalVoltage.size() == 2) {
752 m_electricalData.primaryNominalVoltage = nominalVoltage[0];
753 m_electricalData.primaryNominalVoltageUnit = nominalVoltageUnit[0];
754 m_electricalData.secondaryNominalVoltage = nominalVoltage[1];
755 m_electricalData.secondaryNominalVoltageUnit = nominalVoltageUnit[1];
756 }
757}

◆ SetPowerFlowDirection()

void Transformer::SetPowerFlowDirection ( PowerFlowDirection  pfDirection)
virtual

Set the direction of the power flow.

Parameters
pfDirectionPower flow direction.

Reimplemented from PowerElement.

Definition at line 858 of file Transformer.cpp.

859{
860 m_pfDirection = pfDirection;
861 UpdatePowerFlowArrowsPosition();
862}
Here is the caller graph for this function:

◆ ShowForm()

bool Transformer::ShowForm ( wxWindow *  parent,
Element *  element,
wxWindow *  workspace = nullptr 
)
virtual

Show element data form.

Parameters
parentForm parent
elementElement that will be edited.
Returns
True if the form is shown, false otherwise.

Reimplemented from Element.

Definition at line 735 of file Transformer.cpp.

736{
737 TransformerForm transfForm(parent, this);
738 transfForm.CenterOnParent();
739 if (transfForm.ShowModal() == wxID_OK) {
740 return true;
741 }
742 return false;
743}
Form to edit the transformer power data and OLTC tap changer.

◆ StartMove()

void Transformer::StartMove ( wxPoint2DDouble  position)
virtual

Update the element attributes related to the movement.

Parameters
positionStart move position.

Reimplemented from Branch.

Definition at line 692 of file Transformer.cpp.

693{
694 m_moveStartPt = position;
695 m_movePts = m_pointList;
696 m_movePos = m_position;
697}

◆ UpdatePowerFlowArrowsPosition()

void Transformer::UpdatePowerFlowArrowsPosition ( )
protectedvirtual

Reimplemented from PowerElement.

Definition at line 759 of file Transformer.cpp.

760{
761 std::vector<wxPoint2DDouble> edges;
762 switch (m_pfDirection) {
764 m_powerFlowArrow.clear();
765 } break;
767 for (int i = 1; i < (int)m_pointList.size() - 1; i++) { edges.push_back(m_pointList[i]); }
768 } break;
770 for (int i = (int)m_pointList.size() - 2; i > 0; i--) { edges.push_back(m_pointList[i]); }
771 } break;
772 default:
773 break;
774 }
776}
virtual void CalculatePowerFlowPts(std::vector< wxPoint2DDouble > edges)
Calculate the points of the power flow arrows.

Member Data Documentation

◆ m_electricalData

TransformerElectricalData Transformer::m_electricalData
protected

Definition at line 132 of file Transformer.h.


The documentation for this class was generated from the following files: