Power System Platform  2026w11a-beta
Loading...
Searching...
No Matches
SimulationsSettingsForm.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
19#include "../utils/PropertiesData.h"
20#include "../utils/Path.h"
21
22SimulationsSettingsForm::SimulationsSettingsForm(wxWindow* parent, PropertiesData* properties, wxLocale* locale)
23 : SimulationsSettingsFormBase(parent)
24{
25 m_properties = properties;
26 auto data = m_properties->GetSimulationPropertiesData();
27
28 m_textCtrlbasePower->SetValue(Element::StringFromDouble(data.basePower));
29 switch (data.basePowerUnit) {
31 m_choiceBasePower->SetSelection(0);
32 } break;
34 m_choiceBasePower->SetSelection(1);
35 } break;
37 m_choiceBasePower->SetSelection(2);
38 } break;
39 default: {
40 m_choiceBasePower->SetSelection(wxNOT_FOUND);
41 } break;
42 }
43 m_checkBoxFaultAfterPF->SetValue(data.faultAfterPowerFlow);
44 m_checkBoxSCPowerAfterPF->SetValue(data.scPowerAfterPowerFlow);
45 m_checkBoxTHDAfterPF->SetValue(data.harmDistortionAfterPowerFlow);
46 switch (data.powerFlowMethod) {
47 case NEWTON_RAPHSON : {
48 m_choicePFMethod->SetSelection(0);
49 } break;
50 case GAUSS_SEIDEL: {
51 m_choicePFMethod->SetSelection(1);
52 } break;
53 case GAUSS_NEWTON: {
54 m_choicePFMethod->SetSelection(2);
55 } break;
56 default: {
57 m_choicePFMethod->SetSelection(wxNOT_FOUND);
58 } break;
59 }
60 m_textCtrlAccFactor->SetValue(Element::StringFromDouble(data.accFator));
61 m_textCtrlPFTolerance->SetValue(wxString::Format("%g", data.powerFlowTolerance));
62 m_textCtrlPFMaxIterations->SetValue(wxString::Format("%d", data.powerFlowMaxIterations));
63 m_textCtrlPFSlackBusAngle->SetValue(Element::StringFromDouble(data.initAngle));
64 m_textCtrlPFNewtonInertia->SetValue(Element::StringFromDouble(data.newtonInertia));
65 m_textCtrlPFGaussTolerance->SetValue(wxString::Format("%g", data.gaussTolerance));
66 m_textCtrlTimeStep->SetValue(wxString::Format("%g", data.timeStep));
67 m_textCtrlSimTime->SetValue(Element::StringFromDouble(data.stabilitySimulationTime));
68 m_textCtrlFreq->SetValue(Element::StringFromDouble(data.stabilityFrequency));
69 m_textCtrlStabTolerance->SetValue(wxString::Format("%g", data.stabilityTolerance));
70 m_textCtrlStabMaxIterations->SetValue(wxString::Format("%d", data.stabilityMaxIterations));
71 m_textCtrlCtrlStepRatio->SetValue(wxString::Format("%d", data.controlTimeStepRatio));
72 m_textCtrlPrintTime->SetValue(wxString::Format("%g", data.plotTime));
73
74 m_checkBoxUseCOI->SetValue(data.useCOI);
75
76 m_checkBoxUseCompLoads->SetValue(data.useCompLoads);
77
78 m_textCtrlActivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceActive));
79 m_textCtrlActivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentActive));
80 m_textCtrlActivePowerPow->SetValue(Element::StringFromDouble(data.constPowerActive));
81 m_textCtrlReactivePowerImp->SetValue(Element::StringFromDouble(data.constImpedanceReactive));
82 m_textCtrlReactivePowerCur->SetValue(Element::StringFromDouble(data.constCurrentReactive));
83 m_textCtrlReactivePowerPow->SetValue(Element::StringFromDouble(data.constPowerReactive));
84
85 m_textCtrlUVCur->SetValue(Element::StringFromDouble(data.underVoltageConstCurrent));
86 m_textCtrlUVPow->SetValue(Element::StringFromDouble(data.underVoltageConstPower));
87
88 m_radioBoxBusFreqEstimation->SetSelection(static_cast<int>(data.busFreqEstimation));
89 m_checkBoxBusFreqIgnoreEvent->SetValue(data.ignoreBusFreqEventStep);
90 m_textCtrlTf->SetValue(Element::StringFromDouble(data.tf));
91 m_textCtrlTw->SetValue(Element::StringFromDouble(data.tw));
92
93 m_choiceHarmLoadConn->SetSelection(static_cast<int>(data.harmLoadConnection));
94
95 if (locale->GetCanonicalName() == wxT("pt_BR")) {
96 wxBitmap wfDiagram;
97 wfDiagram.LoadFile(Paths::GetDataPath() + "/images/WF-pt.png", wxBITMAP_TYPE_PNG);
98 m_staticBitmapDiagram->SetBitmap(wfDiagram);
99 }
100
101 UpdateZIPLoadFieldStatus();
102 UpdatePFFieldStatus();
103 UpdateBusFreqFieldStatus();
104}
105
106SimulationsSettingsForm::~SimulationsSettingsForm() {}
107void SimulationsSettingsForm::OnButtonOKClick(wxCommandEvent& event)
108{
109 if (ValidateData()) EndModal(wxID_OK);
110}
111
112bool SimulationsSettingsForm::ValidateData()
113{
114 auto data = m_properties->GetSimulationPropertiesData();
115 if (!Element::DoubleFromString(this, m_textCtrlbasePower->GetValue(), data.basePower,
116 _("Value entered incorrectly in the field \"Base power\".")))
117 return false;
118 switch (m_choiceBasePower->GetSelection()) {
119 case 0: {
120 data.basePowerUnit = ElectricalUnit::UNIT_VA;
121 } break;
122 case 1: {
123 data.basePowerUnit = ElectricalUnit::UNIT_kVA;
124 } break;
125 default: {
126 data.basePowerUnit = ElectricalUnit::UNIT_MVA;
127 } break;
128 }
129 data.faultAfterPowerFlow = m_checkBoxFaultAfterPF->GetValue();
130 data.scPowerAfterPowerFlow = m_checkBoxSCPowerAfterPF->GetValue();
131 data.harmDistortionAfterPowerFlow = m_checkBoxTHDAfterPF->GetValue();
132 switch (m_choicePFMethod->GetSelection()) {
133 case 0: {
134 data.powerFlowMethod = NEWTON_RAPHSON;
135 } break;
136 case 1: {
137 data.powerFlowMethod = GAUSS_SEIDEL;
138 } break;
139 case 2: {
140 data.powerFlowMethod = GAUSS_NEWTON;
141 } break;
142 }
143 if (!Element::DoubleFromString(this, m_textCtrlAccFactor->GetValue(), data.accFator,
144 _("Value entered incorrectly in the field \"Acceleration factor\".")))
145 return false;
146 if (!Element::DoubleFromString(this, m_textCtrlPFTolerance->GetValue(), data.powerFlowTolerance,
147 _("Value entered incorrectly in the field \"Tolerance (Power flow)\".")))
148 return false;
149 if (!Element::IntFromString(this, m_textCtrlPFMaxIterations->GetValue(), data.powerFlowMaxIterations,
150 _("Value entered incorrectly in the field \"Max. iterations (Power flow)\".")))
151 return false;
152 if (!Element::DoubleFromString(this, m_textCtrlPFSlackBusAngle->GetValue(), data.initAngle,
153 _("Value entered incorrectly in the field \"Slack bus angle\".")))
154 return false;
155 if (!Element::DoubleFromString(this, m_textCtrlPFNewtonInertia->GetValue(), data.newtonInertia,
156 _("Value entered incorrectly in the field \"Newton inertia (Power flow)\".")))
157 return false;
158 if (!Element::DoubleFromString(this, m_textCtrlPFGaussTolerance->GetValue(), data.gaussTolerance,
159 _("Value entered incorrectly in the field \"Gauss tolerance (Power flow)\".")))
160 return false;
161 if (!Element::DoubleFromString(this, m_textCtrlTimeStep->GetValue(), data.timeStep,
162 _("Value entered incorrectly in the field \"Time step\".")))
163 return false;
164 if (!Element::DoubleFromString(this, m_textCtrlSimTime->GetValue(), data.stabilitySimulationTime,
165 _("Value entered incorrectly in the field \"Simulation time\".")))
166 return false;
167 if (!Element::DoubleFromString(this, m_textCtrlFreq->GetValue(), data.stabilityFrequency,
168 _("Value entered incorrectly in the field \"System frequency\".")))
169 return false;
170 if (!Element::DoubleFromString(this, m_textCtrlStabTolerance->GetValue(), data.stabilityTolerance,
171 _("Value entered incorrectly in the field \"Tolerance (stability)\".")))
172 return false;
173 if (!Element::IntFromString(this, m_textCtrlStabMaxIterations->GetValue(), data.stabilityMaxIterations,
174 _("Value entered incorrectly in the field \"Max. iterations (stability)\".")))
175 return false;
176 if (!Element::IntFromString(this, m_textCtrlCtrlStepRatio->GetValue(), data.controlTimeStepRatio,
177 _("Value entered incorrectly in the field \"Controls step ratio\".")))
178 return false;
179 if (!Element::DoubleFromString(this, m_textCtrlPrintTime->GetValue(), data.plotTime,
180 _("Value entered incorrectly in the field \"Plot time\".")))
181 return false;
182 data.useCOI = m_checkBoxUseCOI->GetValue();
183
184 data.useCompLoads = m_checkBoxUseCompLoads->GetValue();
185
187 this, m_textCtrlActivePowerImp->GetValue(), data.constImpedanceActive,
188 _("Value entered incorrectly in the field \"Constant impedance portion of active power (ZIP load)\".")))
189 return false;
191 this, m_textCtrlActivePowerCur->GetValue(), data.constCurrentActive,
192 _("Value entered incorrectly in the field \"Constant current portion of active power (ZIP load)\".")))
193 return false;
195 this, m_textCtrlActivePowerPow->GetValue(), data.constPowerActive,
196 _("Value entered incorrectly in the field \"Constant power portion of active power (ZIP load)\".")))
197 return false;
199 this, m_textCtrlReactivePowerImp->GetValue(), data.constImpedanceReactive,
200 _("Value entered incorrectly in the field \"Constant impedance portion of reactive power (ZIP load)\".")))
201 return false;
203 this, m_textCtrlReactivePowerCur->GetValue(), data.constCurrentReactive,
204 _("Value entered incorrectly in the field \"Constant current portion of reactive power (ZIP load)\".")))
205 return false;
207 this, m_textCtrlReactivePowerPow->GetValue(), data.constPowerReactive,
208 _("Value entered incorrectly in the field \"Constant power portion of reactive power (ZIP load)\".")))
209 return false;
210
212 this, m_textCtrlUVCur->GetValue(), data.underVoltageConstCurrent,
213 _("Value entered incorrectly in the field \"Constant current undervoltage limit (ZIP load)\".")))
214 return false;
215
217 this, m_textCtrlUVPow->GetValue(), data.underVoltageConstPower,
218 _("Value entered incorrectly in the field \"Constant power undervoltage limit (ZIP load)\".")))
219 return false;
220
221 double sum = data.constImpedanceActive + data.constCurrentActive + data.constPowerActive;
222 if (sum > 100.01 || sum < 99.99) {
223 wxMessageDialog msgDialog(this, _("The sum of active power load composition must be 100%."), _("Error"),
224 wxOK | wxCENTRE | wxICON_ERROR);
225 msgDialog.ShowModal();
226 return false;
227 }
228 sum = data.constImpedanceReactive + data.constCurrentReactive + data.constPowerReactive;
229 if (sum > 100.01 || sum < 99.99) {
230 wxMessageDialog msgDialog(this, _("The sum of reactive power load composition must be 100%."), _("Error"),
231 wxOK | wxCENTRE | wxICON_ERROR);
232 msgDialog.ShowModal();
233 return false;
234 }
235
236 data.busFreqEstimation = static_cast<BusFreqEstimation>(m_radioBoxBusFreqEstimation->GetSelection());
237
238 if (m_checkBoxBusFreqIgnoreEvent->IsShown()) {
239 data.ignoreBusFreqEventStep = m_checkBoxBusFreqIgnoreEvent->GetValue();
240 }
241
242 if (m_textCtrlTf->IsShown()) {
244 this, m_textCtrlTf->GetValue(), data.tf,
245 _("Value entered incorrectly in the field \"Time constant Tf (Bus Frequency)\".")))
246 return false;
247 }
248 if (m_textCtrlTw->IsShown()) {
250 this, m_textCtrlTw->GetValue(), data.tw,
251 _("Value entered incorrectly in the field \"Time constant Tw (Bus Frequency)\".")))
252 return false;
253 }
254
255 data.harmLoadConnection = static_cast<HarmLoadConnection>(m_choiceHarmLoadConn->GetSelection());
256
257 m_properties->SetSimulationPropertiesData(data);
258 return true;
259}
260
261void SimulationsSettingsForm::OnPFMethodChoiceSelected(wxCommandEvent& event) { UpdatePFFieldStatus(); }
262
263void SimulationsSettingsForm::UpdateZIPLoadFieldStatus()
264{
265 m_textCtrlActivePowerImp->Enable(m_checkBoxUseCompLoads->GetValue());
266 m_textCtrlActivePowerCur->Enable(m_checkBoxUseCompLoads->GetValue());
267 m_textCtrlActivePowerPow->Enable(m_checkBoxUseCompLoads->GetValue());
268 m_textCtrlReactivePowerImp->Enable(m_checkBoxUseCompLoads->GetValue());
269 m_textCtrlReactivePowerCur->Enable(m_checkBoxUseCompLoads->GetValue());
270 m_textCtrlReactivePowerPow->Enable(m_checkBoxUseCompLoads->GetValue());
271}
272
273void SimulationsSettingsForm::UpdatePFFieldStatus()
274{
275 if (m_choicePFMethod->GetSelection() == 1 || m_choicePFMethod->GetSelection() == 2)
276 m_textCtrlAccFactor->Enable();
277 else
278 m_textCtrlAccFactor->Enable(false);
279 if (m_choicePFMethod->GetSelection() == 2)
280 m_textCtrlPFGaussTolerance->Enable();
281 else
282 m_textCtrlPFGaussTolerance->Enable(false);
283 if (m_choicePFMethod->GetSelection() == 0 || m_choicePFMethod->GetSelection() == 2)
284 m_textCtrlPFNewtonInertia->Enable();
285 else
286 m_textCtrlPFNewtonInertia->Enable(false);
287}
288void SimulationsSettingsForm::UpdateBusFreqFieldStatus()
289{
290 bool visible = true;
291 if (m_radioBoxBusFreqEstimation->GetSelection() == 0) visible = false;
292 m_checkBoxBusFreqIgnoreEvent->Show(!visible);
293 m_staticTextTf->Show(visible);
294 m_textCtrlTf->Show(visible);
295 m_staticTextTw->Show(visible);
296 m_textCtrlTw->Show(visible);
297 m_staticBitmapDiagram->Show(visible);
298}
299
300void SimulationsSettingsForm::OnBusFreqEstimationSelect(wxCommandEvent& event)
301{
302 UpdateBusFreqFieldStatus();
303}
static bool IntFromString(wxWindow *parent, wxString strValue, int &value, wxString errorMsg)
Convert a string to int. Show a error message if the conversion fail.
Definition Element.cpp:447
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.
Definition Element.cpp:433
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
Definition Element.cpp:461
General and simulation data manager.