Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
DataReport.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "DataReport.h"
19#include "../simulation/ElectricCalculation.h"
20#include "../editors/Workspace.h"
21#include "ExportCSVForm.h"
22
23DataReport::DataReport(wxWindow* parent, Workspace* workspace) : DataReportBase(parent)
24{
25 m_workspace = workspace;
26
27 m_headerColour = wxColour(191, 223, 255);
28 m_offlineColour = wxColour(100, 100, 100);
29 m_oddRowColour = wxColour(220, 220, 220);
30 m_evenRowColour = wxColour(255, 255, 255);
31
32 m_fontSize = wxAtoi(m_choiceFontSize->GetStringSelection());
33 m_precision = wxAtoi(m_textCtrlPrecision->GetValue());
34
35 wxGrid* grids[] = { m_gridPowerFlow, m_gridPFBuses, m_gridPFBranches, m_gridFault, m_gridFaultBuses, m_gridFaultBranches, m_gridFaultGenerators, m_gridHarmCurrents, m_gridHarmBuses, m_gridHarmBranches };
36 for (auto grid : grids)
37 grid->Bind(wxEVT_MOUSEWHEEL, &DataReport::OnMouseWheel, this);
38
39 UpdateFontSize();
40 CreateGrids();
41 SetHeaders();
42 FillValues();
43
44 SetRowsColours(m_gridPowerFlow);
45 SetRowsColours(m_gridPFBuses);
46 SetRowsColours(m_gridPFBranches);
47 SetRowsColours(m_gridFault, 2);
48 SetRowsColours(m_gridFaultBuses, 2);
49 SetRowsColours(m_gridFaultBranches, 2);
50 SetRowsColours(m_gridFaultGenerators, 2);
51 SetRowsColours(m_gridHarmCurrents, 1, 2);
52 SetRowsColours(m_gridHarmBuses, 1, 2);
53 SetRowsColours(m_gridHarmBranches, 1, 4, 1);
54
55 UpdateCurrentGrid();
56}
57
58DataReport::~DataReport()
59{
60 wxGrid* grids[] = { m_gridPowerFlow, m_gridPFBuses, m_gridPFBranches, m_gridFault, m_gridFaultBuses, m_gridFaultBranches, m_gridFaultGenerators, m_gridHarmCurrents, m_gridHarmBuses, m_gridHarmBranches };
61 for (auto grid : grids)
62 grid->Unbind(wxEVT_MOUSEWHEEL, &DataReport::OnMouseWheel, this);
63}
64
65void DataReport::CreateGrids()
66{
67 wxFont headerFont = m_gridPowerFlow->GetLabelFont();
68 headerFont.SetWeight(wxFONTWEIGHT_BOLD);
69
71 eCalc.GetElementsFromList(m_workspace->GetElementList());
72 auto lineList = eCalc.GetLineList();
73 auto transformerList = eCalc.GetTransformerList();
74 auto busList = eCalc.GetBusList();
75 auto generatorList = eCalc.GetSyncGeneratorList();
76 auto harmCurrentSourceList = eCalc.GetHarmCurrentList();
77
78 // Power Flow
79 // Header
80 m_gridPowerFlow->AppendCols(7);
81 m_gridPowerFlow->AppendRows();
82 m_gridPowerFlow->HideColLabels();
83 m_gridPowerFlow->HideRowLabels();
84 for (int i = 0; i < 7; ++i) {
85 m_gridPowerFlow->SetCellBackgroundColour(0, i, m_headerColour);
86 m_gridPowerFlow->SetCellFont(0, i, headerFont);
87 }
88 m_gridPowerFlow->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
89 // Values
90 m_gridPowerFlow->AppendRows((lineList.size() + transformerList.size()) * 2);
91 m_gridPowerFlow->AutoSize();
92
93 // Power Flow buses
94 // Header
95 m_gridPFBuses->AppendCols(6);
96 m_gridPFBuses->AppendRows();
97 m_gridPFBuses->HideColLabels();
98 m_gridPFBuses->HideRowLabels();
99 for (int i = 0; i < 6; ++i) {
100 m_gridPFBuses->SetCellBackgroundColour(0, i, m_headerColour);
101 m_gridPFBuses->SetCellFont(0, i, headerFont);
102 }
103 m_gridPFBuses->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
104 // Values
105 m_gridPFBuses->AppendRows(busList.size());
106 m_gridPFBuses->AutoSize();
107
108 // Power flow branches
109 // Header
110 m_gridPFBranches->AppendCols(10);
111 m_gridPFBranches->AppendRows(1);
112 m_gridPFBranches->HideColLabels();
113 m_gridPFBranches->HideRowLabels();
114 for (int i = 0; i < 10; ++i) {
115 m_gridPFBranches->SetCellBackgroundColour(0, i, m_headerColour);
116 m_gridPFBranches->SetCellFont(0, i, headerFont);
117 }
118 m_gridPFBranches->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
119 // Values
120 m_gridPFBranches->AppendRows(lineList.size() + transformerList.size());
121 m_gridPFBranches->AutoSize();
122
123 // Fault
124 // Header
125 m_gridFault->AppendCols(7);
126 m_gridFault->AppendRows(2);
127 m_gridFault->HideColLabels();
128 m_gridFault->HideRowLabels();
129 for (int i = 0; i < 2; ++i) {
130 for (int j = 0; j < 7; ++j) {
131 m_gridFault->SetCellBackgroundColour(i, j, m_headerColour);
132 m_gridFault->SetCellFont(i, j, headerFont);
133 }
134 }
135 m_gridFault->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
136 m_gridFault->SetCellSize(0, 0, 2, 1);
137 m_gridFault->SetCellSize(0, 1, 1, 2);
138 m_gridFault->SetCellSize(0, 3, 1, 2);
139 m_gridFault->SetCellSize(0, 5, 1, 2);
140 // Values
141 for (auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) {
142 Bus* bus = *it;
143 if (bus->GetElectricalData().hasFault) m_gridFault->AppendRows();
144 }
145 m_gridFault->AutoSize();
146
147 // Fault buses
148 // Header
149 m_gridFaultBuses->AppendCols(7);
150 m_gridFaultBuses->AppendRows(2);
151 m_gridFaultBuses->HideColLabels();
152 m_gridFaultBuses->HideRowLabels();
153 for (int i = 0; i < 2; ++i) {
154 for (int j = 0; j < 7; ++j) {
155 m_gridFaultBuses->SetCellBackgroundColour(i, j, m_headerColour);
156 m_gridFaultBuses->SetCellFont(i, j, headerFont);
157 }
158 }
159 m_gridFaultBuses->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
160 m_gridFaultBuses->SetCellSize(0, 0, 2, 1);
161 m_gridFaultBuses->SetCellSize(0, 1, 1, 2);
162 m_gridFaultBuses->SetCellSize(0, 3, 1, 2);
163 m_gridFaultBuses->SetCellSize(0, 5, 1, 2);
164 // Values
165 m_gridFaultBuses->AppendRows(busList.size());
166 m_gridFaultBuses->AutoSize();
167
168 // Fault branches
169 // Header
170 m_gridFaultBranches->AppendCols(11);
171 m_gridFaultBranches->AppendRows(2);
172 m_gridFaultBranches->HideColLabels();
173 m_gridFaultBranches->HideRowLabels();
174 for (int i = 0; i < 2; ++i) {
175 for (int j = 0; j < 11; ++j) {
176 m_gridFaultBranches->SetCellBackgroundColour(i, j, m_headerColour);
177 m_gridFaultBranches->SetCellFont(i, j, headerFont);
178 }
179 }
180 m_gridFaultBranches->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
181 m_gridFaultBranches->SetCellSize(0, 0, 2, 1);
182 m_gridFaultBranches->SetCellSize(0, 1, 2, 1);
183 m_gridFaultBranches->SetCellSize(0, 2, 2, 1);
184 m_gridFaultBranches->SetCellSize(0, 3, 2, 1);
185 m_gridFaultBranches->SetCellSize(0, 10, 2, 1);
186 m_gridFaultBranches->SetCellSize(0, 4, 1, 2);
187 m_gridFaultBranches->SetCellSize(0, 6, 1, 2);
188 m_gridFaultBranches->SetCellSize(0, 8, 1, 2);
189 // Values
190 m_gridFaultBranches->AppendRows((lineList.size() + transformerList.size()) * 2);
191 m_gridFaultBranches->AutoSize();
192
193 // Fault generators
194 // Header
195 m_gridFaultGenerators->AppendCols(7);
196 m_gridFaultGenerators->AppendRows(2);
197 m_gridFaultGenerators->HideColLabels();
198 m_gridFaultGenerators->HideRowLabels();
199 for (int i = 0; i < 2; ++i) {
200 for (int j = 0; j < 7; ++j) {
201 m_gridFaultGenerators->SetCellBackgroundColour(i, j, m_headerColour);
202 m_gridFaultGenerators->SetCellFont(i, j, headerFont);
203 }
204 }
205 m_gridFaultGenerators->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
206 m_gridFaultGenerators->SetCellSize(0, 0, 2, 1);
207 m_gridFaultGenerators->SetCellSize(0, 1, 1, 2);
208 m_gridFaultGenerators->SetCellSize(0, 3, 1, 2);
209 m_gridFaultGenerators->SetCellSize(0, 5, 1, 2);
210 // Values
211 m_gridFaultGenerators->AppendRows(generatorList.size());
212 m_gridFaultGenerators->AutoSize();
213
214 // Harmonics currents
215 // Header
216 m_gridHarmCurrents->AppendCols(5);
217 m_gridHarmCurrents->AppendRows();
218 m_gridHarmCurrents->HideColLabels();
219 m_gridHarmCurrents->HideRowLabels();
220 for (int i = 0; i < 5; ++i) {
221 m_gridHarmCurrents->SetCellBackgroundColour(0, i, m_headerColour);
222 m_gridHarmCurrents->SetCellFont(0, i, headerFont);
223 }
224 m_gridHarmCurrents->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
225 // Values
226 int numRowDataHarmCurrent = 0;
227 for (auto* hSource : harmCurrentSourceList) {
228 numRowDataHarmCurrent += hSource->GetElectricalData().harmonicOrder.size();
229 }
230 m_gridHarmCurrents->AppendRows(numRowDataHarmCurrent);
231 m_gridHarmCurrents->AutoSize();
232
233 // Harmonics buses
234 // Header
235 m_gridHarmBuses->AppendCols(5);
236 m_gridHarmBuses->AppendRows();
237 m_gridHarmBuses->HideColLabels();
238 m_gridHarmBuses->HideRowLabels();
239 for (int i = 0; i < 5; ++i) {
240 m_gridHarmBuses->SetCellBackgroundColour(0, i, m_headerColour);
241 m_gridHarmBuses->SetCellFont(0, i, headerFont);
242 }
243 m_gridHarmBuses->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
244 // Values
245 int numRowDataHarmBuses = 0;
246 for (auto* bus : busList) {
247 numRowDataHarmBuses += bus->GetElectricalData().harmonicOrder.size();
248 }
249 m_gridHarmBuses->AppendRows(numRowDataHarmBuses);
250 m_gridHarmBuses->AutoSize();
251
252 // Harmonics branches currents
253 // Header
254 m_gridHarmBranches->AppendCols(8);
255 m_gridHarmBranches->AppendRows();
256 m_gridHarmBranches->HideColLabels();
257 m_gridHarmBranches->HideRowLabels();
258 for (int i = 0; i < 8; ++i) {
259 m_gridHarmBranches->SetCellBackgroundColour(0, i, m_headerColour);
260 m_gridHarmBranches->SetCellFont(0, i, headerFont);
261 }
262 m_gridHarmBranches->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
263 // Values
264 int numRowDataHarmBranches = 0;
265 for (auto* line : lineList) {
266 numRowDataHarmBranches += line->GetElectricalData().harmonicOrder.size();
267 }
268 for (auto* transformer : transformerList) {
269 numRowDataHarmBranches += transformer->GetElectricalData().harmonicOrder.size();
270 }
271 m_gridHarmBranches->AppendRows(numRowDataHarmBranches * 2.0);
272 m_gridHarmBranches->AutoSize();
273
274}
275
276void DataReport::SetHeaders()
277{
278 // Headers choices fill
279 wxString omega = static_cast<wxString>(L'\u03A9');
280
281 m_voltageChoices.Add(_("Voltage (p.u.)"));
282 m_voltageChoices.Add(_("Voltage (V)"));
283 m_voltageChoices.Add(_("Voltage (kV)"));
284
285 m_phaseVoltageChoices.Add(_("Phase Voltage (p.u.)"));
286 m_phaseVoltageChoices.Add(_("Phase Voltage (V)"));
287 m_phaseVoltageChoices.Add(_("Phase Voltage (kV)"));
288
289 m_activePowerChoices.Add(_("Active Power (p.u.)"));
290 m_activePowerChoices.Add(_("Active Power (W)"));
291 m_activePowerChoices.Add(_("Active Power (kW)"));
292 m_activePowerChoices.Add(_("Active Power (MW)"));
293
294 m_reactivePowerChoices.Add(_("Reactive Power (p.u.)"));
295 m_reactivePowerChoices.Add(_("Reactive Power (var)"));
296 m_reactivePowerChoices.Add(_("Reactive Power (kvar)"));
297 m_reactivePowerChoices.Add(_("Reactive Power (Mvar)"));
298
299 m_resistanceChoices.Add(_("R (p.u.)"));
300 m_resistanceChoices.Add(_("R (") + omega + wxT(")"));
301
302 m_indReactanceChoices.Add(_("XL (p.u.)"));
303 m_indReactanceChoices.Add(_("XL (") + omega + wxT(")"));
304
305 m_capSusceptanceChoices.Add(_("B (p.u.)"));
306 m_capSusceptanceChoices.Add(_("B (S)"));
307
308 m_currentChoices.Add(_("Current (p.u.)"));
309 m_currentChoices.Add(_("Current (A)"));
310 m_currentChoices.Add(_("Current (kA)"));
311
312 // Power flow
313 m_gridPowerFlow->SetCellValue(0, 0, _("Type"));
314 m_gridPowerFlow->SetCellValue(0, 1, _("Name"));
315 m_gridPowerFlow->SetCellValue(0, 2, _("From"));
316 m_gridPowerFlow->SetCellValue(0, 3, _("To"));
317 m_gridPowerFlow->SetCellEditor(0, 4, new wxGridCellChoiceEditor(m_activePowerChoices));
318 m_gridPowerFlow->SetCellValue(0, 4, m_activePowerChoices[3]);
319 m_gridPowerFlow->SetCellEditor(0, 5, new wxGridCellChoiceEditor(m_reactivePowerChoices));
320 m_gridPowerFlow->SetCellValue(0, 5, m_reactivePowerChoices[3]);
321 m_gridPowerFlow->SetCellValue(0, 6, _("Online"));
322
323 // Power flow buses
324 m_gridPFBuses->SetCellValue(0, 0, _("Name"));
325 m_gridPFBuses->SetCellValue(0, 1, _("Type"));
326 m_gridPFBuses->SetCellEditor(0, 2, new wxGridCellChoiceEditor(m_voltageChoices));
327 m_gridPFBuses->SetCellValue(0, 2, m_voltageChoices[0]);
328 m_gridPFBuses->SetCellValue(0, 3, _("Angle"));
329 m_gridPFBuses->SetCellEditor(0, 4, new wxGridCellChoiceEditor(m_activePowerChoices));
330 m_gridPFBuses->SetCellValue(0, 4, m_activePowerChoices[3]);
331 m_gridPFBuses->SetCellEditor(0, 5, new wxGridCellChoiceEditor(m_reactivePowerChoices));
332 m_gridPFBuses->SetCellValue(0, 5, m_reactivePowerChoices[3]);
333
334 // Power flow branches
335 m_gridPFBranches->SetCellValue(0, 0, _("Type"));
336 m_gridPFBranches->SetCellValue(0, 1, _("Name"));
337 m_gridPFBranches->SetCellValue(0, 2, _("From"));
338 m_gridPFBranches->SetCellValue(0, 3, _("To"));
339 m_gridPFBranches->SetCellEditor(0, 4, new wxGridCellChoiceEditor(m_resistanceChoices));
340 m_gridPFBranches->SetCellValue(0, 4, m_resistanceChoices[0]);
341 m_gridPFBranches->SetCellEditor(0, 5, new wxGridCellChoiceEditor(m_indReactanceChoices));
342 m_gridPFBranches->SetCellValue(0, 5, m_indReactanceChoices[0]);
343 m_gridPFBranches->SetCellEditor(0, 6, new wxGridCellChoiceEditor(m_capSusceptanceChoices));
344 m_gridPFBranches->SetCellValue(0, 6, m_capSusceptanceChoices[0]);
345 m_gridPFBranches->SetCellValue(0, 7, _("TAP"));
346 m_gridPFBranches->SetCellValue(0, 8, _("Phase Shift"));
347 m_gridPFBranches->SetCellValue(0, 9, _("Online"));
348
349 // Fault
350 m_gridFault->SetCellValue(0, 0, _("Fault bus name"));
351 m_gridFault->SetCellValue(0, 1, _("Phase A"));
352 m_gridFault->SetCellValue(0, 3, _("Phase B"));
353 m_gridFault->SetCellValue(0, 5, _("Phase C"));
354 m_gridFault->SetCellEditor(1, 1, new wxGridCellChoiceEditor(m_currentChoices));
355 m_gridFault->SetCellValue(1, 1, m_currentChoices[1]);
356 m_gridFault->SetCellValue(1, 2, _("Angle"));
357 m_gridFault->SetCellEditor(1, 3, new wxGridCellChoiceEditor(m_currentChoices));
358 m_gridFault->SetCellValue(1, 3, m_currentChoices[1]);
359 m_gridFault->SetCellValue(1, 4, _("Angle"));
360 m_gridFault->SetCellEditor(1, 5, new wxGridCellChoiceEditor(m_currentChoices));
361 m_gridFault->SetCellValue(1, 5, m_currentChoices[1]);
362 m_gridFault->SetCellValue(1, 6, _("Angle"));
363
364 // Fault buses
365 m_gridFaultBuses->SetCellValue(0, 0, _("Name"));
366 m_gridFaultBuses->SetCellValue(0, 1, _("Phase A"));
367 m_gridFaultBuses->SetCellValue(0, 3, _("Phase B"));
368 m_gridFaultBuses->SetCellValue(0, 5, _("Phase C"));
369 m_gridFaultBuses->SetCellEditor(1, 1, new wxGridCellChoiceEditor(m_voltageChoices));
370 m_gridFaultBuses->SetCellValue(1, 1, m_voltageChoices[0]);
371 m_gridFaultBuses->SetCellValue(1, 2, _("Angle"));
372 m_gridFaultBuses->SetCellEditor(1, 3, new wxGridCellChoiceEditor(m_voltageChoices));
373 m_gridFaultBuses->SetCellValue(1, 3, m_voltageChoices[0]);
374 m_gridFaultBuses->SetCellValue(1, 4, _("Angle"));
375 m_gridFaultBuses->SetCellEditor(1, 5, new wxGridCellChoiceEditor(m_voltageChoices));
376 m_gridFaultBuses->SetCellValue(1, 5, m_voltageChoices[0]);
377 m_gridFaultBuses->SetCellValue(1, 6, _("Angle"));
378
379 // Fault branches
380 m_gridFaultBranches->SetCellValue(0, 0, _("Type"));
381 m_gridFaultBranches->SetCellValue(0, 1, _("Name"));
382 m_gridFaultBranches->SetCellValue(0, 2, _("From"));
383 m_gridFaultBranches->SetCellValue(0, 3, _("To"));
384 m_gridFaultBranches->SetCellValue(0, 4, _("Phase A"));
385 m_gridFaultBranches->SetCellValue(0, 6, _("Phase B"));
386 m_gridFaultBranches->SetCellValue(0, 8, _("Phase C"));
387 m_gridFaultBranches->SetCellValue(0, 10, _("Online"));
388 m_gridFaultBranches->SetCellEditor(1, 4, new wxGridCellChoiceEditor(m_currentChoices));
389 m_gridFaultBranches->SetCellValue(1, 4, m_currentChoices[1]);
390 m_gridFaultBranches->SetCellValue(1, 5, _("Angle"));
391 m_gridFaultBranches->SetCellEditor(1, 6, new wxGridCellChoiceEditor(m_currentChoices));
392 m_gridFaultBranches->SetCellValue(1, 6, m_currentChoices[1]);
393 m_gridFaultBranches->SetCellValue(1, 7, _("Angle"));
394 m_gridFaultBranches->SetCellEditor(1, 8, new wxGridCellChoiceEditor(m_currentChoices));
395 m_gridFaultBranches->SetCellValue(1, 8, m_currentChoices[1]);
396 m_gridFaultBranches->SetCellValue(1, 9, _("Angle"));
397
398 // Fault generators
399 m_gridFaultGenerators->SetCellValue(0, 0, _("Name"));
400 m_gridFaultGenerators->SetCellValue(0, 1, _("Phase A"));
401 m_gridFaultGenerators->SetCellValue(0, 3, _("Phase B"));
402 m_gridFaultGenerators->SetCellValue(0, 5, _("Phase C"));
403 m_gridFaultGenerators->SetCellEditor(1, 1, new wxGridCellChoiceEditor(m_currentChoices));
404 m_gridFaultGenerators->SetCellValue(1, 1, m_currentChoices[1]);
405 m_gridFaultGenerators->SetCellValue(1, 2, _("Angle"));
406 m_gridFaultGenerators->SetCellEditor(1, 3, new wxGridCellChoiceEditor(m_currentChoices));
407 m_gridFaultGenerators->SetCellValue(1, 3, m_currentChoices[1]);
408 m_gridFaultGenerators->SetCellValue(1, 4, _("Angle"));
409 m_gridFaultGenerators->SetCellEditor(1, 5, new wxGridCellChoiceEditor(m_currentChoices));
410 m_gridFaultGenerators->SetCellValue(1, 5, m_currentChoices[1]);
411 m_gridFaultGenerators->SetCellValue(1, 6, _("Angle"));
412
413 // Harmonic Currents
414 m_gridHarmCurrents->SetCellValue(0, 0, _("Name"));
415 m_gridHarmCurrents->SetCellValue(0, 1, _("Bus"));
416 m_gridHarmCurrents->SetCellValue(0, 2, _("Harmonic"));
417 m_gridHarmCurrents->SetCellEditor(0, 3, new wxGridCellChoiceEditor(m_currentChoices));
418 m_gridHarmCurrents->SetCellValue(0, 3, m_currentChoices[1]);
419 m_gridHarmCurrents->SetCellValue(0, 4, _("Angle"));
420
421 // Harmonic Buses
422 m_gridHarmBuses->SetCellValue(0, 0, _("Name"));
423 m_gridHarmBuses->SetCellValue(0, 1, _("THD"));
424 m_gridHarmBuses->SetCellValue(0, 2, _("Harmonic"));
425 m_gridHarmBuses->SetCellEditor(0, 3, new wxGridCellChoiceEditor(m_phaseVoltageChoices));
426 m_gridHarmBuses->SetCellValue(0, 3, m_phaseVoltageChoices[0]);
427 m_gridHarmBuses->SetCellValue(0, 4, _("Angle"));
428
429 // Harmonic branches currents
430 m_gridHarmBranches->SetCellValue(0, 0, _("Type"));
431 m_gridHarmBranches->SetCellValue(0, 1, _("Name"));
432 m_gridHarmBranches->SetCellValue(0, 2, _("From"));
433 m_gridHarmBranches->SetCellValue(0, 3, _("To"));
434 m_gridHarmBranches->SetCellValue(0, 4, _("Harmonic"));
435 m_gridHarmBranches->SetCellEditor(0, 5, new wxGridCellChoiceEditor(m_currentChoices));
436 m_gridHarmBranches->SetCellValue(0, 5, m_currentChoices[1]);
437 m_gridHarmBranches->SetCellValue(0, 6, _("Angle"));
438 m_gridHarmBranches->SetCellValue(0, 7, _("Online"));
439}
440
441void DataReport::FillValues(GridSelection gridToFill)
442{
443 m_changingValues = true;
445 eCalc.GetElementsFromList(m_workspace->GetElementList());
446
447 double basePower = m_workspace->GetProperties()->GetSimulationPropertiesData().basePower;
448 switch (m_workspace->GetProperties()->GetSimulationPropertiesData().basePowerUnit) {
450 basePower *= 1e3;
451 } break;
453 basePower *= 1e6;
454 } break;
455 default:
456 break;
457 }
458
459 int rowNumber = 1;
460 auto lineList = eCalc.GetLineList();
461 auto transformerList = eCalc.GetTransformerList();
462 auto busList = eCalc.GetBusList();
463 auto generatorList = eCalc.GetSyncGeneratorList();
464 auto harmCurrentList = eCalc.GetHarmCurrentList();
465
466 // Power Flow
467 if (gridToFill == GRID_ALL || gridToFill == GRID_PF) {
468 double kActivePower = 1.0;
469 if (m_gridPowerFlow->GetCellValue(0, 4) == m_activePowerChoices[1])
470 kActivePower = basePower;
471 else if (m_gridPowerFlow->GetCellValue(0, 4) == m_activePowerChoices[2])
472 kActivePower = basePower / 1e3;
473 else if (m_gridPowerFlow->GetCellValue(0, 4) == m_activePowerChoices[3])
474 kActivePower = basePower / 1e6;
475
476 double kReactivePower = 1.0;
477 if (m_gridPowerFlow->GetCellValue(0, 5) == m_reactivePowerChoices[1])
478 kReactivePower = basePower;
479 else if (m_gridPowerFlow->GetCellValue(0, 5) == m_reactivePowerChoices[2])
480 kReactivePower = basePower / 1e3;
481 else if (m_gridPowerFlow->GetCellValue(0, 5) == m_reactivePowerChoices[3])
482 kReactivePower = basePower / 1e6;
483
484 for (auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) {
485 Line* line = *it;
486
487 wxString busName1 = "-";
488 if (line->GetParentList()[0])
489 busName1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().name;
490 wxString busName2 = "-";
491 if (line->GetParentList()[1])
492 busName2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().name;
493
494 wxString isOnline = _("Yes");
495 wxColour textColour = m_gridPowerFlow->GetDefaultCellTextColour();
496 if (!line->IsOnline()) {
497 isOnline = _("No");
498 textColour = m_offlineColour;
499 }
500 for (int i = 0; i < 2; ++i) {
501 for (int j = 0; j < 7; ++j) { m_gridPowerFlow->SetCellTextColour(rowNumber + i, j, textColour); }
502 }
503
504 auto data = line->GetPUElectricalData(basePower);
505
506 m_gridPowerFlow->SetCellValue(rowNumber, 0, _("Line"));
507 m_gridPowerFlow->SetCellValue(rowNumber, 1, data.name);
508 m_gridPowerFlow->SetCellValue(rowNumber, 2, busName1);
509 m_gridPowerFlow->SetCellValue(rowNumber, 3, busName2);
510 m_gridPowerFlow->SetCellValue(rowNumber, 4,
511 line->StringFromDouble(std::real(data.powerFlow[0]) * kActivePower, 0, m_precision));
512 m_gridPowerFlow->SetCellValue(rowNumber, 5,
513 line->StringFromDouble(std::imag(data.powerFlow[0]) * kReactivePower, 0, m_precision));
514 m_gridPowerFlow->SetCellValue(rowNumber, 6, isOnline);
515 rowNumber++;
516
517 m_gridPowerFlow->SetCellValue(rowNumber, 0, _("Line"));
518 m_gridPowerFlow->SetCellValue(rowNumber, 1, data.name);
519 m_gridPowerFlow->SetCellValue(rowNumber, 2, busName2);
520 m_gridPowerFlow->SetCellValue(rowNumber, 3, busName1);
521 m_gridPowerFlow->SetCellValue(rowNumber, 4,
522 line->StringFromDouble(std::real(data.powerFlow[1]) * kActivePower, 0, m_precision));
523 m_gridPowerFlow->SetCellValue(rowNumber, 5,
524 line->StringFromDouble(std::imag(data.powerFlow[1]) * kReactivePower, 0, m_precision));
525 m_gridPowerFlow->SetCellValue(rowNumber, 6, isOnline);
526 rowNumber++;
527 }
528
529 for (auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) {
530 Transformer* transformer = *it;
531 auto data = transformer->GetPUElectricalData(basePower);
532
533 wxString busName1 = "-";
534 if (transformer->GetParentList()[0])
535 busName1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().name;
536 wxString busName2 = "-";
537 if (transformer->GetParentList()[1])
538 busName2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().name;
539
540 wxString isOnline = _("Yes");
541 wxColour textColour = m_gridPowerFlow->GetDefaultCellTextColour();
542 if (!transformer->IsOnline()) {
543 isOnline = _("No");
544 textColour = m_offlineColour;
545 }
546 for (int i = 0; i < 2; ++i) {
547 for (int j = 0; j < 7; ++j) { m_gridPowerFlow->SetCellTextColour(rowNumber + i, j, textColour); }
548 }
549
550 m_gridPowerFlow->SetCellValue(rowNumber, 0, _("Transformer"));
551 m_gridPowerFlow->SetCellValue(rowNumber, 1, data.name);
552 m_gridPowerFlow->SetCellValue(rowNumber, 2, busName1);
553 m_gridPowerFlow->SetCellValue(rowNumber, 3, busName2);
554 m_gridPowerFlow->SetCellValue(rowNumber, 4,
555 transformer->StringFromDouble(std::real(data.powerFlow[0]) * kActivePower, 0, m_precision));
556 m_gridPowerFlow->SetCellValue(rowNumber, 5,
557 transformer->StringFromDouble(std::imag(data.powerFlow[0]) * kReactivePower, 0, m_precision));
558 m_gridPowerFlow->SetCellValue(rowNumber, 6, isOnline);
559 rowNumber++;
560
561 m_gridPowerFlow->SetCellValue(rowNumber, 0, _("Transformer"));
562 m_gridPowerFlow->SetCellValue(rowNumber, 1, data.name);
563 m_gridPowerFlow->SetCellValue(rowNumber, 2, busName2);
564 m_gridPowerFlow->SetCellValue(rowNumber, 3, busName1);
565 m_gridPowerFlow->SetCellValue(rowNumber, 4,
566 transformer->StringFromDouble(std::real(data.powerFlow[1]) * kActivePower, 0, m_precision));
567 m_gridPowerFlow->SetCellValue(rowNumber, 5,
568 transformer->StringFromDouble(std::imag(data.powerFlow[1]) * kReactivePower, 0, m_precision));
569 m_gridPowerFlow->SetCellValue(rowNumber, 6, isOnline);
570 rowNumber++;
571 }
572 m_gridPowerFlow->AutoSize();
573 m_gridPowerFlow->GetContainingSizer()->Layout();
574 }
575
576 // Power Flow buses
577 if (gridToFill == GRID_ALL || gridToFill == GRID_PFBUSES) {
578 double kActivePower = 1.0;
579 if (m_gridPFBuses->GetCellValue(0, 4) == m_activePowerChoices[1])
580 kActivePower = basePower;
581 else if (m_gridPFBuses->GetCellValue(0, 4) == m_activePowerChoices[2])
582 kActivePower = basePower / 1e3;
583 else if (m_gridPFBuses->GetCellValue(0, 4) == m_activePowerChoices[3])
584 kActivePower = basePower / 1e6;
585
586 double kReactivePower = 1.0;
587 if (m_gridPFBuses->GetCellValue(0, 5) == m_reactivePowerChoices[1])
588 kReactivePower = basePower;
589 else if (m_gridPFBuses->GetCellValue(0, 5) == m_reactivePowerChoices[2])
590 kReactivePower = basePower / 1e3;
591 else if (m_gridPFBuses->GetCellValue(0, 5) == m_reactivePowerChoices[3])
592 kReactivePower = basePower / 1e6;
593
594 rowNumber = 1;
595 for (auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) {
596 Bus* bus = *it;
597 auto data = bus->GetElectricalData();
598
599 double vb = std::abs(data.nominalVoltage);
600 if (data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
601 double kVoltage = 1.0;
602 if (m_gridPFBuses->GetCellValue(0, 2) == m_voltageChoices[1])
603 kVoltage = vb;
604 else if (m_gridPFBuses->GetCellValue(0, 2) == m_voltageChoices[2])
605 kVoltage = vb / 1e3;
606
607 m_gridPFBuses->SetCellValue(rowNumber, 0, data.name);
608 wxString busTypeString = "";
609 switch (data.busType) {
610 case BUS_SLACK: {
611 busTypeString = _("Slack");
612 } break;
613 case BUS_PV: {
614 busTypeString = _("PV");
615 } break;
616 case BUS_PQ: {
617 busTypeString = _("PQ");
618 } break;
619 }
620 m_gridPFBuses->SetCellValue(rowNumber, 1, busTypeString);
621 m_gridPFBuses->SetCellValue(rowNumber, 2, bus->StringFromDouble(std::abs(data.voltage) * kVoltage, 0, m_precision));
622 m_gridPFBuses->SetCellValue(rowNumber, 3, bus->StringFromDouble(wxRadToDeg(std::arg(data.voltage)), 0, m_precision));
623 m_gridPFBuses->SetCellValue(rowNumber, 4, bus->StringFromDouble(std::real(data.power) * kActivePower, 0, m_precision));
624 m_gridPFBuses->SetCellValue(rowNumber, 5, bus->StringFromDouble(std::imag(data.power) * kReactivePower, 0, m_precision));
625 rowNumber++;
626 }
627 m_gridPFBuses->AutoSize();
628 m_gridPFBuses->GetContainingSizer()->Layout();
629 }
630
631 // Power flow branches
632 if (gridToFill == GRID_ALL || gridToFill == GRID_PFBRANCHES) {
633 rowNumber = 1;
634 for (auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) {
635 Line* line = *it;
636 auto data = line->GetPUElectricalData(basePower);
637
638 double vb = data.nominalVoltage;
639 if (data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
640 double zb = (vb * vb) / basePower;
641
642 wxString busName1 = "-";
643 if (line->GetParentList()[0])
644 busName1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().name;
645 wxString busName2 = "-";
646 if (line->GetParentList()[1])
647 busName2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().name;
648 wxString isOnline = _("Yes");
649 wxColour textColour = m_gridPFBranches->GetDefaultCellTextColour();
650 if (!line->IsOnline()) {
651 isOnline = _("No");
652 textColour = m_offlineColour;
653 }
654 for (int j = 0; j < 10; ++j) { m_gridPFBranches->SetCellTextColour(rowNumber, j, textColour); }
655
656 m_gridPFBranches->SetCellValue(rowNumber, 0, _("Line"));
657 m_gridPFBranches->SetCellValue(rowNumber, 1, data.name);
658
659 m_gridPFBranches->SetCellValue(rowNumber, 2, busName1);
660 m_gridPFBranches->SetCellValue(rowNumber, 3, busName2);
661
662 double k = 1.0;
663 if (m_gridPFBranches->GetCellValue(0, 4) == m_resistanceChoices[1]) k = zb;
664 m_gridPFBranches->SetCellValue(rowNumber, 4, line->StringFromDouble(data.resistance * k, 0, m_precision));
665 k = 1.0;
666 if (m_gridPFBranches->GetCellValue(0, 5) == m_indReactanceChoices[1]) k = zb;
667 m_gridPFBranches->SetCellValue(rowNumber, 5, line->StringFromDouble(data.indReactance * k, 0, m_precision));
668 k = 1.0;
669 if (m_gridPFBranches->GetCellValue(0, 6) == m_capSusceptanceChoices[1]) k = zb;
670 m_gridPFBranches->SetCellValue(rowNumber, 6, line->StringFromDouble(data.capSusceptance / k, 0, m_precision));
671 m_gridPFBranches->SetCellValue(rowNumber, 7, "-");
672 m_gridPFBranches->SetCellValue(rowNumber, 8, "-");
673 m_gridPFBranches->SetCellValue(rowNumber, 9, isOnline);
674 rowNumber++;
675 }
676 for (auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) {
677 Transformer* transformer = *it;
678 auto data = transformer->GetPUElectricalData(basePower);
679
680 double vb = 0.0;
681 if (data.baseVoltage == 0) {
682 vb = data.primaryNominalVoltage;
683 if (data.primaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
684 }
685 else {
686 vb = data.secondaryNominalVoltage;
687 if (data.secondaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) vb *= 1e3;
688 }
689 double zb = (vb * vb) / basePower;
690
691 wxString busName1 = "-";
692 if (transformer->GetParentList()[0])
693 busName1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().name;
694 wxString busName2 = "-";
695 if (transformer->GetParentList()[1])
696 busName2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().name;
697
698 wxString isOnline = _("Yes");
699 wxColour textColour = m_gridPFBranches->GetDefaultCellTextColour();
700 if (!transformer->IsOnline()) {
701 isOnline = _("No");
702 textColour = m_offlineColour;
703 }
704 for (int j = 0; j < 10; ++j) { m_gridPFBranches->SetCellTextColour(rowNumber, j, textColour); }
705
706 m_gridPFBranches->SetCellValue(rowNumber, 0, _("Transformer"));
707 m_gridPFBranches->SetCellValue(rowNumber, 1, data.name);
708 m_gridPFBranches->SetCellValue(rowNumber, 2, busName1);
709 m_gridPFBranches->SetCellValue(rowNumber, 3, busName2);
710
711 double k = 1.0;
712 if (m_gridPFBranches->GetCellValue(0, 4) == m_resistanceChoices[1]) k = zb;
713 m_gridPFBranches->SetCellValue(rowNumber, 4, transformer->StringFromDouble(data.resistance * k, 0, m_precision));
714 k = 1.0;
715 if (m_gridPFBranches->GetCellValue(0, 5) == m_indReactanceChoices[1]) k = zb;
716 m_gridPFBranches->SetCellValue(rowNumber, 5, transformer->StringFromDouble(data.indReactance * k, 0, m_precision));
717 m_gridPFBranches->SetCellValue(rowNumber, 6, "-");
718 m_gridPFBranches->SetCellValue(rowNumber, 7, transformer->StringFromDouble(data.turnsRatio, 0, m_precision));
719 m_gridPFBranches->SetCellValue(rowNumber, 8, transformer->StringFromDouble(data.phaseShift, 0, m_precision));
720 m_gridPFBranches->SetCellValue(rowNumber, 9, isOnline);
721 rowNumber++;
722 }
723 m_gridPFBranches->AutoSize();
724 m_gridPFBranches->GetContainingSizer()->Layout();
725 }
726
727 // Fault
728 if (gridToFill == GRID_ALL || gridToFill == GRID_FAULT) {
729 rowNumber = 2;
730 for (auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) {
731 Bus* bus = *it;
732 auto data = bus->GetElectricalData();
733 if (data.hasFault) {
734 double vb = bus->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
735 double ib = basePower / (std::sqrt(3.0) * vb);
736
737 m_gridFault->SetCellValue(rowNumber, 0, data.name);
738
739 double kCurrent = 1.0;
740 if (m_gridFault->GetCellValue(1, 1) == m_currentChoices[1]) {
741 kCurrent = ib;
742 }
743 else if (m_gridFault->GetCellValue(1, 1) == m_currentChoices[2]) {
744 kCurrent = ib / 1e3;
745 }
746 m_gridFault->SetCellValue(rowNumber, 1,
747 bus->StringFromDouble(std::abs(data.faultCurrent[0]) * kCurrent, 0, m_precision));
748
749 m_gridFault->SetCellValue(rowNumber, 2,
750 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0])), 0, m_precision));
751
752 kCurrent = 1.0;
753 if (m_gridFault->GetCellValue(1, 3) == m_currentChoices[1]) {
754 kCurrent = ib;
755 }
756 else if (m_gridFault->GetCellValue(1, 3) == m_currentChoices[2]) {
757 kCurrent = ib / 1e3;
758 }
759 m_gridFault->SetCellValue(rowNumber, 3,
760 bus->StringFromDouble(std::abs(data.faultCurrent[1]) * kCurrent, 0, m_precision));
761
762 m_gridFault->SetCellValue(rowNumber, 4,
763 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1])), 0, m_precision));
764
765 kCurrent = 1.0;
766 if (m_gridFault->GetCellValue(1, 5) == m_currentChoices[1]) {
767 kCurrent = ib;
768 }
769 else if (m_gridFault->GetCellValue(1, 5) == m_currentChoices[2]) {
770 kCurrent = ib / 1e3;
771 }
772 m_gridFault->SetCellValue(rowNumber, 5,
773 bus->StringFromDouble(std::abs(data.faultCurrent[2]) * kCurrent, 0, m_precision));
774
775 m_gridFault->SetCellValue(rowNumber, 6,
776 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[2])), 0, m_precision));
777
778 rowNumber++;
779 }
780 }
781 m_gridFault->AutoSize();
782 m_gridFault->GetContainingSizer()->Layout();
783 }
784
785 // Fault buses
786 if (gridToFill == GRID_ALL || gridToFill == GRID_FAULTBUSES) {
787 rowNumber = 2;
788 for (auto it = busList.begin(), itEnd = busList.end(); it != itEnd; ++it) {
789 Bus* bus = *it;
790 auto data = bus->GetElectricalData();
791 double vb = bus->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
792
793 m_gridFaultBuses->SetCellValue(rowNumber, 0, data.name);
794 double kVoltage = 1.0;
795 if (m_gridFaultBuses->GetCellValue(1, 1) == m_voltageChoices[1]) {
796 kVoltage = vb;
797 }
798 else if (m_gridFaultBuses->GetCellValue(1, 1) == m_voltageChoices[2]) {
799 kVoltage = vb / 1e3;
800 }
801 m_gridFaultBuses->SetCellValue(rowNumber, 1,
802 bus->StringFromDouble(std::abs(data.faultVoltage[0]) * kVoltage, 0, m_precision));
803 m_gridFaultBuses->SetCellValue(rowNumber, 2,
804 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultVoltage[0])), 0, m_precision));
805
806 kVoltage = 1.0;
807 if (m_gridFaultBuses->GetCellValue(1, 3) == m_voltageChoices[1]) {
808 kVoltage = vb;
809 }
810 else if (m_gridFaultBuses->GetCellValue(1, 3) == m_voltageChoices[2]) {
811 kVoltage = vb / 1e3;
812 }
813 m_gridFaultBuses->SetCellValue(rowNumber, 3,
814 bus->StringFromDouble(std::abs(data.faultVoltage[1]) * kVoltage, 0, m_precision));
815 m_gridFaultBuses->SetCellValue(rowNumber, 4,
816 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultVoltage[1])), 0, m_precision));
817
818 kVoltage = 1.0;
819 if (m_gridFaultBuses->GetCellValue(1, 5) == m_voltageChoices[1]) {
820 kVoltage = vb;
821 }
822 else if (m_gridFaultBuses->GetCellValue(1, 5) == m_voltageChoices[2]) {
823 kVoltage = vb / 1e3;
824 }
825 m_gridFaultBuses->SetCellValue(rowNumber, 5,
826 bus->StringFromDouble(std::abs(data.faultVoltage[2]) * kVoltage, 0, m_precision));
827 m_gridFaultBuses->SetCellValue(rowNumber, 6,
828 bus->StringFromDouble(wxRadToDeg(std::arg(data.faultVoltage[2])), 0, m_precision));
829
830 rowNumber++;
831 }
832 m_gridFaultBuses->AutoSize();
833 m_gridFaultBuses->GetContainingSizer()->Layout();
834 }
835
836 // Fault branches
837 if (gridToFill == GRID_ALL || gridToFill == GRID_FAULTBRANCHES) {
838 rowNumber = 2;
839 for (auto it = lineList.begin(), itEnd = lineList.end(); it != itEnd; ++it) {
840 Line* line = *it;
841 auto data = line->GetPUElectricalData(basePower);
842
843 double vb = line->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
844 double ib = basePower / (std::sqrt(3.0) * vb);
845
846 wxString busName1 = "-";
847 if (line->GetParentList()[0])
848 busName1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().name;
849 wxString busName2 = "-";
850 if (line->GetParentList()[1])
851 busName2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().name;
852
853 wxString isOnline = _("Yes");
854 wxColour textColour = m_gridFaultBranches->GetDefaultCellTextColour();
855 if (!line->IsOnline()) {
856 isOnline = _("No");
857 textColour = m_offlineColour;
858 }
859 for (int i = 0; i < 2; ++i) {
860 for (int j = 0; j < 11; ++j) { m_gridFaultBranches->SetCellTextColour(rowNumber + i, j, textColour); }
861 }
862
863 m_gridFaultBranches->SetCellValue(rowNumber, 0, _("Line"));
864 m_gridFaultBranches->SetCellValue(rowNumber, 1, data.name);
865 m_gridFaultBranches->SetCellValue(rowNumber, 2, busName1);
866 m_gridFaultBranches->SetCellValue(rowNumber, 3, busName2);
867
868 double kCurrent = 1.0;
869 if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[1]) {
870 kCurrent = ib;
871 }
872 else if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[2]) {
873 kCurrent = ib / 1e3;
874 }
875 m_gridFaultBranches->SetCellValue(rowNumber, 4,
876 line->StringFromDouble(std::abs(data.faultCurrent[0][0]) * kCurrent, 0, m_precision));
877 m_gridFaultBranches->SetCellValue(rowNumber, 5,
878 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][0])), 0, m_precision));
879 kCurrent = 1.0;
880 if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[1]) {
881 kCurrent = ib;
882 }
883 else if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[2]) {
884 kCurrent = ib / 1e3;
885 }
886 m_gridFaultBranches->SetCellValue(rowNumber, 6,
887 line->StringFromDouble(std::abs(data.faultCurrent[0][1]) * kCurrent, 0, m_precision));
888 m_gridFaultBranches->SetCellValue(rowNumber, 7,
889 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][1])), 0, m_precision));
890 kCurrent = 1.0;
891 if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[1]) {
892 kCurrent = ib;
893 }
894 else if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[2]) {
895 kCurrent = ib / 1e3;
896 }
897 m_gridFaultBranches->SetCellValue(rowNumber, 8,
898 line->StringFromDouble(std::abs(data.faultCurrent[0][2]) * kCurrent, 0, m_precision));
899 m_gridFaultBranches->SetCellValue(rowNumber, 9,
900 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][2])), 0, m_precision));
901 m_gridFaultBranches->SetCellValue(rowNumber, 10, isOnline);
902 rowNumber++;
903
904 m_gridFaultBranches->SetCellValue(rowNumber, 0, _("Line"));
905 m_gridFaultBranches->SetCellValue(rowNumber, 1, data.name);
906 m_gridFaultBranches->SetCellValue(rowNumber, 2, busName2);
907 m_gridFaultBranches->SetCellValue(rowNumber, 3, busName1);
908 kCurrent = 1.0;
909 if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[1]) {
910 kCurrent = ib;
911 }
912 else if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[2]) {
913 kCurrent = ib / 1e3;
914 }
915 m_gridFaultBranches->SetCellValue(rowNumber, 4,
916 line->StringFromDouble(std::abs(data.faultCurrent[1][0]) * kCurrent, 0, m_precision));
917 m_gridFaultBranches->SetCellValue(rowNumber, 5,
918 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][0])), 0, m_precision));
919 kCurrent = 1.0;
920 if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[1]) {
921 kCurrent = ib;
922 }
923 else if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[2]) {
924 kCurrent = ib / 1e3;
925 }
926 m_gridFaultBranches->SetCellValue(rowNumber, 6,
927 line->StringFromDouble(std::abs(data.faultCurrent[1][1]) * kCurrent, 0, m_precision));
928 m_gridFaultBranches->SetCellValue(rowNumber, 7,
929 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][1])), 0, m_precision));
930 kCurrent = 1.0;
931 if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[1]) {
932 kCurrent = ib;
933 }
934 else if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[2]) {
935 kCurrent = ib / 1e3;
936 }
937 m_gridFaultBranches->SetCellValue(rowNumber, 8,
938 line->StringFromDouble(std::abs(data.faultCurrent[1][2]) * kCurrent, 0, m_precision));
939 m_gridFaultBranches->SetCellValue(rowNumber, 9,
940 line->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][2])), 0, m_precision));
941 m_gridFaultBranches->SetCellValue(rowNumber, 10, isOnline);
942 rowNumber++;
943 }
944
945 for (auto it = transformerList.begin(), itEnd = transformerList.end(); it != itEnd; ++it) {
946 Transformer* transformer = *it;
947 auto data = transformer->GetPUElectricalData(basePower);
948
949 double vb = transformer->GetValueFromUnit(data.primaryNominalVoltage, data.primaryNominalVoltageUnit);
950 double ibp = basePower / (std::sqrt(3.0) * vb);
951 vb = transformer->GetValueFromUnit(data.secondaryNominalVoltage, data.secondaryNominalVoltageUnit);
952 double ibs = basePower / (std::sqrt(3.0) * vb);
953
954 wxString busName1 = "-";
955 if (transformer->GetParentList()[0])
956 busName1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().name;
957 wxString busName2 = "-";
958 if (transformer->GetParentList()[1])
959 busName2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().name;
960
961 wxString isOnline = _("Yes");
962 wxColour textColour = m_gridFaultBranches->GetDefaultCellTextColour();
963 if (!transformer->IsOnline()) {
964 isOnline = _("No");
965 textColour = m_offlineColour;
966 }
967 for (int i = 0; i < 2; ++i) {
968 for (int j = 0; j < 11; ++j) { m_gridFaultBranches->SetCellTextColour(rowNumber + i, j, textColour); }
969 }
970
971 m_gridFaultBranches->SetCellValue(rowNumber, 0, _("Transformer"));
972 m_gridFaultBranches->SetCellValue(rowNumber, 1, data.name);
973 m_gridFaultBranches->SetCellValue(rowNumber, 2, busName1);
974 m_gridFaultBranches->SetCellValue(rowNumber, 3, busName2);
975
976 double kCurrent = 1.0;
977 if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[1]) {
978 kCurrent = ibp;
979 }
980 else if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[2]) {
981 kCurrent = ibp / 1e3;
982 }
983 m_gridFaultBranches->SetCellValue(
984 rowNumber, 4, transformer->StringFromDouble(std::abs(data.faultCurrent[0][0]) * kCurrent, 0, m_precision));
985 m_gridFaultBranches->SetCellValue(
986 rowNumber, 5, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][0])), 0, m_precision));
987 kCurrent = 1.0;
988 if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[1]) {
989 kCurrent = ibp;
990 }
991 else if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[2]) {
992 kCurrent = ibp / 1e3;
993 }
994 m_gridFaultBranches->SetCellValue(
995 rowNumber, 6, transformer->StringFromDouble(std::abs(data.faultCurrent[0][1]) * kCurrent, 0, m_precision));
996 m_gridFaultBranches->SetCellValue(
997 rowNumber, 7, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][1])), 0, m_precision));
998 kCurrent = 1.0;
999 if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[1]) {
1000 kCurrent = ibp;
1001 }
1002 else if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[2]) {
1003 kCurrent = ibp / 1e3;
1004 }
1005 m_gridFaultBranches->SetCellValue(
1006 rowNumber, 8, transformer->StringFromDouble(std::abs(data.faultCurrent[0][2]) * kCurrent, 0, m_precision));
1007 m_gridFaultBranches->SetCellValue(
1008 rowNumber, 9, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0][2])), 0, m_precision));
1009 m_gridFaultBranches->SetCellValue(rowNumber, 10, isOnline);
1010 rowNumber++;
1011
1012 m_gridFaultBranches->SetCellValue(rowNumber, 0, _("Transformer"));
1013 m_gridFaultBranches->SetCellValue(rowNumber, 1, data.name);
1014 m_gridFaultBranches->SetCellValue(rowNumber, 2, busName2);
1015 m_gridFaultBranches->SetCellValue(rowNumber, 3, busName1);
1016 kCurrent = 1.0;
1017 if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[1]) {
1018 kCurrent = ibs;
1019 }
1020 else if (m_gridFaultBranches->GetCellValue(1, 4) == m_currentChoices[2]) {
1021 kCurrent = ibs / 1e3;
1022 }
1023 m_gridFaultBranches->SetCellValue(
1024 rowNumber, 4, transformer->StringFromDouble(std::abs(data.faultCurrent[1][0]) * kCurrent, 0, m_precision));
1025 m_gridFaultBranches->SetCellValue(
1026 rowNumber, 5, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][0])), 0, m_precision));
1027 kCurrent = 1.0;
1028 if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[1]) {
1029 kCurrent = ibs;
1030 }
1031 else if (m_gridFaultBranches->GetCellValue(1, 6) == m_currentChoices[2]) {
1032 kCurrent = ibs / 1e3;
1033 }
1034 m_gridFaultBranches->SetCellValue(
1035 rowNumber, 6, transformer->StringFromDouble(std::abs(data.faultCurrent[1][1]) * kCurrent, 0, m_precision));
1036 m_gridFaultBranches->SetCellValue(
1037 rowNumber, 7, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][1])), 0, m_precision));
1038 kCurrent = 1.0;
1039 if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[1]) {
1040 kCurrent = ibs;
1041 }
1042 else if (m_gridFaultBranches->GetCellValue(1, 8) == m_currentChoices[2]) {
1043 kCurrent = ibs / 1e3;
1044 }
1045 m_gridFaultBranches->SetCellValue(
1046 rowNumber, 8, transformer->StringFromDouble(std::abs(data.faultCurrent[1][2]) * kCurrent, 0, m_precision));
1047 m_gridFaultBranches->SetCellValue(
1048 rowNumber, 9, transformer->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1][2])), 0, m_precision));
1049 m_gridFaultBranches->SetCellValue(rowNumber, 10, isOnline);
1050 rowNumber++;
1051 }
1052
1053 m_gridFaultBranches->AutoSize();
1054 m_gridFaultBranches->GetContainingSizer()->Layout();
1055 }
1056
1057 // Fault generators
1058 if (gridToFill == GRID_ALL || gridToFill == GRID_FAULTGENERATORS) {
1059 rowNumber = 2;
1060 for (auto it = generatorList.begin(), itEnd = generatorList.end(); it != itEnd; ++it) {
1061 SyncGenerator* generator = *it;
1062 auto data = generator->GetPUElectricalData(basePower);
1063 double vb = generator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
1064 double ib = basePower / (std::sqrt(3.0) * vb);
1065
1066 m_gridFaultGenerators->SetCellValue(rowNumber, 0, data.name);
1067
1068 double kCurrent = 1.0;
1069 if (m_gridFaultGenerators->GetCellValue(1, 1) == m_currentChoices[1])
1070 kCurrent = ib;
1071 else if (m_gridFaultGenerators->GetCellValue(1, 1) == m_currentChoices[2])
1072 kCurrent = ib / 1e3;
1073 m_gridFaultGenerators->SetCellValue(rowNumber, 1,
1074 generator->StringFromDouble(std::abs(data.faultCurrent[0]) * kCurrent, 0, m_precision));
1075 m_gridFaultGenerators->SetCellValue(
1076 rowNumber, 2, generator->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[0])), 0, m_precision));
1077
1078 kCurrent = 1.0;
1079 if (m_gridFaultGenerators->GetCellValue(1, 3) == m_currentChoices[1])
1080 kCurrent = ib;
1081 else if (m_gridFaultGenerators->GetCellValue(1, 3) == m_currentChoices[2])
1082 kCurrent = ib / 1e3;
1083 m_gridFaultGenerators->SetCellValue(rowNumber, 3,
1084 generator->StringFromDouble(std::abs(data.faultCurrent[1]) * kCurrent, 0, m_precision));
1085 m_gridFaultGenerators->SetCellValue(
1086 rowNumber, 4, generator->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[1])), 0, m_precision));
1087
1088 kCurrent = 1.0;
1089 if (m_gridFaultGenerators->GetCellValue(1, 5) == m_currentChoices[1])
1090 kCurrent = ib;
1091 else if (m_gridFaultGenerators->GetCellValue(1, 5) == m_currentChoices[2])
1092 kCurrent = ib / 1e3;
1093 m_gridFaultGenerators->SetCellValue(rowNumber, 5,
1094 generator->StringFromDouble(std::abs(data.faultCurrent[2]) * kCurrent, 0, m_precision));
1095 m_gridFaultGenerators->SetCellValue(
1096 rowNumber, 6, generator->StringFromDouble(wxRadToDeg(std::arg(data.faultCurrent[2])), 0, m_precision));
1097
1098 rowNumber++;
1099 }
1100 m_gridFaultGenerators->AutoSize();
1101 m_gridFaultGenerators->GetContainingSizer()->Layout();
1102 }
1103
1104 // Harmonic Currents
1105 if (gridToFill == GRID_ALL || gridToFill == GRID_HARMCURRENT) {
1106 rowNumber = 1;
1107 for (auto* hCurrent : harmCurrentList) {
1108 if (hCurrent->GetParentList()[0]) {
1109 auto busData = static_cast<Bus*>(hCurrent->GetParentList()[0])->GetElectricalData();
1110 double vb = hCurrent->GetValueFromUnit(busData.nominalVoltage, busData.nominalVoltageUnit);
1111 double ib = basePower / (std::sqrt(3.0) * vb);
1112
1113 auto data = hCurrent->GetPUElectricalData(basePower, vb);
1114 m_gridHarmCurrents->SetCellSize(rowNumber, 0, data.harmonicOrder.size(), 1);
1115 m_gridHarmCurrents->SetCellValue(rowNumber, 0, data.name);
1116 m_gridHarmCurrents->SetCellSize(rowNumber, 1, data.harmonicOrder.size(), 1);
1117 m_gridHarmCurrents->SetCellValue(rowNumber, 1, busData.name);
1118 int i = 0;
1119 for (auto& order : data.harmonicOrder) {
1120 m_gridHarmCurrents->SetCellValue(rowNumber, 2, wxString::Format(wxT("%d%s"), order, wxString(L'\u00BA')));
1121 double kCurrent = 1.0;
1122 if (m_gridHarmCurrents->GetCellValue(0, 3) == m_currentChoices[1]) {
1123 kCurrent = ib;
1124 }
1125 else if (m_gridHarmCurrents->GetCellValue(0, 3) == m_currentChoices[2]) {
1126 kCurrent = ib / 1e3;
1127 }
1128 m_gridHarmCurrents->SetCellValue(rowNumber, 3, hCurrent->StringFromDouble(data.injHarmCurrent[i] * kCurrent, 0, m_precision));
1129 m_gridHarmCurrents->SetCellValue(rowNumber, 4, hCurrent->StringFromDouble(data.injHarmAngle[i], 0, m_precision) + wxString(L'\u00B0'));
1130 i++;
1131 rowNumber++;
1132 }
1133 }
1134 else {
1135 auto data = hCurrent->GetElectricalData();
1136 m_gridHarmCurrents->SetCellSize(rowNumber, 0, data.harmonicOrder.size(), 1);
1137 m_gridHarmCurrents->SetCellValue(rowNumber, 0, data.name);
1138 m_gridHarmCurrents->SetCellSize(rowNumber, 1, data.harmonicOrder.size(), 1);
1139 m_gridHarmCurrents->SetCellValue(rowNumber, 1, "-");
1140 int i = 0;
1141 for (auto& order : data.harmonicOrder) {
1142 m_gridHarmCurrents->SetCellValue(rowNumber, 2, wxString::Format(wxT("%d%s"), order, wxString(L'\u00BA')));
1143 m_gridHarmCurrents->SetCellValue(rowNumber, 3, "?");
1144 m_gridHarmCurrents->SetCellValue(rowNumber, 4, hCurrent->StringFromDouble(data.injHarmAngle[i], 0, m_precision) + wxString(L'\u00B0'));
1145 i++;
1146 rowNumber++;
1147 }
1148
1149 }
1150 }
1151 m_gridHarmCurrents->AutoSize();
1152 m_gridHarmCurrents->GetContainingSizer()->Layout();
1153 }
1154
1155 // Harmonic Buses/Voltages
1156 if (gridToFill == GRID_ALL || gridToFill == GRID_HARMBUSES) {
1157 rowNumber = 1;
1158 for (auto* bus : busList) {
1159 auto data = bus->GetElectricalData();
1160 double vb = bus->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
1161
1162 m_gridHarmBuses->SetCellSize(rowNumber, 0, data.harmonicOrder.size(), 1);
1163 m_gridHarmBuses->SetCellValue(rowNumber, 0, data.name);
1164 m_gridHarmBuses->SetCellSize(rowNumber, 1, data.harmonicOrder.size(), 1);
1165 m_gridHarmBuses->SetCellValue(rowNumber, 1, bus->StringFromDouble(data.thd, 0, m_precision) + wxT("%"));
1166 int i = 0;
1167 for (auto& order : data.harmonicOrder) {
1168 m_gridHarmBuses->SetCellValue(rowNumber, 2, wxString::Format(wxT("%d%s"), order, wxString(L'\u00BA')));
1169 wxString voltageStr = "";
1170 if (m_gridHarmBuses->GetCellValue(0, 3) == m_phaseVoltageChoices[0]) {
1171 voltageStr.Printf(wxString::Format("%%.%de", m_precision), std::abs(data.harmonicVoltage[i]));
1172 }
1173 else if (m_gridHarmBuses->GetCellValue(0, 3) == m_phaseVoltageChoices[1]) {
1174 voltageStr = bus->StringFromDouble(std::abs(data.harmonicVoltage[i]) * vb / sqrt(3.0), 0, m_precision);
1175 }
1176 else if (m_gridHarmBuses->GetCellValue(0, 3) == m_phaseVoltageChoices[2]) {
1177 voltageStr = bus->StringFromDouble(std::abs(data.harmonicVoltage[i]) * vb / (sqrt(3.0) * 1e3), 0, m_precision);
1178 }
1179 m_gridHarmBuses->SetCellValue(rowNumber, 3, voltageStr);
1180 m_gridHarmBuses->SetCellValue(rowNumber, 4, bus->StringFromDouble(wxRadToDeg(std::arg(data.harmonicVoltage[i])), 0, m_precision) + wxString(L'\u00B0'));
1181
1182 i++;
1183 rowNumber++;
1184 }
1185 }
1186 m_gridHarmBuses->AutoSize();
1187 m_gridHarmBuses->GetContainingSizer()->Layout();
1188 }
1189
1190 // Harmonic current branches
1191 if (gridToFill == GRID_ALL || gridToFill == GRID_HARMBRANCHES) {
1192 rowNumber = 1;
1193 for (auto* line : lineList) {
1194 auto data = line->GetPUElectricalData(basePower);
1195
1196 double vb = line->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
1197 double ib = basePower / (std::sqrt(3.0) * vb);
1198
1199 wxString busName1 = "-";
1200 if (line->GetParentList()[0])
1201 busName1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData().name;
1202 wxString busName2 = "-";
1203 if (line->GetParentList()[1])
1204 busName2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData().name;
1205
1206 wxString isOnline = _("Yes");
1207 wxColour textColour = m_gridHarmBranches->GetDefaultCellTextColour();
1208 if (!line->IsOnline()) {
1209 isOnline = _("No");
1210 textColour = m_offlineColour;
1211 }
1212 for (int side = 0; side < 2; ++side) {
1213 for (unsigned int i = 0; i < data.harmonicOrder.size(); ++i) {
1214 for (int j = 0; j < 8; ++j) { m_gridHarmBranches->SetCellTextColour(rowNumber + i, j, textColour); }
1215 }
1216
1217 m_gridHarmBranches->SetCellSize(rowNumber, 0, data.harmonicOrder.size(), 1);
1218 m_gridHarmBranches->SetCellValue(rowNumber, 0, _("Line"));
1219 m_gridHarmBranches->SetCellSize(rowNumber, 1, data.harmonicOrder.size(), 1);
1220 m_gridHarmBranches->SetCellValue(rowNumber, 1, data.name);
1221 m_gridHarmBranches->SetCellSize(rowNumber, 2, data.harmonicOrder.size(), 1);
1222 m_gridHarmBranches->SetCellValue(rowNumber, 2, side == 0 ? busName1 : busName2);
1223 m_gridHarmBranches->SetCellSize(rowNumber, 3, data.harmonicOrder.size(), 1);
1224 m_gridHarmBranches->SetCellValue(rowNumber, 3, side == 0 ? busName2 : busName1);
1225 m_gridHarmBranches->SetCellSize(rowNumber, 7, data.harmonicOrder.size(), 1);
1226 m_gridHarmBranches->SetCellValue(rowNumber, 7, isOnline);
1227
1228 int i = 0;
1229 for (auto& order : data.harmonicOrder) {
1230 m_gridHarmBranches->SetCellValue(rowNumber, 4, wxString::Format(wxT("%d%s"), order, wxString(L'\u00BA')));
1231 wxString currentStr = "";
1232 wxString angleStr = "";
1233 if (line->IsOnline()) {
1234 if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[0]) {
1235 currentStr.Printf(wxString::Format("%%.%de", m_precision), std::abs(data.harmonicCurrent[side][i]));
1236 }
1237 else if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[1]) {
1238 currentStr = line->StringFromDouble(std::abs(data.harmonicCurrent[side][i]) * ib, 0, m_precision);
1239 }
1240 else if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[2]) {
1241 currentStr = line->StringFromDouble(std::abs(data.harmonicCurrent[side][i]) * ib / 1e3, 0, m_precision);
1242 }
1243 angleStr = line->StringFromDouble(wxRadToDeg(std::arg(data.harmonicCurrent[side][i])), 0, m_precision) + wxString(L'\u00B0');
1244 }
1245 else {
1246 currentStr = line->StringFromDouble(0.0, 0, m_precision);
1247 angleStr = line->StringFromDouble(0.0, 0, m_precision);
1248 }
1249
1250 m_gridHarmBranches->SetCellValue(rowNumber, 5, currentStr);
1251 m_gridHarmBranches->SetCellValue(rowNumber, 6, angleStr);
1252
1253 i++;
1254 rowNumber++;
1255 }
1256 }
1257 }
1258
1259 for (auto* transformer : transformerList) {
1260 auto data = transformer->GetPUElectricalData(basePower);
1261
1262 double vb = transformer->GetValueFromUnit(data.primaryNominalVoltage, data.primaryNominalVoltageUnit);
1263 double ibp = basePower / (std::sqrt(3.0) * vb);
1264 vb = transformer->GetValueFromUnit(data.secondaryNominalVoltage, data.secondaryNominalVoltageUnit);
1265 double ibs = basePower / (std::sqrt(3.0) * vb);
1266
1267 wxString busName1 = "-";
1268 if (transformer->GetParentList()[0])
1269 busName1 = static_cast<Bus*>(transformer->GetParentList()[0])->GetElectricalData().name;
1270 wxString busName2 = "-";
1271 if (transformer->GetParentList()[1])
1272 busName2 = static_cast<Bus*>(transformer->GetParentList()[1])->GetElectricalData().name;
1273
1274 wxString isOnline = _("Yes");
1275 wxColour textColour = m_gridHarmBranches->GetDefaultCellTextColour();
1276 if (!transformer->IsOnline()) {
1277 isOnline = _("No");
1278 textColour = m_offlineColour;
1279 }
1280 for (int side = 0; side < 2; ++side) {
1281 for (unsigned int i = 0; i < data.harmonicOrder.size(); ++i) {
1282 for (int j = 0; j < 8; ++j) { m_gridHarmBranches->SetCellTextColour(rowNumber + i, j, textColour); }
1283 }
1284 double ib = side == 0 ? ibp : ibs;
1285
1286 m_gridHarmBranches->SetCellSize(rowNumber, 0, data.harmonicOrder.size(), 1);
1287 m_gridHarmBranches->SetCellValue(rowNumber, 0, _("Transformer"));
1288 m_gridHarmBranches->SetCellSize(rowNumber, 1, data.harmonicOrder.size(), 1);
1289 m_gridHarmBranches->SetCellValue(rowNumber, 1, data.name);
1290 m_gridHarmBranches->SetCellSize(rowNumber, 2, data.harmonicOrder.size(), 1);
1291 m_gridHarmBranches->SetCellValue(rowNumber, 2, side == 0 ? busName1 : busName2);
1292 m_gridHarmBranches->SetCellSize(rowNumber, 3, data.harmonicOrder.size(), 1);
1293 m_gridHarmBranches->SetCellValue(rowNumber, 3, side == 0 ? busName2 : busName1);
1294 m_gridHarmBranches->SetCellSize(rowNumber, 7, data.harmonicOrder.size(), 1);
1295 m_gridHarmBranches->SetCellValue(rowNumber, 7, isOnline);
1296
1297 int i = 0;
1298 for (auto& order : data.harmonicOrder) {
1299 m_gridHarmBranches->SetCellValue(rowNumber, 4, wxString::Format(wxT("%d%s"), order, wxString(L'\u00BA')));
1300 wxString currentStr = "";
1301 wxString angleStr = "";
1302 if (transformer->IsOnline()) {
1303 if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[0]) {
1304 currentStr.Printf(wxString::Format("%%.%de", m_precision), std::abs(data.harmonicCurrent[side][i]));
1305 }
1306 else if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[1]) {
1307 currentStr = transformer->StringFromDouble(std::abs(data.harmonicCurrent[side][i]) * ib, 0, m_precision);
1308 }
1309 else if (m_gridHarmBranches->GetCellValue(0, 5) == m_currentChoices[2]) {
1310 currentStr = transformer->StringFromDouble(std::abs(data.harmonicCurrent[side][i]) * ib / 1e3, 0, m_precision);
1311 }
1312 angleStr = transformer->StringFromDouble(wxRadToDeg(std::arg(data.harmonicCurrent[side][i])), 0, m_precision) + wxString(L'\u00B0');
1313 }
1314 else {
1315 currentStr = transformer->StringFromDouble(0.0, 0, m_precision);
1316 angleStr = transformer->StringFromDouble(0.0, 0, m_precision);
1317 }
1318
1319 m_gridHarmBranches->SetCellValue(rowNumber, 5, currentStr);
1320 m_gridHarmBranches->SetCellValue(rowNumber, 6, angleStr);
1321
1322 i++;
1323 rowNumber++;
1324 }
1325 }
1326 }
1327
1328 m_gridHarmBranches->AutoSize();
1329 m_gridHarmBranches->GetContainingSizer()->Layout();
1330 }
1331
1332 m_changingValues = false;
1333}
1334
1335//void DataReport::SetRowsColours(wxGrid* grid, int rowStart, int colStart, int colEndTrim)
1336//{
1337// for (int i = rowStart; i < grid->GetNumberRows(); ++i) {
1338// wxGridCellAttr* attr = grid->GetOrCreateCellAttr(i, colStart);
1339// if ((i - rowStart) % 2 == 0)
1340// attr->SetBackgroundColour(m_evenRowColour);
1341// else
1342// attr->SetBackgroundColour(m_oddRowColour);
1343// //grid->SetRowAttr(i, attr);
1344// for (int j = colStart; j < (grid->GetNumberCols() - colEndTrim); ++j) {
1345// grid->SetAttr(i, j, attr);
1346// }
1347// }
1348//}
1349
1350void DataReport::SetRowsColours(wxGrid* grid, int rowStart, int colStart, int colEndTrim)
1351{
1352 for (int i = rowStart; i < grid->GetNumberRows(); ++i)
1353 {
1354 wxColour colour =
1355 ((i - rowStart) % 2 == 0) ?
1356 m_evenRowColour :
1357 m_oddRowColour;
1358
1359 for (int j = colStart; j < (grid->GetNumberCols() - colEndTrim); ++j)
1360 {
1361 wxGridCellAttr* attr = new wxGridCellAttr;
1362
1363 attr->SetBackgroundColour(colour);
1364
1365 grid->SetAttr(i, j, attr);
1366 }
1367 }
1368}
1369
1370void DataReport::OnPFBusGridChanged(wxGridEvent& event)
1371{
1372 if (!m_changingValues) FillValues(GRID_PFBUSES);
1373}
1374void DataReport::OnFaulrGridChanged(wxGridEvent& event)
1375{
1376 if (!m_changingValues) FillValues(GRID_FAULT);
1377}
1378void DataReport::OnFaultBranchesGridChanged(wxGridEvent& event)
1379{
1380 if (!m_changingValues) FillValues(GRID_FAULTBRANCHES);
1381}
1382void DataReport::OnFaultBusesGridChanged(wxGridEvent& event)
1383{
1384 if (!m_changingValues) FillValues(GRID_FAULTBUSES);
1385}
1386void DataReport::OnFaultGeneratorsGridChanged(wxGridEvent& event)
1387{
1388 if (!m_changingValues) FillValues(GRID_FAULTGENERATORS);
1389}
1390void DataReport::OnPFBranchesGridChanged(wxGridEvent& event)
1391{
1392 if (!m_changingValues) FillValues(GRID_PFBRANCHES);
1393}
1394void DataReport::OnPowerFlowGridChanged(wxGridEvent& event)
1395{
1396 if (!m_changingValues) FillValues(GRID_PF);
1397}
1398
1399void DataReport::GridKeyHandler(wxGrid* grid, wxKeyEvent& event)
1400{
1401 if (event.GetKeyCode() == 'C' && event.GetModifiers() == wxMOD_CONTROL) { // Copy selection
1402 // [Ref.] https://forums.wxwidgets.org/viewtopic.php?t=2200
1403 wxString copyData = "";
1404 bool lineNotEmpty;
1405
1406 for (int i = 0; i < grid->GetNumberRows(); i++) {
1407 lineNotEmpty = false;
1408 for (int j = 0; j < grid->GetNumberCols(); j++) {
1409 if (grid->IsInSelection(i, j)) {
1410 if (lineNotEmpty == false) {
1411 if (copyData.IsEmpty() == false) {
1412 copyData.Append(wxT("\r\n")); // In Windows if copy to notepad need \r\n to new line.
1413 }
1414 lineNotEmpty = true;
1415 }
1416 else {
1417 copyData.Append(wxT("\t"));
1418 }
1419 copyData = copyData + grid->GetCellValue(i, j);
1420 }
1421 }
1422 }
1423
1424 if (wxTheClipboard->Open())
1425 {
1426 wxTheClipboard->SetData(new wxTextDataObject(copyData));
1427 wxTheClipboard->Close();
1428 }
1429 }
1430 else if (event.GetKeyCode() == 'A' && event.GetModifiers() == wxMOD_CONTROL) { // Select all
1431 grid->SelectAll();
1432 }
1433 event.Skip();
1434}
1435void DataReport::UpdateFontSize()
1436{
1437 wxFont font = m_gridPowerFlow->GetFont();
1438 font.SetPointSize(m_fontSize);
1439
1440 wxFont headerFont = font;
1441 headerFont.SetWeight(wxFONTWEIGHT_BOLD);
1442
1443 wxGrid* grids[] = { m_gridPowerFlow, m_gridPFBuses, m_gridPFBranches, m_gridFault, m_gridFaultBuses, m_gridFaultBranches, m_gridFaultGenerators, m_gridHarmCurrents, m_gridHarmBuses, m_gridHarmBranches };
1444
1445 for (auto* grid : grids) {
1446 grid->SetLabelFont(headerFont);
1447 grid->SetDefaultCellFont(font);
1448 // Set font for all cells in header (first row)
1449 for (int col = 0; col < grid->GetNumberCols(); ++col) {
1450 grid->SetCellFont(0, col, headerFont);
1451 if (grid == m_gridFault ||
1452 grid == m_gridFaultBuses ||
1453 grid == m_gridFaultBranches ||
1454 grid == m_gridFaultGenerators)
1455 {
1456 grid->SetCellFont(1, col, headerFont);
1457 }
1458 }
1459 grid->SetFont(font);
1460 grid->AutoSize();
1461 grid->GetContainingSizer()->Layout();
1462 grid->ForceRefresh();
1463 }
1464}
1465
1466void DataReport::UpdateCurrentGrid()
1467{
1468 int mainSlection = m_notebookDataReport->GetSelection();
1469 if (mainSlection != wxNOT_FOUND) {
1470 switch (mainSlection) {
1471 case 0: // Power Flow
1472 {
1473 int selection = m_notebookPowerFlow->GetSelection();
1474 if (selection == 0) {
1475 m_currentGrid = m_gridPowerFlow;
1476 }
1477 else if (selection == 1) {
1478 m_currentGrid = m_gridPFBuses;
1479 }
1480 else if (selection == 2) {
1481 m_currentGrid = m_gridPFBranches;
1482 }
1483 break;
1484 }
1485 case 1: // Fault
1486 {
1487 int selection = m_notebookFault->GetSelection();
1488 if (selection == 0) {
1489 m_currentGrid = m_gridFault;
1490 }
1491 else if (selection == 1) {
1492 m_currentGrid = m_gridFaultBuses;
1493 }
1494 else if (selection == 2) {
1495 m_currentGrid = m_gridFaultBranches;
1496 }
1497 else if (selection == 3) {
1498 m_currentGrid = m_gridFaultGenerators;
1499 }
1500 break;
1501 }
1502 case 2: // Harmonics
1503 {
1504 int selection = m_notebookHarmCurrents->GetSelection();
1505 if (selection == 0) {
1506 m_currentGrid = m_gridHarmCurrents;
1507 }
1508 else if (selection == 1) {
1509 m_currentGrid = m_gridHarmBuses;
1510 }
1511 else if (selection == 2) {
1512 m_currentGrid = m_gridHarmBranches;
1513 }
1514 break;
1515 }
1516 }
1517 }
1518}
1519
1520void DataReport::OnHarmCurrentGridChanged(wxGridEvent& event)
1521{
1522 if (!m_changingValues) FillValues(GRID_HARMCURRENT);
1523}
1524void DataReport::OnHarmBusesGridChanged(wxGridEvent& event)
1525{
1526 if (!m_changingValues) FillValues(GRID_HARMBUSES);
1527}
1528void DataReport::OnHarmBranchesGridChanged(wxGridEvent& event)
1529{
1530 if (!m_changingValues) FillValues(GRID_HARMBRANCHES);
1531}
1532void DataReport::ClipboardButtonClick(wxCommandEvent& event)
1533{
1534 wxString plainText;
1535 wxString html;
1536 wxGrid* grid = m_currentGrid;
1537
1538 if (grid == nullptr) {
1539 wxMessageDialog msgDialog(this, _("Unable to copy to clipboard."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1540 msgDialog.ShowModal();
1541 return;
1542 }
1543
1544 int headerRows = 1;
1545
1546 if (grid == m_gridFault ||
1547 grid == m_gridFaultBuses ||
1548 grid == m_gridFaultBranches ||
1549 grid == m_gridFaultGenerators)
1550 {
1551 headerRows = 2;
1552 }
1553
1554 html << "<table style='border-collapse:collapse; "
1555 "font-family:Segoe UI, Arial, sans-serif; "
1556 "font-size:10pt;'>";
1557
1558 int rows = grid->GetNumberRows();
1559 int cols = grid->GetNumberCols();
1560
1561 for (int row = 0; row < rows; row++)
1562 {
1563 html << "<tr>";
1564
1565 for (int col = 0; col < cols; )
1566 {
1567 int rowspan = 1;
1568 int colspan = 1;
1569
1570 grid->GetCellSize(row, col, &rowspan, &colspan);
1571
1572 // Skip covered cells
1573 if (rowspan == 0 || colspan == 0)
1574 {
1575 col++;
1576 continue;
1577 }
1578
1579 wxString value = grid->GetCellValue(row, col);
1580
1581 // Plain text
1582 if (col > 0)
1583 plainText << "\t";
1584 plainText << value;
1585
1586 // Repeat value in plain text if merged horizontally
1587 for (int c = 1; c < colspan; c++)
1588 plainText << "\t" << value;
1589
1590 // Escape HTML
1591 wxString escaped = value;
1592 escaped.Replace("&", "&amp;");
1593 escaped.Replace("<", "&lt;");
1594 escaped.Replace(">", "&gt;");
1595
1596 bool isHeader = (row < headerRows);
1597
1598 if (isHeader)
1599 {
1600 html << "<th style='"
1601 "border:1px solid #c9d1e6;"
1602 "background-color:#BFDFFF;"
1603 "color:black;"
1604 "padding:5px 8px;"
1605 "text-align:center;'";
1606
1607 if (rowspan > 1)
1608 html << " rowspan='" << rowspan << "'";
1609 if (colspan > 1)
1610 html << " colspan='" << colspan << "'";
1611
1612 html << ">" << escaped << "</th>";
1613 }
1614 else
1615 {
1616 html << "<td style='"
1617 "border:1px solid #c9d1e6;"
1618 "padding:4px 8px;"
1619 "text-align:center;'";
1620
1621 if (rowspan > 1)
1622 html << " rowspan='" << rowspan << "'";
1623 if (colspan > 1)
1624 html << " colspan='" << colspan << "'";
1625
1626 html << ">" << escaped << "</td>";
1627 }
1628
1629 col += colspan;
1630 }
1631
1632 plainText << "\r\n";
1633 html << "</tr>";
1634 }
1635
1636 html << "</table>";
1637
1638
1639 if (wxTheClipboard->Open())
1640 {
1641 wxDataObjectComposite* data = new wxDataObjectComposite();
1642
1643 data->Add(new wxHTMLDataObject(html));
1644 data->Add(new wxTextDataObject(plainText));
1645
1646 wxTheClipboard->SetData(data);
1647 wxTheClipboard->Close();
1648 }
1649 else {
1650 wxMessageDialog msgDialog(this, _("Unable to copy to clipboard."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
1651 msgDialog.ShowModal();
1652 }
1653}
1654void DataReport::ExportCSVButtonClick(wxCommandEvent& event)
1655{
1656 std::vector<wxGrid*> grids = { m_gridPowerFlow, m_gridPFBuses, m_gridPFBranches,
1657 m_gridFault, m_gridFaultBuses, m_gridFaultBranches, m_gridFaultGenerators,
1658 m_gridHarmCurrents, m_gridHarmBuses, m_gridHarmBranches };
1659 ExportCSVForm expCSV(this, grids);
1660 expCSV.ShowModal();
1661}
1662
1663void DataReport::OnPFNotebookChanged(wxNotebookEvent& event)
1664{
1665 UpdateCurrentGrid();
1666}
1667
1668void DataReport::OnFaultNotebookChanged(wxNotebookEvent& event)
1669{
1670 UpdateCurrentGrid();
1671}
1672
1673void DataReport::OnHarmNotebookChanged(wxNotebookEvent& event)
1674{
1675 UpdateCurrentGrid();
1676}
1677
1678void DataReport::OnMainNotebookChanged(wxNotebookEvent& event)
1679{
1680 UpdateCurrentGrid();
1681}
1682
1683void DataReport::OnFontSizeSelected(wxCommandEvent& event)
1684{
1685 m_fontSize = wxAtoi(m_choiceFontSize->GetStringSelection());
1686 UpdateFontSize();
1687}
1688
1689void DataReport::OnTextPrecisionUpdate(wxCommandEvent& event)
1690{
1691 long precision = m_precision;
1692 if (m_textCtrlPrecision->GetValue().ToLong(&precision)) {
1693 if (precision >= 0) {
1694 m_precision = precision;
1695 FillValues(GRID_ALL);
1696 }
1697 }
1698
1699}
1700void DataReport::OnMouseWheel(wxMouseEvent& event)
1701{
1702 if (event.ControlDown()) {
1703 if (event.GetWheelRotation() > 0) {
1704 size_t newSelection = m_choiceFontSize->GetSelection() + 1;
1705 if (newSelection < m_choiceFontSize->GetCount()) {
1706 m_choiceFontSize->SetSelection(newSelection);
1707 m_fontSize = wxAtoi(m_choiceFontSize->GetStringSelection());
1708 UpdateFontSize();
1709 }
1710 }
1711 else {
1712 size_t newSelection = m_choiceFontSize->GetSelection() - 1;
1713 if (newSelection >= 0) {
1714 m_choiceFontSize->SetSelection(newSelection);
1715 m_fontSize = wxAtoi(m_choiceFontSize->GetStringSelection());
1716 UpdateFontSize();
1717 }
1718 }
1719 }
1720
1721 event.Skip();
1722}
@ BUS_SLACK
Node for power elements. All others power elements are connected through this.
Definition Bus.h:86
Form that shows the results of power flow and fault calculations.
Definition DataReport.h:34
Base class for electrical calculations providing general utility methods.
const std::vector< SyncGenerator * > GetSyncGeneratorList() const
Get the synchronous generators of the system (use GetElementsFromList first).
const std::vector< Transformer * > GetTransformerList() const
Get the transformers of the system (use GetElementsFromList first).
const std::vector< Line * > GetLineList() const
Get the lines of the system (use GetElementsFromList first).
const std::vector< Bus * > GetBusList() const
Get the buses of the system (use GetElementsFromList first).
virtual void GetElementsFromList(std::vector< Element * > elementList)
Separate the power elements from a generic list.
const std::vector< HarmCurrent * > GetHarmCurrentList() const
Get the harmonic current source of the system (use GetElementsFromList first).
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:559
bool IsOnline() const
Checks if the element is online or offline.
Definition Element.h:226
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
Definition Element.cpp:533
Power line element.
Definition Line.h:64
Synchronous generator power element.
Two-winding transformer power element.
Definition Transformer.h:84
This class manages the graphical and power elements. It is responsible for handling the user's intera...
Definition Workspace.h:103