25{
26
27 std::ofstream writeProjectsFile(path.GetFullPath().mb_str());
28 writeProjectsFile.close();
29
30 rapidxml::xml_document<> doc;
31 rapidxml::file<> xmlFile(path.GetFullPath());
32 doc.parse<0>(xmlFile.data());
33
34 rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
35 rapidxml::xml_attribute<>* ver = doc.allocate_attribute("version", "1.0");
36 rapidxml::xml_attribute<>* encoding = doc.allocate_attribute("encoding", "utf-8");
37 decl->append_attribute(ver);
38 decl->append_attribute(encoding);
39 doc.append_node(decl);
40
41 rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element, "Project");
42 doc.append_node(rootNode);
43
44 rapidxml::xml_node<>* projectNameNode = XMLParser::AppendNode(doc, rootNode, "Name");
45 XMLParser::SetNodeValue(doc, projectNameNode, path.GetName());
46
47
49 auto propertiesNode = XMLParser::AppendNode(doc, rootNode, "Properties");
50
51 SimulationData simulationData = properties->GetSimulationPropertiesData();
52 auto simulationPropNode = XMLParser::XMLParser::AppendNode(doc, propertiesNode, "SimulationProperties");
53
54 auto generalPropNode = XMLParser::AppendNode(doc, simulationPropNode, "General");
55 auto basePower = XMLParser::AppendNode(doc, generalPropNode, "BasePower");
56 XMLParser::SetNodeValue(doc, basePower, simulationData.basePower);
57 XMLParser::SetNodeAttribute(doc, basePower, "UnitID", static_cast<int>(simulationData.basePowerUnit));
58 auto contCalc = XMLParser::AppendNode(doc, generalPropNode, "ContinuousCalculation");
59 auto contCalcFault = XMLParser::AppendNode(doc, contCalc, "Fault");
60 XMLParser::SetNodeValue(doc, contCalcFault, simulationData.faultAfterPowerFlow);
61 auto contCalcSCPower = XMLParser::AppendNode(doc, contCalc, "SCPower");
62 XMLParser::SetNodeValue(doc, contCalcSCPower, simulationData.scPowerAfterPowerFlow);
63 auto contCalcTHD = XMLParser::AppendNode(doc, contCalc, "HarmonicDistortion");
64 XMLParser::SetNodeValue(doc, contCalcTHD, simulationData.harmDistortionAfterPowerFlow);
65
66 auto powerFlowPropNode = XMLParser::AppendNode(doc, simulationPropNode, "PowerFlow");
67 auto solutionMethod = XMLParser::AppendNode(doc, powerFlowPropNode, "SolutionMethod");
68 XMLParser::SetNodeValue(doc, solutionMethod, simulationData.powerFlowMethod);
69 auto accFactor = XMLParser::AppendNode(doc, powerFlowPropNode, "AccFactor");
70 XMLParser::SetNodeValue(doc, accFactor, simulationData.accFator);
71 auto pfTolerance = XMLParser::AppendNode(doc, powerFlowPropNode, "Tolerance");
72 XMLParser::SetNodeValue(doc, pfTolerance, simulationData.powerFlowTolerance);
73 auto pfMaxIter = XMLParser::AppendNode(doc, powerFlowPropNode, "MaxIterations");
74 XMLParser::SetNodeValue(doc, pfMaxIter, simulationData.powerFlowMaxIterations);
75 auto pfSlackAngle = XMLParser::AppendNode(doc, powerFlowPropNode, "SlackAngle");
76 XMLParser::SetNodeValue(doc, pfSlackAngle, simulationData.initAngle);
77
78 auto stabilityPropNode = XMLParser::AppendNode(doc, simulationPropNode, "Stability");
79 auto timeStep = XMLParser::AppendNode(doc, stabilityPropNode, "TimeStep");
80 XMLParser::SetNodeValue(doc, timeStep, simulationData.timeStep);
81 auto simTime = XMLParser::AppendNode(doc, stabilityPropNode, "SimulationTime");
82 XMLParser::SetNodeValue(doc, simTime, simulationData.stabilitySimulationTime);
83 auto freq = XMLParser::AppendNode(doc, stabilityPropNode, "Frequency");
84 XMLParser::SetNodeValue(doc, freq, simulationData.stabilityFrequency);
85 auto stabTolerance = XMLParser::AppendNode(doc, stabilityPropNode, "Tolerance");
86 XMLParser::SetNodeValue(doc, stabTolerance, simulationData.stabilityTolerance);
87 auto stabTMaxIter = XMLParser::AppendNode(doc, stabilityPropNode, "MaxIterations");
88 XMLParser::SetNodeValue(doc, stabTMaxIter, simulationData.stabilityMaxIterations);
89 auto controlRatio = XMLParser::AppendNode(doc, stabilityPropNode, "ControlStepRatio");
90 XMLParser::SetNodeValue(doc, controlRatio, simulationData.controlTimeStepRatio);
91 auto plotStep = XMLParser::AppendNode(doc, stabilityPropNode, "PlotStep");
92 XMLParser::SetNodeValue(doc, plotStep, simulationData.plotTime);
93 auto useCOI = XMLParser::AppendNode(doc, stabilityPropNode, "UseCOI");
94 XMLParser::SetNodeValue(doc, useCOI, simulationData.useCOI);
95
96 auto zipPropNode = XMLParser::AppendNode(doc, simulationPropNode, "ZIPLoad");
97 auto useCompLoads = XMLParser::AppendNode(doc, zipPropNode, "UseCompositeLoad");
98 XMLParser::SetNodeValue(doc, useCompLoads, simulationData.useCompLoads);
99 auto activePowerComp = XMLParser::AppendNode(doc, zipPropNode, "ActivePowerComposition");
100 auto pz = XMLParser::AppendNode(doc, activePowerComp, "ConstantImpedance");
101 XMLParser::SetNodeValue(doc, pz, simulationData.constImpedanceActive);
102 auto pi = XMLParser::AppendNode(doc, activePowerComp, "ConstantCurrent");
103 XMLParser::SetNodeValue(doc, pi, simulationData.constCurrentActive);
104 auto pp = XMLParser::AppendNode(doc, activePowerComp, "ConstantPower");
105 XMLParser::SetNodeValue(doc, pp, simulationData.constPowerActive);
106 auto reactivePowerComp = XMLParser::AppendNode(doc, zipPropNode, "ReactivePowerComposition");
107 auto qz = XMLParser::AppendNode(doc, reactivePowerComp, "ConstantImpedance");
108 XMLParser::SetNodeValue(doc, qz, simulationData.constImpedanceReactive);
109 auto qi = XMLParser::AppendNode(doc, reactivePowerComp, "ConstantCurrent");
110 XMLParser::SetNodeValue(doc, qi, simulationData.constCurrentReactive);
111 auto qp = XMLParser::AppendNode(doc, reactivePowerComp, "ConstantPower");
112 XMLParser::SetNodeValue(doc, qp, simulationData.constPowerReactive);
113 auto undervoltageLim = XMLParser::AppendNode(doc, zipPropNode, "UndervoltageLimit");
114 auto uvi = XMLParser::AppendNode(doc, undervoltageLim, "ConstantCurrent");
115 XMLParser::SetNodeValue(doc, uvi, simulationData.underVoltageConstCurrent);
116 auto uvp = XMLParser::AppendNode(doc, undervoltageLim, "ConstantPower");
117 XMLParser::SetNodeValue(doc, uvp, simulationData.underVoltageConstPower);
118
119
120
121 auto elementsNode = XMLParser::AppendNode(doc, rootNode, "Elements");
122
123
126 int elementID = 0;
127
128
129 auto busesNode = XMLParser::AppendNode(doc, elementsNode, "BusList");
131 for (auto* bus : busList) {
132 if (bus->IsInserted()) {
133 bus->SetID(elementID);
134 bus->SaveElement(doc, busesNode);
135 elementID++;
136 }
137 }
138
139
140
141 auto capacitorsNode = XMLParser::AppendNode(doc, elementsNode, "CapacitorList");
143 elementID = 0;
144 for (auto* capacitor : capacitorList) {
145 if (capacitor->IsInserted()) {
146 capacitor->SetID(elementID);
147 capacitor->SaveElement(doc, capacitorsNode);
148 elementID++;
149 }
150 }
151
152
153
154 auto indMotorsNode = XMLParser::AppendNode(doc, elementsNode, "IndMotorList");
156 elementID = 0;
157 for (auto* indMotor : indMotorList) {
158 if (indMotor->IsInserted()) {
159 indMotor->SetID(elementID);
160 indMotor->SaveElement(doc, indMotorsNode);
161 elementID++;
162 }
163 }
164
165
166
167 auto inductorsNode = XMLParser::AppendNode(doc, elementsNode, "InductorList");
169 elementID = 0;
170 for (auto* inductor : inductorList) {
171 if (inductor->IsInserted()) {
172 inductor->SetID(elementID);
173 inductor->SaveElement(doc, inductorsNode);
174 elementID++;
175 }
176 }
177
178
179
180 auto linesNode = XMLParser::AppendNode(doc, elementsNode, "LineList");
182 elementID = 0;
183 for (auto* line : lineList) {
184 if (line->IsInserted()) {
185 line->SetID(elementID);
186 line->SaveElement(doc, linesNode);
187 elementID++;
188 }
189 }
190
191
192
193 auto loadsNode = XMLParser::AppendNode(doc, elementsNode, "LoadList");
195 elementID = 0;
196 for (auto* load : loadList) {
197 if (load->IsInserted()) {
198 load->SetID(elementID);
199 load->SaveElement(doc, loadsNode);
200 elementID++;
201 }
202 }
203
204
205
206 auto syncGeneratorsNode = XMLParser::AppendNode(doc, elementsNode, "SyncGeneratorList");
208 elementID = 0;
209 for (auto syncGen : syncGeneratorList) {
210 if (syncGen->IsInserted()) {
211 syncGen->SetID(elementID);
212 auto elementNode = syncGen->SaveElement(doc, syncGeneratorsNode);
213
214
215 auto data = syncGen->GetElectricalData();
216 auto electricalProp = elementNode->first_node("ElectricalProperties");
217 auto stability = electricalProp->first_node("Stability");
218
219 auto avr = XMLParser::AppendNode(doc, stability, "AVR");
220 if (data.avr) SaveControlElements(doc, avr, data.avr);
221
222 auto speedGov = XMLParser::AppendNode(doc, stability, "SpeedGovernor");
223 if (data.speedGov) SaveControlElements(doc, speedGov, data.speedGov);
224
225 elementID++;
226 }
227 }
228
229
230
231 auto syncMotorsNode = XMLParser::AppendNode(doc, elementsNode, "SyncMotorList");
233 elementID = 0;
234 for (auto* syncMotor : syncMotorList) {
235 if (syncMotor->IsInserted()) {
236 syncMotor->SetID(elementID);
237 syncMotor->SaveElement(doc, syncMotorsNode);
238 elementID++;
239 }
240 }
241
242
243
244 auto transformersNode = XMLParser::AppendNode(doc, elementsNode, "TransformerList");
246 elementID = 0;
247 for (auto* transformer : transformerList) {
248 if (transformer->IsInserted()) {
249 transformer->SetID(elementID);
250 transformer->SaveElement(doc, transformersNode);
251 elementID++;
252 }
253 }
254
255
256
257 auto harmCurrentNode = XMLParser::AppendNode(doc, elementsNode, "HarmCurrentList");
259 elementID = 0;
260 for (auto* harmCurrent : harmCurrentList) {
261 if (harmCurrent->IsInserted()) {
262 harmCurrent->SetID(elementID);
263 harmCurrent->SaveElement(doc, harmCurrentNode);
264 elementID++;
265 }
266 }
267
268
269
270 auto emtElementNode = XMLParser::AppendNode(doc, elementsNode, "EMTElementList");
272 elementID = 0;
273 for (auto* emtElement : emtElementList) {
274 if (emtElement->IsInserted()) {
275 emtElement->SetID(elementID);
276 emtElement->SaveElement(doc, emtElementNode);
277 elementID++;
278 }
279 }
280
281
282
283 auto textsNode = XMLParser::AppendNode(doc, elementsNode, "TextList");
284 auto textList = m_workspace->GetTextList();
285 elementID = 0;
286 for (auto& text : textList) {
287 if (text->IsInserted()) {
288 text->SetID(elementID);
289 text->SaveElement(doc, textsNode);
290 elementID++;
291 }
292 }
293
294
295 std::ofstream writeXML(path.GetFullPath().mb_str());
296 writeXML << doc;
297 writeXML.close();
298}
Base class for electrical calculations providing general utility methods.
const std::vector< IndMotor * > GetIndMotorList() const
Get the induction motors of the system (use GetElementsFromList first).
const std::vector< Load * > GetLoadList() const
Get the loads of the system (use GetElementsFromList first).
const std::vector< SyncMotor * > GetSyncMotorList() const
Get the synchronous motors of the system (use GetElementsFromList first).
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< Capacitor * > GetCapacitorList() const
Get the capacitors of the system (use GetElementsFromList first).
const std::vector< Inductor * > GetInductorList() const
Get the inductors of the system (use GetElementsFromList first).
const std::vector< Line * > GetLineList() const
Get the lines of the system (use GetElementsFromList first).
const std::vector< EMTElement * > GetEMTElementList() const
Get the electromagnetic element list 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).