30{
31 double radInitAngle = wxDegToRad(initAngle);
32
33
35
36
37 if (!
GetYBus(m_yBus, systemPowerBase)) {
38 m_errorMsg = _("No buses found on the system.");
39 return false;
40 }
41
42
44
45
46
47 m_numberOfBuses = static_cast<int>(m_yBus.size());
48
49 busType.clear();
50 voltage.clear();
51 power.clear();
52 loadPower.clear();
53 reactiveLimit.clear();
54
55 reactiveLimit.resize(m_numberOfBuses);
56
57 int busNumber = 0;
58 Bus* slackBus =
nullptr;
62 if (data.isConnected) {
63
64 if (data.slackBus) {
66 slackBus = bus;
67 }
68
69
70 else if (data.isVoltageControlled) {
71 bool hasSyncMachine = false;
72
76 }
77
81 }
82 if (hasSyncMachine)
84 else
86 }
87 else
89
90
91 double v = 1.0;
92 double t = 0.0;
93 if (data.slackBus) {
94 v = data.controlledVoltage;
95 t = radInitAngle;
96 }
97 else if (busType[busNumber] ==
BUS_PV) {
98 v = data.controlledVoltage;
99 t = std::arg(data.voltage);
100 }
101 else {
102 v = std::abs(data.voltage);
103 if (v <= 0.1) v = 1.0;
104 t = std::arg(data.voltage);
105 }
106 voltage.push_back(std::complex<double>(v * std::cos(t), v * std::sin(t)));
107
108
109
110
111
112
113
114
115
116
117 power.push_back(std::complex<double>(0.0, 0.0));
118 loadPower.push_back(std::complex<double>(0.0, 0.0));
119
120
126 power[busNumber] += std::complex<double>(childData.activePower, childData.reactivePower);
127
128 if (busType[busNumber] ==
BUS_PV) {
129 if (childData.haveMaxReactive && reactiveLimit[busNumber].maxLimitType !=
RL_UNLIMITED_SOURCE) {
130 reactiveLimit[busNumber].maxLimitType =
RL_LIMITED;
131 reactiveLimit[busNumber].maxLimit += childData.maxReactive;
132 }
133 else if (!childData.haveMaxReactive)
135
136 if (childData.haveMinReactive && reactiveLimit[busNumber].minLimitType !=
RL_UNLIMITED_SOURCE) {
137 reactiveLimit[busNumber].minLimitType =
RL_LIMITED;
138 reactiveLimit[busNumber].minLimit += childData.minReactive;
139 }
140 else if (!childData.haveMinReactive)
142 }
143 }
144 }
145 }
146
152 power[busNumber] += std::complex<double>(-childData.activePower, childData.reactivePower);
153 loadPower[busNumber] += std::complex<double>(-childData.activePower, 0.0);
154
155 if (busType[busNumber] ==
BUS_PV) {
156 if (childData.haveMaxReactive && reactiveLimit[busNumber].maxLimitType !=
RL_UNLIMITED_SOURCE) {
157 reactiveLimit[busNumber].maxLimitType =
RL_LIMITED;
158 reactiveLimit[busNumber].maxLimit += childData.maxReactive;
159 }
160 else if (!childData.haveMaxReactive)
162
163 if (childData.haveMinReactive && reactiveLimit[busNumber].minLimitType !=
RL_UNLIMITED_SOURCE) {
164 reactiveLimit[busNumber].minLimitType =
RL_LIMITED;
165 reactiveLimit[busNumber].minLimit += childData.minReactive;
166 }
167 else if (!childData.haveMinReactive)
169 }
170 }
171 }
172 }
173
179 if (childData.loadType == CONST_POWER) {
180 power[busNumber] += std::complex<double>(-childData.activePower, -childData.reactivePower);
181 loadPower[busNumber] += std::complex<double>(-childData.activePower, -childData.reactivePower);
182 }
183 }
184 }
185 }
186
187
193 double reactivePower = childData.reactivePower;
194
195 if (childData.calcQInPowerFlow) {
196 indMotor->InitPowerFlowMotor(systemPowerBase, data.number);
197 if (!indMotor->CalculateReactivePower(std::abs(voltage[childData.busNum]))) {
198 m_errorMsg = _("It was not possible to solve the induction motors.");
199 return false;
200 }
201 reactivePower = indMotor->GetElectricalData().qValue;
202 }
203
204 power[busNumber] += std::complex<double>(-childData.activePower, -reactivePower);
205 loadPower[busNumber] += std::complex<double>(-childData.activePower, -reactivePower);
206 }
207 }
208 }
209
210
212 if (emtElement->IsOnline() && !emtElement->GetParentList().empty()) {
213 if (bus == emtElement->GetParentList()[0]) {
215 power[busNumber] -= childData.power;
216 loadPower[busNumber] -= childData.power;
217 }
218 }
219 }
220
221 busNumber++;
222 }
223 }
224
225
226 bool haveSlackBus = false;
227 bool slackBusHaveGeneration = false;
228 for (unsigned int i = 0; i < busType.size(); i++) {
232 if (syncGenerator->
IsOnline() && slackBus == syncGenerator->
GetParentList()[0]) slackBusHaveGeneration =
true;
233 }
234 haveSlackBus = true;
235 }
236 }
237 if (!haveSlackBus) {
238 m_errorMsg = _("There is no slack bus on the system.");
239 return false;
240 }
241 if (!slackBusHaveGeneration) {
242 m_errorMsg = _("The slack bus don't have generation.");
243 return false;
244 }
245
246 return true;
247}
Node for power elements. All others power elements are connected through this.
Element to connect ATP-EMTP.
std::vector< Bus * > m_busList
List of buses in the system.
std::vector< Load * > m_loadList
List of load elements in the system.
bool CalculateEMTElementsAdmittance(const double &basePower, wxString &errorMsg)
Calculate the admittance of EMT elements.
bool CalculateEMTElementsPower(const double &basePower, wxString &errorMsg, bool updateCurrent=true)
Calculate the power of EMT elements.
std::vector< SyncGenerator * > m_syncGeneratorList
List of synchronous generators in the system.
std::vector< EMTElement * > m_emtElementList
List of electromagnetic transient (EMT) elements in the system.
virtual bool GetYBus(std::vector< std::vector< std::complex< double > > > &yBus, double systemPowerBase, YBusSequence sequence=POSITIVE_SEQ, bool includeSyncMachines=false, bool allLoadsAsImpedances=false, bool usePowerFlowVoltagesOnImpedances=false)
Get the admittance matrix from the list of elements (use GetElementsFromList first).
std::vector< SyncMotor * > m_syncMotorList
List of synchronous motors in the system.
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Loas shunt power element.
Synchronous generator power element.
Synchronous motor (synchronous compensator) power element.