161{
162
163 m_harmYbusList.clear();
164 std::vector<double> harmOrders = GetHarmonicOrdersList();
165
166
167 for (unsigned int i = 0; i < harmOrders.size(); ++i) {
168 HarmonicYbus newYbus;
169 newYbus.order = harmOrders[i];
170 m_harmYbusList.push_back(newYbus);
171 }
172 CalculateHarmonicYbusList(systemPowerBase, loadConnection);
173
174
175 std::vector<std::vector<std::complex<double> > > iHarmInjList;
176 for (unsigned int i = 0; i < harmOrders.size(); i++) {
177 std::vector<std::complex<double> > line;
178 for (
unsigned int j = 0; j <
m_busList.size(); j++) { line.push_back(std::complex<double>(0.0, 0.0)); }
179 iHarmInjList.push_back(line);
180 }
181
182
183 for (unsigned int i = 0; i < harmOrders.size(); ++i) {
187
188 for (unsigned int k = 0; k < harmCurrent->GetElectricalData().harmonicOrder.size(); ++k) {
189 if (harmCurrent->GetElectricalData().harmonicOrder[k] == static_cast<int>(harmOrders[i])) {
191 auto busData = parentBus->GetElectricalData();
192 int j = busData.number;
193
194
195 double voltage = busData.nominalVoltage;
197
198 auto puData = harmCurrent->GetPUElectricalData(systemPowerBase, voltage);
199
200 iHarmInjList[i][j] += std::complex<double>(
201 puData.injHarmCurrent[k] * std::cos(wxDegToRad(puData.injHarmAngle[k])),
202 puData.injHarmCurrent[k] * std::sin(wxDegToRad(puData.injHarmAngle[k])));
203 }
204 }
205 }
206 }
207
209 if (!emtElement->IsOnline()) continue;
210 if (emtElement->GetParentList().size() > 0) {
211 if (emtElement->GetParentList()[0] != nullptr) {
212 auto data = emtElement->GetEMTElementData();
213 for (auto const& [order, current] : data.currHarmonics) {
214 if (order == 1) continue;
215 else if (order == static_cast<int>(harmOrders[i])) {
216 Bus* parentBus =
static_cast<Bus*
>(emtElement->GetParentList()[0]);
217 auto busData = parentBus->GetElectricalData();
218 int j = busData.number;
219
220 double voltage = busData.nominalVoltage;
222 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * voltage);
223
224 iHarmInjList[i][j] += current / baseCurrent;
225 }
226 }
227 }
228 }
229 }
230 }
231
232
233 std::vector<std::vector<std::complex<double> > > vHarmList;
234 for (unsigned int i = 0; i < m_harmYbusList.size(); ++i) {
236 }
237
240 auto data = bus->GetElectricalData();
241 data.harmonicOrder.clear();
242 data.harmonicVoltage.clear();
243 double thd = 0.0;
244 for (unsigned int i = 0; i < vHarmList.size(); ++i) {
245 thd += std::abs(vHarmList[i][data.number]) * std::abs(vHarmList[i][data.number]);
246 data.harmonicVoltage.push_back(vHarmList[i][data.number]);
247 data.harmonicOrder.push_back(static_cast<int>(harmOrders[i]));
248 }
249
250 thd = std::sqrt(thd) * 100.0;
251 data.thd = thd;
252 bus->SetElectricalData(data);
253 }
254
255
256
258 if (line->IsOnline()) {
260
261 auto busData1 =
static_cast<Bus*
>(line->GetParentList()[0])->GetElectricalData();
262 auto busData2 =
static_cast<Bus*
>(line->GetParentList()[1])->GetElectricalData();
263
264 if (busData1.harmonicVoltage.size() != busData1.harmonicVoltage.size()) {
265 m_errorMsg = _("Error calculating the harmonic current in \"") + data.name + wxT("\".");
266 return false;
267 }
268
269
270 data.harmonicOrder.clear();
271 data.harmonicCurrent[0].clear();
272 data.harmonicCurrent[1].clear();
273
274 int i = 0;
275 for (auto& hVoltage : busData1.harmonicVoltage) {
276 int order = busData1.harmonicOrder[i];
277 data.harmonicOrder.push_back(order);
278
279 std::complex<double> v1 = hVoltage;
280 std::complex<double> v2 = busData2.harmonicVoltage[i];
281 std::complex<double> zs = std::complex<double>(data.resistance, data.indReactance * order);
282 std::complex<double> bsh = std::complex<double>(0.0, (data.capSusceptance * order) / 2.0);
283
284 data.harmonicCurrent[0].push_back((v1 - v2) / zs + v1 * bsh);
285 data.harmonicCurrent[1].push_back((v2 - v1) / zs + v2 * bsh);
286 i++;
287 }
288
289 line->SetElectricalData(data);
290 }
291 }
292
294 if (transformer->IsOnline()) {
296
297 auto busData1 =
static_cast<Bus*
>(transformer->GetParentList()[0])->GetElectricalData();
298 auto busData2 =
static_cast<Bus*
>(transformer->GetParentList()[1])->GetElectricalData();
299
300 if (busData1.harmonicVoltage.size() != busData1.harmonicVoltage.size()) {
301 m_errorMsg = _("Error calculating the harmonic current in \"") + data.name + wxT("\".");
302 return false;
303 }
304
305
306 data.harmonicOrder.clear();
307 data.harmonicCurrent[0].clear();
308 data.harmonicCurrent[1].clear();
309
310 int i = 0;
311 for (auto& hVoltage : busData1.harmonicVoltage) {
312 int order = busData1.harmonicOrder[i];
313 data.harmonicOrder.push_back(order);
314
315 std::complex<double> v1 = hVoltage;
316 std::complex<double> v2 = busData2.harmonicVoltage[i];
317
318 auto yMatrix = GetTransformerHarmAdmmitance(transformer, systemPowerBase, order);
319
320 data.harmonicCurrent[0].push_back(yMatrix[0][0] * v1 + yMatrix[0][1] * v2);
321 data.harmonicCurrent[1].push_back(yMatrix[1][0] * v1 + yMatrix[1][1] * v2);
322
323 i++;
324 }
325
326 transformer->SetElectricaData(data);
327
328 }
329 }
330
331 return true;
332}
Node for power elements. All others power elements are connected through this.
std::vector< Line * > m_lineList
List of transmission lines in the system.
std::vector< Bus * > m_busList
List of buses in the system.
std::vector< Transformer * > m_transformerList
List of transformers in the system.
std::vector< EMTElement * > m_emtElementList
List of electromagnetic transient (EMT) elements in the system.
std::vector< std::complex< double > > GaussianElimination(std::vector< std::vector< std::complex< double > > > matrix, std::vector< std::complex< double > > array)
Solve a linear system using Gaussian elimination (complex version).
std::vector< HarmCurrent * > m_harmCurrentList
List of harmonic current sources in the system.
virtual std::vector< Element * > GetParentList() const
Get the parent list.
bool IsOnline() const
Checks if the element is online or offline.
Shunt Harmonic Corrent Source.