20FileHanding::~FileHanding() {}
21FileHanding::FileHanding(
Workspace* workspace) { m_workspace = workspace; }
22FileHanding::FileHanding(
ControlEditor* controlEditor) { m_controlEditor = controlEditor; }
23FileHanding::FileHanding() {}
24void FileHanding::SaveProject(wxFileName path)
27 std::ofstream writeProjectsFile(path.GetFullPath().mb_str());
28 writeProjectsFile.close();
30 rapidxml::xml_document<> doc;
31 rapidxml::file<> xmlFile(path.GetFullPath());
32 doc.parse<0>(xmlFile.data());
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);
41 rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element,
"Project");
42 doc.append_node(rootNode);
44 rapidxml::xml_node<>* projectNameNode = XMLParser::AppendNode(doc, rootNode,
"Name");
45 XMLParser::SetNodeValue(doc, projectNameNode, path.GetName());
49 auto propertiesNode = XMLParser::AppendNode(doc, rootNode,
"Properties");
51 SimulationData simulationData = properties->GetSimulationPropertiesData();
52 auto simulationPropNode = XMLParser::XMLParser::AppendNode(doc, propertiesNode,
"SimulationProperties");
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);
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);
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);
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);
121 auto elementsNode = XMLParser::AppendNode(doc, rootNode,
"Elements");
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);
141 auto capacitorsNode = XMLParser::AppendNode(doc, elementsNode,
"CapacitorList");
144 for (
auto* capacitor : capacitorList) {
145 if (capacitor->IsInserted()) {
146 capacitor->SetID(elementID);
147 capacitor->SaveElement(doc, capacitorsNode);
154 auto indMotorsNode = XMLParser::AppendNode(doc, elementsNode,
"IndMotorList");
157 for (
auto* indMotor : indMotorList) {
158 if (indMotor->IsInserted()) {
159 indMotor->SetID(elementID);
160 indMotor->SaveElement(doc, indMotorsNode);
167 auto inductorsNode = XMLParser::AppendNode(doc, elementsNode,
"InductorList");
170 for (
auto* inductor : inductorList) {
171 if (inductor->IsInserted()) {
172 inductor->SetID(elementID);
173 inductor->SaveElement(doc, inductorsNode);
180 auto linesNode = XMLParser::AppendNode(doc, elementsNode,
"LineList");
183 for (
auto* line : lineList) {
184 if (line->IsInserted()) {
185 line->SetID(elementID);
186 line->SaveElement(doc, linesNode);
193 auto loadsNode = XMLParser::AppendNode(doc, elementsNode,
"LoadList");
196 for (
auto* load : loadList) {
197 if (load->IsInserted()) {
198 load->SetID(elementID);
199 load->SaveElement(doc, loadsNode);
206 auto syncGeneratorsNode = XMLParser::AppendNode(doc, elementsNode,
"SyncGeneratorList");
209 for (
auto syncGen : syncGeneratorList) {
210 if (syncGen->IsInserted()) {
211 syncGen->SetID(elementID);
212 auto elementNode = syncGen->SaveElement(doc, syncGeneratorsNode);
215 auto data = syncGen->GetElectricalData();
216 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
217 auto stability = electricalProp->first_node(
"Stability");
219 auto avr = XMLParser::AppendNode(doc, stability,
"AVR");
220 if (data.avr) SaveControlElements(doc, avr, data.avr);
222 auto speedGov = XMLParser::AppendNode(doc, stability,
"SpeedGovernor");
223 if (data.speedGov) SaveControlElements(doc, speedGov, data.speedGov);
231 auto syncMotorsNode = XMLParser::AppendNode(doc, elementsNode,
"SyncMotorList");
234 for (
auto* syncMotor : syncMotorList) {
235 if (syncMotor->IsInserted()) {
236 syncMotor->SetID(elementID);
237 syncMotor->SaveElement(doc, syncMotorsNode);
244 auto transformersNode = XMLParser::AppendNode(doc, elementsNode,
"TransformerList");
247 for (
auto* transformer : transformerList) {
248 if (transformer->IsInserted()) {
249 transformer->SetID(elementID);
250 transformer->SaveElement(doc, transformersNode);
257 auto harmCurrentNode = XMLParser::AppendNode(doc, elementsNode,
"HarmCurrentList");
260 for (
auto* harmCurrent : harmCurrentList) {
261 if (harmCurrent->IsInserted()) {
262 harmCurrent->SetID(elementID);
263 harmCurrent->SaveElement(doc, harmCurrentNode);
270 auto emtElementNode = XMLParser::AppendNode(doc, elementsNode,
"EMTElementList");
273 for (
auto* emtElement : emtElementList) {
274 if (emtElement->IsInserted()) {
275 emtElement->SetID(elementID);
276 emtElement->SaveElement(doc, emtElementNode);
283 auto textsNode = XMLParser::AppendNode(doc, elementsNode,
"TextList");
284 auto textList = m_workspace->GetTextList();
286 for (
auto& text : textList) {
287 if (text->IsInserted()) {
288 text->SetID(elementID);
289 text->SaveElement(doc, textsNode);
295 std::ofstream writeXML(path.GetFullPath().mb_str());
300bool FileHanding::OpenProject(wxFileName path)
302 rapidxml::xml_document<> doc;
303 rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
305 doc.parse<0>(xmlFile.data());
307 auto projectNode = doc.first_node(
"Project");
308 if (!projectNode)
return false;
309 auto nameNode = projectNode->first_node(
"Name");
310 if (!nameNode)
return false;
311 m_workspace->SetName(nameNode->value());
317 auto propertiesNode = projectNode->first_node(
"Properties");
318 if (propertiesNode) {
319 auto simPropertiesNode = propertiesNode->first_node(
"SimulationProperties");
320 if (simPropertiesNode) {
322 auto general = simPropertiesNode->first_node(
"General");
323 simData.basePower = XMLParser::GetNodeValueDouble(general,
"BasePower");
324 simData.basePowerUnit =
325 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(general,
"BasePower",
"UnitID"));
326 auto contCalc = general->first_node(
"ContinuousCalculation");
327 simData.faultAfterPowerFlow = XMLParser::GetNodeValueInt(contCalc,
"Fault");
328 simData.scPowerAfterPowerFlow = XMLParser::GetNodeValueInt(contCalc,
"SCPower");
329 int harmDistortionAfterPowerFlow = XMLParser::GetNodeValueInt(contCalc,
"HarmonicDistortion");
330 simData.harmDistortionAfterPowerFlow = harmDistortionAfterPowerFlow != -1 ? harmDistortionAfterPowerFlow :
false;
333 auto powerFlow = simPropertiesNode->first_node(
"PowerFlow");
334 simData.powerFlowMethod =
335 static_cast<PowerFlowMethod
>(XMLParser::GetNodeValueInt(powerFlow,
"SolutionMethod"));
336 simData.accFator = XMLParser::GetNodeValueDouble(powerFlow,
"AccFactor");
337 simData.powerFlowTolerance = XMLParser::GetNodeValueDouble(powerFlow,
"Tolerance");
338 simData.powerFlowMaxIterations = XMLParser::GetNodeValueInt(powerFlow,
"MaxIterations");
339 simData.initAngle = XMLParser::GetNodeValueDouble(powerFlow,
"SlackAngle");
342 auto stability = simPropertiesNode->first_node(
"Stability");
343 simData.timeStep = XMLParser::GetNodeValueDouble(stability,
"TimeStep");
344 simData.stabilitySimulationTime = XMLParser::GetNodeValueDouble(stability,
"SimulationTime");
345 simData.stabilityFrequency = XMLParser::GetNodeValueDouble(stability,
"Frequency");
346 simData.stabilityTolerance = XMLParser::GetNodeValueDouble(stability,
"Tolerance");
347 simData.stabilityMaxIterations = XMLParser::GetNodeValueDouble(stability,
"MaxIterations");
348 simData.controlTimeStepRatio = XMLParser::GetNodeValueInt(stability,
"ControlStepRatio");
349 simData.plotTime = XMLParser::GetNodeValueDouble(stability,
"PlotStep");
350 simData.useCOI = XMLParser::GetNodeValueInt(stability,
"UseCOI");
353 auto compLoads = simPropertiesNode->first_node(
"ZIPLoad");
354 simData.useCompLoads = XMLParser::GetNodeValueInt(compLoads,
"UseCompositeLoad");
355 auto activePowerComp = compLoads->first_node(
"ActivePowerComposition");
356 simData.constImpedanceActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantImpedance");
357 simData.constCurrentActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantCurrent");
358 simData.constPowerActive = XMLParser::GetNodeValueDouble(activePowerComp,
"ConstantPower");
359 auto reactivePowerComp = compLoads->first_node(
"ReactivePowerComposition");
360 simData.constImpedanceReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantImpedance");
361 simData.constCurrentReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantCurrent");
362 simData.constPowerReactive = XMLParser::GetNodeValueDouble(reactivePowerComp,
"ConstantPower");
363 auto uvLimit = compLoads->first_node(
"UndervoltageLimit");
364 simData.underVoltageConstCurrent = XMLParser::GetNodeValueDouble(uvLimit,
"ConstantCurrent");
365 simData.underVoltageConstPower = XMLParser::GetNodeValueDouble(uvLimit,
"ConstantPower");
370 propData->SetSimulationPropertiesData(simData);
373 auto elementsNode = projectNode->first_node(
"Elements");
374 if (!elementsNode)
return false;
375 std::vector<Element*> elementList;
377 std::vector<Bus*> busList;
378 std::vector<Capacitor*> capacitorList;
379 std::vector<IndMotor*> indMotorList;
380 std::vector<Inductor*> inductorList;
381 std::vector<Line*> lineList;
382 std::vector<Load*> loadList;
383 std::vector<SyncGenerator*> syncGeneratorList;
384 std::vector<SyncMotor*> syncMotorList;
385 std::vector<Transformer*> transformerList;
386 std::vector<HarmCurrent*> harmCurrentList;
387 std::vector<EMTElement*> emtElementList;
389 std::vector< std::shared_ptr<Text> > textList;
392 std::vector<Element*> parentList;
395 auto busListNode = elementsNode->first_node(
"BusList");
396 if (!busListNode)
return false;
397 auto busNode = busListNode->first_node(
"Bus");
401 if (!bus->OpenElement(busNode))
return false;
402 elementList.push_back(bus);
403 busList.push_back(bus);
404 parentList.push_back(bus);
406 busNode = busNode->next_sibling(
"Bus");
410 auto capacitorListNode = elementsNode->first_node(
"CapacitorList");
411 if (!capacitorListNode)
return false;
412 auto capacitorNode = capacitorListNode->first_node(
"Capacitor");
413 while (capacitorNode) {
416 if (!capacitor->OpenElement(capacitorNode, parentList))
return false;
417 elementList.push_back(capacitor);
418 capacitorList.push_back(capacitor);
420 capacitorNode = capacitorNode->next_sibling(
"Capacitor");
424 auto indMotorListNode = elementsNode->first_node(
"IndMotorList");
425 if (!indMotorListNode)
return false;
426 auto indMotorNode = indMotorListNode->first_node(
"IndMotor");
427 while (indMotorNode) {
430 if (!indMotor->OpenElement(indMotorNode, parentList))
return false;
431 elementList.push_back(indMotor);
432 indMotorList.push_back(indMotor);
434 indMotorNode = indMotorNode->next_sibling(
"IndMotor");
438 auto inductorListNode = elementsNode->first_node(
"InductorList");
439 if (!inductorListNode)
return false;
440 auto inductorNode = inductorListNode->first_node(
"Inductor");
441 while (inductorNode) {
444 if (!inductor->OpenElement(inductorNode, parentList))
return false;
445 elementList.push_back(inductor);
446 inductorList.push_back(inductor);
448 inductorNode = inductorNode->next_sibling(
"Inductor");
452 auto lineListNode = elementsNode->first_node(
"LineList");
453 if (!lineListNode)
return false;
454 auto lineNode = lineListNode->first_node(
"Line");
458 if (!line->OpenElement(lineNode, parentList))
return false;
459 elementList.push_back(line);
460 lineList.push_back(line);
462 lineNode = lineNode->next_sibling(
"Line");
466 auto loadListNode = elementsNode->first_node(
"LoadList");
467 if (!loadListNode)
return false;
468 auto loadNode = loadListNode->first_node(
"Load");
472 if (!load->OpenElement(loadNode, parentList))
return false;
473 elementList.push_back(load);
474 loadList.push_back(load);
476 loadNode = loadNode->next_sibling(
"Load");
480 auto syncGeneratorListNode = elementsNode->first_node(
"SyncGeneratorList");
481 if (!syncGeneratorListNode)
return false;
482 auto syncGeneratorNode = syncGeneratorListNode->first_node(
"SyncGenerator");
484 while (syncGeneratorNode) {
487 if (!syncGenerator->OpenElement(syncGeneratorNode, parentList))
return false;
490 auto data = syncGenerator->GetElectricalData();
491 auto electricalProp = syncGeneratorNode->first_node(
"ElectricalProperties");
492 auto stability = electricalProp->first_node(
"Stability");
494 auto avr = stability->first_node(
"AVR");
495 if (!avr)
return false;
496 if (!OpenControlElements(doc, avr, data.avr))
return false;
498 auto speedGov = stability->first_node(
"SpeedGovernor");
499 if (!speedGov)
return false;
500 if (!OpenControlElements(doc, speedGov, data.speedGov))
return false;
502 syncGenerator->SetElectricalData(data);
504 elementList.push_back(syncGenerator);
505 syncGeneratorList.push_back(syncGenerator);
506 syncGeneratorNode = syncGeneratorNode->next_sibling(
"SyncGenerator");
510 auto syncMotorListNode = elementsNode->first_node(
"SyncMotorList");
511 if (!syncMotorListNode)
return false;
512 auto syncMotorNode = syncMotorListNode->first_node(
"SyncMotor");
513 while (syncMotorNode) {
516 if (!syncMotor->OpenElement(syncMotorNode, parentList))
return false;
517 elementList.push_back(syncMotor);
518 syncMotorList.push_back(syncMotor);
520 syncMotorNode = syncMotorNode->next_sibling(
"SyncMotor");
524 auto transformerListNode = elementsNode->first_node(
"TransformerList");
525 if (!transformerListNode)
return false;
526 auto transfomerNode = transformerListNode->first_node(
"Transfomer");
527 while (transfomerNode) {
530 if (!transformer->OpenElement(transfomerNode, parentList))
return false;
531 elementList.push_back(transformer);
532 transformerList.push_back(transformer);
534 transfomerNode = transfomerNode->next_sibling(
"Transfomer");
538 auto harmCurrentListNode = elementsNode->first_node(
"HarmCurrentList");
539 if (harmCurrentListNode) {
540 auto harmCurrentNode = harmCurrentListNode->first_node(
"HarmCurrent");
541 while (harmCurrentNode) {
544 if (!harmCurrent->OpenElement(harmCurrentNode, parentList))
return false;
545 elementList.push_back(harmCurrent);
546 harmCurrentList.push_back(harmCurrent);
548 harmCurrentNode = harmCurrentNode->next_sibling(
"HarmCurrent");
552 auto emtElementListNode = elementsNode->first_node(
"EMTElementList");
553 if (emtElementListNode) {
554 auto emtElementNode = emtElementListNode->first_node(
"EMTElement");
555 while (emtElementNode) {
558 if (!emtElement->OpenElement(emtElementNode, parentList))
return false;
559 elementList.push_back(emtElement);
560 emtElementList.push_back(emtElement);
562 emtElementNode = emtElementNode->next_sibling(
"EMTElement");
566 m_workspace->SetElementList(elementList);
569 auto textListNode = elementsNode->first_node(
"TextList");
570 if (!textListNode)
return false;
571 auto textNode = textListNode->first_node(
"Text");
574 auto text = std::make_shared<Text>();
576 if (!text->OpenElement(textNode))
return true;
578 switch (text->GetElementTypeText()) {
582 Bus* bus = busList[text->GetElementNumber()];
583 text->SetElement(bus);
585 case TYPE_CAPACITOR: {
586 Capacitor* capacitor = capacitorList[text->GetElementNumber()];
587 text->SetElement(capacitor);
589 case TYPE_IND_MOTOR: {
590 IndMotor* indMotor = indMotorList[text->GetElementNumber()];
591 text->SetElement(indMotor);
593 case TYPE_INDUCTOR: {
594 Inductor* inductor = inductorList[text->GetElementNumber()];
595 text->SetElement(inductor);
598 Line* line = lineList[text->GetElementNumber()];
599 text->SetElement(line);
602 Load* load = loadList[text->GetElementNumber()];
603 text->SetElement(load);
605 case TYPE_SYNC_GENERATOR: {
606 SyncGenerator* syncGenerator = syncGeneratorList[text->GetElementNumber()];
607 text->SetElement(syncGenerator);
609 case TYPE_SYNC_MOTOR: {
610 SyncMotor* syncMotor = syncMotorList[text->GetElementNumber()];
611 text->SetElement(syncMotor);
613 case TYPE_TRANSFORMER: {
614 Transformer* transformer = transformerList[text->GetElementNumber()];
615 text->SetElement(transformer);
617 case TYPE_HARMCURRENT: {
618 HarmCurrent* harmCurrent = harmCurrentList[text->GetElementNumber()];
619 text->SetElement(harmCurrent);
623 textList.push_back(text);
624 textNode = textNode->next_sibling(
"Text");
627 m_workspace->SetTextList(textList);
631void FileHanding::SaveControl(wxFileName path)
634 std::ofstream writeProjectsFile(path.GetFullPath().mb_str());
635 writeProjectsFile.close();
637 rapidxml::xml_document<> doc;
638 rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
639 doc.parse<0>(xmlFile.data());
641 rapidxml::xml_node<>* decl = doc.allocate_node(rapidxml::node_declaration);
642 rapidxml::xml_attribute<>* ver = doc.allocate_attribute(
"version",
"1.0");
643 rapidxml::xml_attribute<>* encoding = doc.allocate_attribute(
"encoding",
"utf-8");
644 decl->append_attribute(ver);
645 decl->append_attribute(encoding);
646 doc.append_node(decl);
648 rapidxml::xml_node<>* rootNode = doc.allocate_node(rapidxml::node_element,
"Control");
649 doc.append_node(rootNode);
651 rapidxml::xml_node<>* projectNameNode = XMLParser::AppendNode(doc, rootNode,
"Name");
652 XMLParser::SetNodeValue(doc, projectNameNode, path.GetName());
654 auto elementsNode = XMLParser::AppendNode(doc, rootNode,
"ControlElements");
655 SaveControlElements(doc, elementsNode);
656 std::ofstream writeXML(path.GetFullPath().mb_str());
661bool FileHanding::OpenControl(wxFileName path,
662 std::vector< std::shared_ptr<ControlElement> >& ctrlElementList,
663 std::vector< std::shared_ptr<ConnectionLine> >& ctrlConnectionList)
665 rapidxml::xml_document<> doc;
666 rapidxml::file<> xmlFile(path.GetFullPath().mb_str());
668 doc.parse<0>(xmlFile.data());
670 auto projectNode = doc.first_node(
"Control");
671 if (!projectNode)
return false;
677 auto elementsNode = projectNode->first_node(
"ControlElements");
678 if (!elementsNode)
return false;
682 if (!OpenControlElements(doc, elementsNode, ctrlElementContainer))
return false;
684 ctrlElementList.clear();
685 ctrlConnectionList.clear();
686 auto elementRawList = ctrlElementContainer->GetControlElementsList();
687 for (
auto& element : elementRawList) {
688 ctrlElementList.emplace_back(element);
690 auto connectionRawList = ctrlElementContainer->GetConnectionLineList();
691 for (
auto& connection : connectionRawList) {
692 ctrlConnectionList.emplace_back(connection);
699void FileHanding::SaveControlElements(rapidxml::xml_document<>& doc,
700 rapidxml::xml_node<>* elementsNode,
703 if (!ctrlContainer) {
705 ctrlContainer->FillContainer(m_controlEditor);
709 auto constsNode = XMLParser::AppendNode(doc, elementsNode,
"ConstantList");
710 auto constList = ctrlContainer->GetConstantList();
711 for (
auto it = constList.begin(), itEnd = constList.end(); it != itEnd; ++it) {
712 (*it)->SaveElement(doc, constsNode);
716 auto expsNode = XMLParser::AppendNode(doc, elementsNode,
"ExponentialList");
717 auto expList = ctrlContainer->GetExponentialList();
718 for (
auto it = expList.begin(), itEnd = expList.end(); it != itEnd; ++it) { (*it)->SaveElement(doc, expsNode); }
721 auto gainsNode = XMLParser::AppendNode(doc, elementsNode,
"GainList");
722 auto gainList = ctrlContainer->GetGainList();
723 for (
auto it = gainList.begin(), itEnd = gainList.end(); it != itEnd; ++it) {
724 (*it)->SaveElement(doc, gainsNode);
728 auto iosNode = XMLParser::AppendNode(doc, elementsNode,
"IOList");
729 auto ioList = ctrlContainer->GetIOControlList();
730 for (
auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) { (*it)->SaveElement(doc, iosNode); }
733 auto limitersNode = XMLParser::AppendNode(doc, elementsNode,
"LimiterList");
734 auto limiterList = ctrlContainer->GetLimiterList();
735 for (
auto it = limiterList.begin(), itEnd = limiterList.end(); it != itEnd; ++it) {
736 (*it)->SaveElement(doc, limitersNode);
740 auto multipliersNode = XMLParser::AppendNode(doc, elementsNode,
"MultiplierList");
741 auto multiplierList = ctrlContainer->GetMultiplierList();
742 for (
auto it = multiplierList.begin(), itEnd = multiplierList.end(); it != itEnd; ++it) {
743 (*it)->SaveElement(doc, multipliersNode);
747 auto dividersNode = XMLParser::AppendNode(doc, elementsNode,
"DividerList");
748 auto dividersList = ctrlContainer->GetDividerList();
749 for (
auto it = dividersList.begin(), itEnd = dividersList.end(); it != itEnd; ++it) {
750 (*it)->SaveElement(doc, dividersNode);
754 auto rateLimitersNode = XMLParser::AppendNode(doc, elementsNode,
"RateLimiterList");
755 auto rateLimiterList = ctrlContainer->GetRateLimiterList();
756 for (
auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) {
757 (*it)->SaveElement(doc, rateLimitersNode);
761 auto sumsNode = XMLParser::AppendNode(doc, elementsNode,
"SumList");
762 auto sumList = ctrlContainer->GetSumList();
763 for (
auto it = sumList.begin(), itEnd = sumList.end(); it != itEnd; ++it) { (*it)->SaveElement(doc, sumsNode); }
766 auto mathExprsNode = XMLParser::AppendNode(doc, elementsNode,
"MathExprList");
767 auto mathExprList = ctrlContainer->GetMathExprList();
768 for (
auto it = mathExprList.begin(), itEnd = mathExprList.end(); it != itEnd; ++it) {
769 (*it)->SaveElement(doc, mathExprsNode);
773 auto tfsNode = XMLParser::AppendNode(doc, elementsNode,
"TransferFunctionList");
774 auto tfList = ctrlContainer->GetTFList();
775 for (
auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) { (*it)->SaveElement(doc, tfsNode); }
778 auto cLinesNode = XMLParser::AppendNode(doc, elementsNode,
"ConnectionList");
779 auto connLineList = ctrlContainer->GetConnectionLineList();
780 for (
auto it = connLineList.begin(), itEnd = connLineList.end(); it != itEnd; ++it) {
782 auto cLineNode = XMLParser::AppendNode(doc, cLinesNode,
"Connection");
783 XMLParser::SetNodeAttribute(doc, cLineNode,
"ID", cLine->
GetID());
786 auto cadProp = XMLParser::AppendNode(doc, cLineNode,
"CADProperties");
787 auto offset = XMLParser::AppendNode(doc, cadProp,
"Offset");
788 XMLParser::SetNodeValue(doc, offset, cLine->GetOffset());
791 auto parentsNode = XMLParser::AppendNode(doc, cLineNode,
"ParentList");
794 for (
auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) {
796 auto parentNode = XMLParser::AppendNode(doc, parentsNode,
"Parent");
797 auto elementID = XMLParser::AppendNode(doc, parentNode,
"ElementID");
798 XMLParser::SetNodeValue(doc, elementID, parent->
GetID());
799 auto nodeID = XMLParser::AppendNode(doc, parentNode,
"NodeID");
800 XMLParser::SetNodeValue(doc, nodeID, cLine->GetNodeList()[nodeIndex]->GetID());
804 auto parentLine = XMLParser::AppendNode(doc, cLineNode,
"ParentLine");
805 if (cLine->GetParentLine()) {
807 XMLParser::SetNodeAttribute(doc, parentLine,
"ID", parent->
GetID());
810 XMLParser::SetNodeAttribute(doc, parentLine,
"ID", -1);
815bool FileHanding::OpenControlElements(rapidxml::xml_document<>& doc,
816 rapidxml::xml_node<>* elementsNode,
819 std::vector< std::shared_ptr<ControlElement> > elementList;
820 std::vector< std::shared_ptr<ConnectionLine> > connectionList;
823 auto constListNode = elementsNode->first_node(
"ConstantList");
825 auto constNode = constListNode->first_node(
"Constant");
827 int id = XMLParser::GetAttributeValueInt(constNode,
"ID");
830 if (!constant->OpenElement(constNode))
return false;
831 elementList.emplace_back(constant);
833 constNode = constNode->next_sibling(
"Constant");
839 auto expListNode = elementsNode->first_node(
"ExponentialList");
841 auto expNode = expListNode->first_node(
"Exponential");
843 int id = XMLParser::GetAttributeValueInt(expNode,
"ID");
846 if (!exponential->OpenElement(expNode))
return false;
847 elementList.emplace_back(exponential);
849 expNode = expNode->next_sibling(
"Exponential");
855 auto gainListNode = elementsNode->first_node(
"GainList");
857 auto gainNode = gainListNode->first_node(
"Gain");
859 int id = XMLParser::GetAttributeValueInt(gainNode,
"ID");
862 if (!gain->OpenElement(gainNode))
return false;
863 elementList.emplace_back(gain);
865 gainNode = gainNode->next_sibling(
"Gain");
871 auto ioListNode = elementsNode->first_node(
"IOList");
873 auto ioNode = ioListNode->first_node(
"IO");
875 int id = XMLParser::GetAttributeValueInt(ioNode,
"ID");
876 int ioFlags = XMLParser::GetNodeValueInt(ioNode,
"IOFlags");
880 if (!io->OpenElement(ioNode))
return false;
881 elementList.emplace_back(io);
883 ioNode = ioNode->next_sibling(
"IO");
889 auto limiterListNode = elementsNode->first_node(
"LimiterList");
890 if (limiterListNode) {
891 auto limiterNode = limiterListNode->first_node(
"Limiter");
892 while (limiterNode) {
893 int id = XMLParser::GetAttributeValueInt(limiterNode,
"ID");
896 if (!limiter->OpenElement(limiterNode))
return false;
897 elementList.emplace_back(limiter);
899 limiterNode = limiterNode->next_sibling(
"Limiter");
905 auto multiplierListNode = elementsNode->first_node(
"MultiplierList");
906 if (multiplierListNode) {
907 auto multiplierNode = multiplierListNode->first_node(
"Multiplier");
908 while (multiplierNode) {
909 int id = XMLParser::GetAttributeValueInt(multiplierNode,
"ID");
912 if (!multiplier->OpenElement(multiplierNode))
return false;
913 elementList.emplace_back(multiplier);
915 multiplierNode = multiplierNode->next_sibling(
"Multiplier");
921 auto dividerListNode = elementsNode->first_node(
"DividerList");
922 if (dividerListNode) {
923 auto dividerNode = dividerListNode->first_node(
"Divider");
924 while (dividerNode) {
925 int id = XMLParser::GetAttributeValueInt(dividerNode,
"ID");
928 if (!divider->OpenElement(dividerNode))
return false;
929 elementList.emplace_back(divider);
931 dividerNode = dividerNode->next_sibling(
"Divider");
937 auto rateLimiterListNode = elementsNode->first_node(
"RateLimiterList");
938 if (rateLimiterListNode) {
939 auto rateLimiterNode = rateLimiterListNode->first_node(
"RateLimiter");
940 while (rateLimiterNode) {
941 int id = XMLParser::GetAttributeValueInt(rateLimiterNode,
"ID");
944 if (!limiter->OpenElement(rateLimiterNode))
return false;
945 elementList.emplace_back(limiter);
947 rateLimiterNode = rateLimiterNode->next_sibling(
"RateLimiter");
953 auto sumListNode = elementsNode->first_node(
"SumList");
955 auto sumNode = sumListNode->first_node(
"Sum");
957 int id = XMLParser::GetAttributeValueInt(sumNode,
"ID");
960 if (!sum->OpenElement(sumNode))
return false;
961 elementList.emplace_back(sum);
963 sumNode = sumNode->next_sibling(
"Sum");
969 auto mathListNode = elementsNode->first_node(
"MathExprList");
971 auto mathExprNode = mathListNode->first_node(
"MathExpr");
972 while (mathExprNode) {
973 int id = XMLParser::GetAttributeValueInt(mathExprNode,
"ID");
976 if (!mathExpr->OpenElement(mathExprNode))
return false;
977 elementList.emplace_back(mathExpr);
979 mathExprNode = mathExprNode->next_sibling(
"MathExpr");
985 auto tfListNode = elementsNode->first_node(
"TransferFunctionList");
987 auto tfNode = tfListNode->first_node(
"TransferFunction");
989 int id = XMLParser::GetAttributeValueInt(tfNode,
"ID");
992 if (!tf->OpenElement(tfNode))
return false;
993 elementList.emplace_back(tf);
995 tfNode = tfNode->next_sibling(
"TransferFunction");
1001 auto connectionListNode = elementsNode->first_node(
"ConnectionList");
1002 if (connectionListNode) {
1003 auto connNode = connectionListNode->first_node(
"Connection");
1006 int id = XMLParser::GetAttributeValueInt(connNode,
"ID");
1008 auto cadPropNode = connNode->first_node(
"CADProperties");
1009 if (!cadPropNode)
return false;
1010 double offset = XMLParser::GetNodeValueDouble(cadPropNode,
"Offset");
1012 auto parentList = connNode->first_node(
"ParentList");
1013 if (!parentList)
return false;
1015 auto parentNode = parentList->first_node(
"Parent");
1016 bool firstNode =
true;
1017 while (parentNode) {
1018 int elementID = XMLParser::GetNodeValueInt(parentNode,
"ElementID");
1019 int nodeID = XMLParser::GetNodeValueInt(parentNode,
"NodeID");
1021 ControlElement* element = ControlElement::GetControlElementFromID(elementList, elementID);
1022 Node* node = element->GetNodeList()[nodeID];
1027 if (!firstNode) cLine->AppendNode(node, element);
1029 if (firstNode) firstNode =
false;
1030 parentNode = parentNode->next_sibling(
"Parent");
1033 auto parentLine = connNode->first_node(
"ParentLine");
1034 if (!parentLine)
return false;
1035 int parentLineID = XMLParser::GetAttributeValueInt(parentLine,
"ID");
1036 if (parentLineID != -1) {
1037 for (
auto it = connectionList.begin(), itEnd = connectionList.end(); it != itEnd; ++it) {
1039 if (parent->
GetID() == parentLineID) {
1040 cLine->SetParentLine(parent);
1046 cLine->SetOffset(offset);
1047 cLine->UpdatePoints();
1048 connectionList.emplace_back(cLine);
1049 connNode = connNode->next_sibling(
"Connection");
1053 ctrlContainer->FillContainer(elementList, connectionList);
ElectricalUnit
Electrical units.
Node for power elements. All others power elements are connected through this.
Shunt capactior power element.
Connection between two control elements or other connection line and an element.
A control element that provides a constant value.
Class that can contain all control elements. Can identify (using RTTI) the elements from a generic li...
Control element that divides two inputs.
Element to connect ATP-EMTP.
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).
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual std::vector< Element * > GetParentList() const
Get the parent list.
virtual int GetID() const
Get the element ID.
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
virtual void AddChild(Element *child)
Add a child to the child list.
Generates an output following an exponential function.
Provide an output multiplying the input by a constant.
Shunt Harmonic Corrent Source.
Provides the communication with the power element.
Induction motor power element.
Inductor shunt power element.
Limits the input value by superior and inferior values.
Loas shunt power element.
A generic math expression block that can perform math and conditional operations with the inputs.
Node of a control element. This class manages the user interaction with the connection and control el...
General and simulation data manager.
Limits the rising and/or falling rate.
Sum the all inputs (can choose the input signal).
Synchronous generator power element.
Synchronous motor (synchronous compensator) power element.
Calculates the time response by a frequency domain transfer function.
This class manages the graphical and power elements. It is responsible for handling the user's intera...