diff --git a/nrt/data/IEEE14/CTC/files/IEEE14.crv b/nrt/data/IEEE14/CTC/files/IEEE14.crv new file mode 100644 index 00000000..3f726487 --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/IEEE14.crv @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nrt/data/IEEE14/CTC/files/IEEE14.dyd b/nrt/data/IEEE14/CTC/files/IEEE14.dyd new file mode 100644 index 00000000..63b3310a --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/IEEE14.dyd @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nrt/data/IEEE14/CTC/files/IEEE14.iidm b/nrt/data/IEEE14/CTC/files/IEEE14.iidm new file mode 100644 index 00000000..1ec775cf --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/IEEE14.iidm @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nrt/data/IEEE14/CTC/files/IEEE14.jobs b/nrt/data/IEEE14/CTC/files/IEEE14.jobs new file mode 100644 index 00000000..2016f742 --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/IEEE14.jobs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/nrt/data/IEEE14/CTC/files/IEEE14.par b/nrt/data/IEEE14/CTC/files/IEEE14.par new file mode 100644 index 00000000..cb5a2e34 --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/IEEE14.par @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nrt/data/IEEE14/CTC/files/fic_MULTIPLE.xml b/nrt/data/IEEE14/CTC/files/fic_MULTIPLE.xml new file mode 100644 index 00000000..cd0bcc5c --- /dev/null +++ b/nrt/data/IEEE14/CTC/files/fic_MULTIPLE.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/nrt/data/IEEE14/CTC/reference/aggregatedResults.xml b/nrt/data/IEEE14/CTC/reference/aggregatedResults.xml new file mode 100644 index 00000000..9f01783d --- /dev/null +++ b/nrt/data/IEEE14/CTC/reference/aggregatedResults.xml @@ -0,0 +1,4 @@ + + + + diff --git a/nrt/data/IEEE14/cases.py b/nrt/data/IEEE14/cases.py index 8dd8ce96..97a8e205 100755 --- a/nrt/data/IEEE14/cases.py +++ b/nrt/data/IEEE14/cases.py @@ -95,3 +95,13 @@ job_file = os.path.join(os.path.dirname(__file__), "IEEE14_BlackBoxModels", "IEEE14.jobs") test_cases.append((case_name, case_description, "CS", job_file, -1, 5, False, standardReturnCodeType, standardReturnCode)) + +######################################### +# IEEE14 - Critical Time Calculation # +######################################### + +case_name = "IEEE14_CTC" +case_description = "IEEE14 - Critical Time Calculation input file" +job_file = os.path.join(os.path.dirname(__file__), "CTC", "fic_MULTIPLE.xml") + +test_cases.append((case_name, case_description, "CTC", job_file, -1, 5, False, standardReturnCodeType, standardReturnCode)) diff --git a/sources/API/aggregatedResults/DYNAggrResXmlExporter.cpp b/sources/API/aggregatedResults/DYNAggrResXmlExporter.cpp index cef1b686..c6d2d4d6 100644 --- a/sources/API/aggregatedResults/DYNAggrResXmlExporter.cpp +++ b/sources/API/aggregatedResults/DYNAggrResXmlExporter.cpp @@ -101,6 +101,34 @@ XmlExporter::exportLoadIncreaseResultsToStream(const vector& formatter->endDocument(); } +void +XmlExporter::exportCriticalTimeResultsToFile(double criticalTime, const std::string& messageCriticalTimeError, std::string filePath) const { + fstream file; + file.open(filePath.c_str(), fstream::out); + if (!file.is_open()) { + throw DYNError(DYN::Error::API, KeyError_t::FileGenerationFailed, filePath.c_str()); + } + + exportCriticalTimeResultsToStream(criticalTime, messageCriticalTimeError, file); + file.close(); +} + +void +XmlExporter::exportCriticalTimeResultsToStream(double criticalTime, const std::string& messageCriticalTimeError, std::ostream& stream) const { + FormatterPtr formatter = Formatter::createFormatter(stream, "http://www.rte-france.com/dynawo"); + + formatter->startDocument(); + AttributeList attrs; + formatter->startElement("aggregatedResults", attrs); + attrs.add("criticalTime", criticalTime); + attrs.add("message", messageCriticalTimeError); + formatter->startElement("criticalTimeResults", attrs); + formatter->endElement(); + + formatter->endElement(); // aggregatedResults + formatter->endDocument(); +} + void XmlExporter::appendScenarioResultsElement(const vector& results, FormatterPtr& formatter) const { AttributeList attrs; diff --git a/sources/API/aggregatedResults/DYNAggrResXmlExporter.h b/sources/API/aggregatedResults/DYNAggrResXmlExporter.h index 7d15ba35..ec3f7ea4 100644 --- a/sources/API/aggregatedResults/DYNAggrResXmlExporter.h +++ b/sources/API/aggregatedResults/DYNAggrResXmlExporter.h @@ -60,6 +60,22 @@ class XmlExporter { */ void exportLoadIncreaseResultsToStream(const std::vector& results, std::ostream& stream) const; + /** + * @brief Export critical time calculation results into a file + * + * @param results aggregated results to export + * @param filePath file where the results must be exported + */ + void exportCriticalTimeResultsToFile(double criticalTime, const std::string& messageCriticalTimeError, std::string filePath) const; + + /** + * @brief Export critical time calculation results into a stream + * + * @param results aggregated results to export + * @param stream stream where the results must be exported + */ + void exportCriticalTimeResultsToStream(double CriticalTime, const std::string& messageCriticalTimeError, std::ostream& stream) const; + private: /** * @brief append to the formatter a scenario results diff --git a/sources/API/aggregatedResults/test/TestAggregatedResults.cpp b/sources/API/aggregatedResults/test/TestAggregatedResults.cpp index 9944e1ec..502fdbaa 100644 --- a/sources/API/aggregatedResults/test/TestAggregatedResults.cpp +++ b/sources/API/aggregatedResults/test/TestAggregatedResults.cpp @@ -89,4 +89,16 @@ TEST(TestAggregatedResults, TestAggregatedResultsLoadIncreaseResults) { std::cout << ssDiff.str() << std::endl; ASSERT_EQ(ssDiff.str(), "Executing command : diff res/loadIncreaseResultsRef.xml res/loadIncreaseResults.xml\n"); } + +TEST(TestAggregatedResults, TestAggregatedResultsCriticalTimeResults) { + const double& criticalTime = 1; + std::string messageCriticalTimeError = "MyMessage"; + + XmlExporter exporter; + exporter.exportCriticalTimeResultsToFile(criticalTime, messageCriticalTimeError, "res/criticalTimeResults.xml"); + std::stringstream ssDiff; + executeCommand("diff res/criticalTimeResultsRef.xml res/criticalTimeResults.xml", ssDiff); + std::cout << ssDiff.str() << std::endl; + ASSERT_EQ(ssDiff.str(), "Executing command : diff res/criticalTimeResultsRef.xml res/criticalTimeResults.xml\n"); +} } // namespace aggregatedResults diff --git a/sources/API/aggregatedResults/test/res/criticalTimeResultsRef.xml b/sources/API/aggregatedResults/test/res/criticalTimeResultsRef.xml new file mode 100644 index 00000000..72281202 --- /dev/null +++ b/sources/API/aggregatedResults/test/res/criticalTimeResultsRef.xml @@ -0,0 +1,4 @@ + + + + diff --git a/sources/API/aggregatedResults/xsd/aggregatedResults.xsd b/sources/API/aggregatedResults/xsd/aggregatedResults.xsd index 330f9f4a..f7ce0e34 100644 --- a/sources/API/aggregatedResults/xsd/aggregatedResults.xsd +++ b/sources/API/aggregatedResults/xsd/aggregatedResults.xsd @@ -21,6 +21,7 @@ + @@ -55,5 +56,10 @@ + + + + + diff --git a/sources/API/multipleJobs/DYNMultipleJobs.cpp b/sources/API/multipleJobs/DYNMultipleJobs.cpp index b1df18b4..8f507fcd 100644 --- a/sources/API/multipleJobs/DYNMultipleJobs.cpp +++ b/sources/API/multipleJobs/DYNMultipleJobs.cpp @@ -21,9 +21,11 @@ #include "DYNScenarios.h" #include "DYNMarginCalculation.h" +#include "DYNCriticalTimeCalculation.h" using DYNAlgorithms::Scenarios; using DYNAlgorithms::MarginCalculation; +using DYNAlgorithms::CriticalTimeCalculation; namespace multipleJobs { @@ -43,6 +45,11 @@ MultipleJobs::setMarginCalculation(const boost::shared_ptr& m marginCalculation_ = marginCalculation; } +void +MultipleJobs::setCriticalTimeCalculation(const boost::shared_ptr& criticalTimeCalculation) { + criticalTimeCalculation_ = criticalTimeCalculation; +} + boost::shared_ptr MultipleJobs::getScenarios() const { return scenarios_; @@ -52,4 +59,9 @@ boost::shared_ptr MultipleJobs::getMarginCalculation() const { return marginCalculation_; } + +boost::shared_ptr +MultipleJobs::getCriticalTimeCalculation() const { + return criticalTimeCalculation_; +} } // namespace multipleJobs diff --git a/sources/API/multipleJobs/DYNMultipleJobs.h b/sources/API/multipleJobs/DYNMultipleJobs.h index 7b0f2583..4d2bfa31 100644 --- a/sources/API/multipleJobs/DYNMultipleJobs.h +++ b/sources/API/multipleJobs/DYNMultipleJobs.h @@ -25,6 +25,7 @@ namespace DYNAlgorithms { class Scenarios; class MarginCalculation; +class CriticalTimeCalculation; } namespace multipleJobs { @@ -57,6 +58,12 @@ class MultipleJobs { */ void setMarginCalculation(const boost::shared_ptr& marginCalculation); + /** + * @brief Set the critical time calculation input data to launch + * @param criticalTimeCalculation critical time calculation input data to launch + */ + void setCriticalTimeCalculation(const boost::shared_ptr& criticalTimeCalculation); + /** * @brief get the list of scenarios to launch * @return list of scenarios to launch @@ -69,9 +76,16 @@ class MultipleJobs { */ boost::shared_ptr getMarginCalculation() const; + /** + * @brief get the critical time calculation to launch + * @return critical time calculation to launch + */ + boost::shared_ptr getCriticalTimeCalculation() const; + private: boost::shared_ptr scenarios_; ///< scenarios to launch boost::shared_ptr marginCalculation_; ///< margin calculation to launch + boost::shared_ptr criticalTimeCalculation_; ///< critical time calculation to launch }; } // namespace multipleJobs diff --git a/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.cpp b/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.cpp index 63fe22ee..eba9825f 100644 --- a/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.cpp +++ b/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.cpp @@ -30,6 +30,7 @@ #include "DYNMultipleJobs.h" #include "DYNMultipleJobsFactory.h" #include "DYNMarginCalculation.h" +#include "DYNCriticalTimeCalculation.h" #include "DYNScenarios.h" #include "DYNScenario.h" @@ -43,18 +44,22 @@ using DYNAlgorithms::Scenarios; using DYNAlgorithms::Scenario; using DYNAlgorithms::MarginCalculation; using DYNAlgorithms::LoadIncrease; +using DYNAlgorithms::CriticalTimeCalculation; namespace multipleJobs { XmlHandler::XmlHandler() : multipleJobsRead_(MultipleJobsFactory::newInstance()), scenariosHandler_(parser::ElementName(multipleJobs_ns, "scenarios")), +criticalTimeCalculationHandler_(parser::ElementName(multipleJobs_ns, "criticalTimeCalculation")), marginCalculationHandler_(parser::ElementName(multipleJobs_ns, "marginCalculation")) { onElement(multipleJobs_ns("multipleJobs/scenarios"), scenariosHandler_); onElement(multipleJobs_ns("multipleJobs/marginCalculation"), marginCalculationHandler_); + onElement(multipleJobs_ns("multipleJobs/criticalTimeCalculation"), criticalTimeCalculationHandler_); scenariosHandler_.onEnd(lambda::bind(&XmlHandler::addScenarios, lambda::ref(*this))); marginCalculationHandler_.onEnd(lambda::bind(&XmlHandler::addMarginCalculation, lambda::ref(*this))); + criticalTimeCalculationHandler_.onEnd(lambda::bind(&XmlHandler::addCriticalTimeCalculation, lambda::ref(*this))); } XmlHandler::~XmlHandler() { @@ -75,6 +80,11 @@ XmlHandler::addMarginCalculation() { multipleJobsRead_->setMarginCalculation(marginCalculationHandler_.get()); } +void +XmlHandler::addCriticalTimeCalculation() { + multipleJobsRead_->setCriticalTimeCalculation(criticalTimeCalculationHandler_.get()); +} + MarginCalculationHandler::MarginCalculationHandler(const elementName_type& root_element) : scenariosHandler_(parser::ElementName(multipleJobs_ns, "scenarios")), loadIncreaseHandler_(parser::ElementName(multipleJobs_ns, "loadIncrease")) { @@ -118,6 +128,40 @@ MarginCalculationHandler::get() const { return marginCalculation_; } +CriticalTimeCalculationHandler::CriticalTimeCalculationHandler(const elementName_type& root_element) { + onStartElement(root_element, lambda::bind(&CriticalTimeCalculationHandler::create, lambda::ref(*this), lambda_args::arg2)); +} + +CriticalTimeCalculationHandler::~CriticalTimeCalculationHandler() { +} + +boost::shared_ptr +CriticalTimeCalculationHandler::get() const { + return criticalTimeCalculation_; +} + +void +CriticalTimeCalculationHandler::create(attributes_type const& attributes) { + criticalTimeCalculation_ = boost::shared_ptr(new CriticalTimeCalculation()); + if (attributes.has("accuracy")) + criticalTimeCalculation_->setAccuracy(attributes["accuracy"]); + + if (attributes.has("jobsFile")) + criticalTimeCalculation_->setJobsFile(attributes["jobsFile"]); + + if (attributes.has("dydId")) + criticalTimeCalculation_->setDydId(attributes["dydId"]); + + if (attributes.has("endPar")) + criticalTimeCalculation_->setEndPar(attributes["endPar"]); + + if (attributes.has("minValue")) + criticalTimeCalculation_->setMinValue(attributes["minValue"]); + + if (attributes.has("maxValue")) + criticalTimeCalculation_->setMaxValue(attributes["maxValue"]); +} + ScenariosHandler::ScenariosHandler(const elementName_type& root_element) : scenarioHandler_(parser::ElementName(multipleJobs_ns, "scenario")) { onStartElement(root_element, lambda::bind(&ScenariosHandler::create, lambda::ref(*this), lambda_args::arg2)); diff --git a/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.h b/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.h index 50cc4e3c..285c0f3a 100644 --- a/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.h +++ b/sources/API/multipleJobs/DYNMultipleJobsXmlHandler.h @@ -28,6 +28,7 @@ namespace DYNAlgorithms { class Scenario; class Scenarios; class MarginCalculation; +class CriticalTimeCalculation; class LoadIncrease; } @@ -188,6 +189,36 @@ class MarginCalculationHandler : public xml::sax::parser::ComposableElementHandl boost::shared_ptr marginCalculation_; ///< current margin calculation element }; +class CriticalTimeCalculationHandler : public xml::sax::parser::ComposableElementHandler { + public: + /** + * @brief Constructor + * @param root_element complete name of the element read by the handler + */ + explicit CriticalTimeCalculationHandler(const elementName_type& root_element); + + /** + * @brief default destructor + */ + ~CriticalTimeCalculationHandler(); + + /** + * @brief return the critical time calculation read in xml file + * @return critical time calculation object build thanks to infos read in xml file + */ + boost::shared_ptr get() const; + + protected: + /** + * @brief Called when the XML element opening tag is read + * @param attributes attributes of the element + */ + void create(attributes_type const& attributes); + + private: + boost::shared_ptr criticalTimeCalculation_; ///< current critical time calculation element +}; + /** * @class XmlHandler * @brief Parameters file handler class @@ -225,9 +256,15 @@ class XmlHandler : public xml::sax::parser::ComposableDocumentHandler { */ void addMarginCalculation(); + /** + * @brief add a critical time calculation element to the current MultipleJobs element + */ + void addCriticalTimeCalculation(); + private: boost::shared_ptr multipleJobsRead_; ///< MultipleJobs instance ScenariosHandler scenariosHandler_; ///< handler used to read scenarios element + CriticalTimeCalculationHandler criticalTimeCalculationHandler_; ///< handler used to read critical time calculation element MarginCalculationHandler marginCalculationHandler_; ///< handler used to read margin calculation element }; diff --git a/sources/API/multipleJobs/test/TestMultipleJobs.cpp b/sources/API/multipleJobs/test/TestMultipleJobs.cpp index 0a8de6e9..9ca7d0ab 100644 --- a/sources/API/multipleJobs/test/TestMultipleJobs.cpp +++ b/sources/API/multipleJobs/test/TestMultipleJobs.cpp @@ -20,6 +20,7 @@ #include "DYNScenarios.h" #include "DYNScenario.h" #include "DYNMarginCalculation.h" +#include "DYNCriticalTimeCalculation.h" #include "DYNMultipleJobs.h" #include "DYNMultipleJobsFactory.h" #include "DYNMultipleJobsXmlHandler.h" @@ -33,26 +34,34 @@ TEST(TestMultipleJobs, TestMultipleJobsClass) { MultipleJobs mj; boost::shared_ptr mc(new DYNAlgorithms::MarginCalculation()); boost::shared_ptr scenarios(new DYNAlgorithms::Scenarios()); + boost::shared_ptr ct(new DYNAlgorithms::CriticalTimeCalculation()); mj.setScenarios(scenarios); mj.setMarginCalculation(mc); + mj.setCriticalTimeCalculation(ct); ASSERT_EQ(mj.getScenarios(), scenarios); ASSERT_EQ(mj.getMarginCalculation(), mc); + ASSERT_EQ(mj.getCriticalTimeCalculation(), ct); } TEST(TestMultipleJobs, TestMultipleJobsFactory) { boost::shared_ptr mj = MultipleJobsFactory::newInstance(); boost::shared_ptr mc(new DYNAlgorithms::MarginCalculation()); boost::shared_ptr scenarios(new DYNAlgorithms::Scenarios()); + boost::shared_ptr ct(new DYNAlgorithms::CriticalTimeCalculation()); mj->setScenarios(scenarios); mj->setMarginCalculation(mc); + mj->setCriticalTimeCalculation(ct); ASSERT_EQ(mj->getScenarios(), scenarios); ASSERT_EQ(mj->getMarginCalculation(), mc); + ASSERT_EQ(mj->getCriticalTimeCalculation(), ct); boost::shared_ptr mj2 = MultipleJobsFactory::copyInstance(mj); ASSERT_EQ(mj2->getScenarios(), scenarios); ASSERT_EQ(mj2->getMarginCalculation(), mc); + ASSERT_EQ(mj2->getCriticalTimeCalculation(), ct); boost::shared_ptr mj3 = MultipleJobsFactory::copyInstance(*mj); ASSERT_EQ(mj3->getScenarios(), scenarios); ASSERT_EQ(mj3->getMarginCalculation(), mc); + ASSERT_EQ(mj3->getCriticalTimeCalculation(), ct); } TEST(TestMultipleJobs, TestMultipleJobsXmlHandlerMarginCalculation) { @@ -105,4 +114,27 @@ TEST(TestMultipleJobs, TestMultipleJobsXmlHandlerScenarios) { ASSERT_EQ(scenarios->getScenarios()[1]->getCriteriaFile(), "MyScenario2.crt"); ASSERT_EQ(scenarios->getJobsFile(), "myScenarios.jobs"); } + +TEST(TestMultipleJobs, TestMultipleJobsXmlHanderCriticalTime) { + XmlHandler multipleJobsHandler; + std::ifstream stream("res/criticalTimeCalculation.xml"); + + xml::sax::parser::ParserFactory parser_factory; + xml::sax::parser::ParserPtr parser = parser_factory.createParser(); + parser->addXmlSchema("multipleJobs.xsd"); + parser->parse(stream, multipleJobsHandler, true); + boost::shared_ptr mj = multipleJobsHandler.getMultipleJobs(); + assert(mj); + assert(!mj->getScenarios()); + assert(!mj->getMarginCalculation()); + assert(mj->getCriticalTimeCalculation()); + boost::shared_ptr ct(new DYNAlgorithms::CriticalTimeCalculation()); + ct = mj->getCriticalTimeCalculation(); + ASSERT_EQ(ct->getAccuracy(), 0.001); + ASSERT_EQ(ct->getJobsFile(), "Myjobs.jobs"); + ASSERT_EQ(ct->getDydId(), "MyDydId"); + ASSERT_EQ(ct->getEndPar(), "MyEndPar"); + ASSERT_EQ(ct->getMinValue(), 0.1); + ASSERT_EQ(ct->getMaxValue(), 1); +} } // namespace multipleJobs diff --git a/sources/API/multipleJobs/test/res/criticalTimeCalculation.xml b/sources/API/multipleJobs/test/res/criticalTimeCalculation.xml new file mode 100644 index 00000000..dc812fc8 --- /dev/null +++ b/sources/API/multipleJobs/test/res/criticalTimeCalculation.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/sources/API/multipleJobs/xsd/multipleJobs.xsd b/sources/API/multipleJobs/xsd/multipleJobs.xsd index 9430b25d..1597cda5 100644 --- a/sources/API/multipleJobs/xsd/multipleJobs.xsd +++ b/sources/API/multipleJobs/xsd/multipleJobs.xsd @@ -17,6 +17,7 @@ + @@ -54,4 +55,13 @@ + + + + + + + + + diff --git a/sources/Common/CMakeLists.txt b/sources/Common/CMakeLists.txt index d9ff4c10..20dd8d9b 100644 --- a/sources/Common/CMakeLists.txt +++ b/sources/Common/CMakeLists.txt @@ -52,6 +52,7 @@ set(DYN_ALGO_COMMON_SOURCES DYNSimulationResult.cpp DYNLoadIncreaseResult.cpp DYNMPIContext.cpp + DYNCriticalTimeCalculation.cpp ${CPP_KEYS} ) @@ -63,6 +64,7 @@ set(DYN_ALGO_COMMON_HEADERS DYNLoadIncreaseResult.h DYNMPIContext.h DYNMPIContext.hpp + DYNCriticalTimeCalculation.h ${INCLUDE_KEYS} ) diff --git a/sources/Common/DYNCriticalTimeCalculation.cpp b/sources/Common/DYNCriticalTimeCalculation.cpp new file mode 100644 index 00000000..60690cdd --- /dev/null +++ b/sources/Common/DYNCriticalTimeCalculation.cpp @@ -0,0 +1,87 @@ +// +// Copyright (c) 2021, RTE (http://www.rte-france.com) +// See AUTHORS.txt +// All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, you can obtain one at http://mozilla.org/MPL/2.0/. +// SPDX-License-Identifier: MPL-2.0 +// +// This file is part of Dynawo, an hybrid C++/Modelica open source suite +// of simulation tools for power systems. +// + +/** + * @file CriticalTimeCalculation.cpp + * @brief CriticalTimeCalculation description : implementation file + * + */ + +#include "DYNCriticalTimeCalculation.h" +#include "MacrosMessage.h" + +namespace DYNAlgorithms { + +void +CriticalTimeCalculation::setAccuracy(double accuracy) { + if (accuracy < 0 || accuracy > 1) + throw DYNAlgorithmsError(IncoherentAccuracyCriticalTime, accuracy); + accuracy_ = accuracy; +} + +double +CriticalTimeCalculation::getAccuracy() const { + return accuracy_; +} + +void +CriticalTimeCalculation::setJobsFile(std::string jobsFile) { + jobsFile_ = jobsFile; +} + +const std::string& +CriticalTimeCalculation::getJobsFile() const { + return jobsFile_; +} + +void +CriticalTimeCalculation::setDydId(const std::string& dydId) { + dydId_ = dydId; +} + +std::string +CriticalTimeCalculation::getDydId() const { + return dydId_; +} + +void +CriticalTimeCalculation::setEndPar(std::string endPar) { + endPar_ = endPar; +} + +std::string +CriticalTimeCalculation::getEndPar() const { + return endPar_; +} + +void +CriticalTimeCalculation::setMinValue(double minValue) { + minValue_ = minValue; +} + +double +CriticalTimeCalculation::getMinValue() const { + return minValue_; +} + +void +CriticalTimeCalculation::setMaxValue(double maxValue) { + maxValue_ = maxValue; +} + +double +CriticalTimeCalculation::getMaxValue() { + return maxValue_; +} + +} // namespace DYNAlgorithms diff --git a/sources/Common/DYNCriticalTimeCalculation.h b/sources/Common/DYNCriticalTimeCalculation.h new file mode 100644 index 00000000..8875b1e1 --- /dev/null +++ b/sources/Common/DYNCriticalTimeCalculation.h @@ -0,0 +1,118 @@ +// +// Copyright (c) 2021, RTE (http://www.rte-france.com) +// See AUTHORS.txt +// All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, you can obtain one at http://mozilla.org/MPL/2.0/. +// SPDX-License-Identifier: MPL-2.0 +// +// This file is part of Dynawo, an hybrid C++/Modelica open source suite +// of simulation tools for power systems. +// + +/** + * @file DYNCriticalTimeCalculation.h + * + * @brief CriticalCalculation description : header file + * + */ + +#ifndef COMMON_DYNCRITICALTIMECALCULATION_H_ +#define COMMON_DYNCRITICALTIMECALCULATION_H_ + +#include + +namespace DYNAlgorithms { + +/** + * @brief Margin calculation class + * + * Class for margin calculation element : input data + */ +class CriticalTimeCalculation { + public: + /** + * @brief set the accuracy of the algorithm + * @param accuracy accuracy of the algorithm + */ + void setAccuracy(double accuracy); + + /** + * @brief get the accuracy of the algorithm + * @return accuracy of the algorithm + */ + double getAccuracy() const; + + /** + * @brief set the jobs file used for the simulation + * @param jobsFile jobs file used for the simulation + */ + void setJobsFile(std::string jobsFile); + + /** + * @brief get the jobs file used for the simulation + * @return jobs file used for the simulation + */ + const std::string& getJobsFile() const; + + /** + * @brief set the id parameter from the Dyd file. + * @param parSetId id parameter we will use + */ + void setDydId(const std::string& dydId); + + /** + * @brief get the id parameter from the Dyd file. + * @return id parameter we will use + */ + std::string getDydId() const; + + /** + * @brief set the end parameter used for the simulation + * @param endPar end parameter used for the simulation + */ + void setEndPar(std::string endPar); + + /** + * @brief get the end parameter used for the simulation + * @return end parameter used for the simulation + */ + std::string getEndPar() const; + + /** + * @brief set the minimum value used for the simulation + * @param minValue minimum value used for the simulation + */ + void setMinValue(double minValue); + + /** + * @brief get the minimum value used for the simulation + * @return minimum value used for the simulation + */ + double getMinValue() const; + + /** + * @brief set the maximum value used for the simulation + * @param maxValue maximum value used for the simulation + */ + void setMaxValue(double maxValue); + + /** + * @brief get the maximum value used for the simulation + * @return maximum value used for the simulation + */ + double getMaxValue(); + + private: + double accuracy_; ///< accuracy of the algorithm + std::string jobsFile_; ///< jobs file used for the simulation + std::string dydId_; ///< dyd id in the dyd file + std::string endPar_; ///< end parameter used for the simulation + double minValue_; ///< minimum value for the critical time + double maxValue_; ///< maximum value for the critical time +}; + +} // namespace DYNAlgorithms + +#endif // COMMON_DYNCRITICALTIMECALCULATION_H_ diff --git a/sources/Common/DYNSimulationResult.cpp b/sources/Common/DYNSimulationResult.cpp index f54a15bb..8c209ef4 100644 --- a/sources/Common/DYNSimulationResult.cpp +++ b/sources/Common/DYNSimulationResult.cpp @@ -88,6 +88,16 @@ SimulationResult::setStatus(status_t status) { status_ = status; } +void +SimulationResult::setCriticalTimeMessageError(const std::string& messageCriticalTimeError) { + messageCriticalTimeError_ = messageCriticalTimeError; +} + +const std::string& +SimulationResult::getCriticalTimeMessageError() const { + return messageCriticalTimeError_; +} + std::stringstream& SimulationResult::getTimelineStream() { return timelineStream_; diff --git a/sources/Common/DYNSimulationResult.h b/sources/Common/DYNSimulationResult.h index f5b2b72e..04e04fab 100644 --- a/sources/Common/DYNSimulationResult.h +++ b/sources/Common/DYNSimulationResult.h @@ -83,6 +83,17 @@ class SimulationResult { */ void setStatus(status_t status); + /** + * @brief set the message error of the last simulation failed + * @param message the message error + */ + void setCriticalTimeMessageError(const std::string& messageCriticalTimeError); + + /** + * @brief get the message error of the last simulation failed + */ + const std::string& getCriticalTimeMessageError() const; + /** * @brief getter of the timeline stream associated to the scenario * @return timeline stream associated to the scenario @@ -217,6 +228,7 @@ class SimulationResult { std::string timelineFileExtension_; ///< timeline export mode for this result std::string constraintsFileExtension_; ///< constraints export mode for this result std::string logPath_; ///< Path to the general dynawo log file associated to this result + std::string messageCriticalTimeError_; ///< message of the last simulation failed. }; } // namespace DYNAlgorithms diff --git a/sources/Common/Dictionaries/DYNAlgorithmsError_en_GB.dic b/sources/Common/Dictionaries/DYNAlgorithmsError_en_GB.dic index 0adc51ba..46962166 100644 --- a/sources/Common/Dictionaries/DYNAlgorithmsError_en_GB.dic +++ b/sources/Common/Dictionaries/DYNAlgorithmsError_en_GB.dic @@ -18,3 +18,5 @@ DirectoryDoesNotExist = directory : %1% does not exist XmlParsingError = error while parsing file %1% : %2% IncoherentAccuracy = accuracy of margin calculation should be a number between 1 and 100 (found : %1%) InputFileFormatNotSupported = input file should be either a zip or a xml file (found %1%) +CriticalTimeCalculationTaskNotFound = criticalTimeCalculation task not found in input files +IncoherentAccuracyCriticalTime = accuracy of critical time calculation should be a number between 0 and 1 (found : %1%) diff --git a/sources/Common/test/TestBaseClasses.cpp b/sources/Common/test/TestBaseClasses.cpp index 9480dcf1..f9af6a22 100644 --- a/sources/Common/test/TestBaseClasses.cpp +++ b/sources/Common/test/TestBaseClasses.cpp @@ -17,6 +17,7 @@ #include "DYNScenario.h" #include "DYNScenarios.h" #include "DYNMarginCalculation.h" +#include "DYNCriticalTimeCalculation.h" #include "DYNSimulationResult.h" #include "DYNLoadIncreaseResult.h" #include "MacrosMessage.h" @@ -103,6 +104,25 @@ TEST(TestBaseClasses, testMarginCalculation) { ASSERT_THROW_DYNAWO(mc.setAccuracy(0), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::IncoherentAccuracy); } +TEST(TestBaseClasses, testCriticalTimeCalculation) { + CriticalTimeCalculation ct; + ct.setAccuracy(0.01); + ct.setJobsFile("Myjobs.jobs"); + ct.setDydId("MyDydId"); + ct.setEndPar("MyEndPar"); + ct.setMinValue(1); + ct.setMaxValue(2); + ASSERT_EQ(ct.getAccuracy(), 0.01); + ASSERT_EQ(ct.getJobsFile(), "Myjobs.jobs"); + ASSERT_EQ(ct.getDydId(), "MyDydId"); + ASSERT_EQ(ct.getEndPar(), "MyEndPar"); + ASSERT_EQ(ct.getMinValue(), 1); + ASSERT_EQ(ct.getMaxValue(), 2); + + ASSERT_THROW_DYNAWO(ct.setAccuracy(-1), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::IncoherentAccuracyCriticalTime); + ASSERT_THROW_DYNAWO(ct.setAccuracy(2), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::IncoherentAccuracyCriticalTime); +} + TEST(TestBaseClasses, testSimulationResult) { SimulationResult sr; ASSERT_TRUE(sr.getScenarioId().empty()); @@ -173,5 +193,4 @@ TEST(TestBaseClasses, testLoadIncreaseResult) { ASSERT_FALSE(test2.getSuccess()); ASSERT_EQ(test2.getStatus(), CRITERIA_NON_RESPECTED_STATUS); } - } // namespace DYNAlgorithms diff --git a/sources/Launcher/CMakeLists.txt b/sources/Launcher/CMakeLists.txt index fcc75ec4..bb4f6a90 100644 --- a/sources/Launcher/CMakeLists.txt +++ b/sources/Launcher/CMakeLists.txt @@ -16,6 +16,7 @@ set(DYN_ALGO_LAUNCHER_SOURCES DYNMarginCalculationLauncher.cpp DYNRobustnessAnalysisLauncher.cpp DYNMultiVariantInputs.cpp + DYNCriticalTimeLauncher.cpp ) set(DYN_ALGO_LAUNCHER_HEADERS @@ -25,6 +26,7 @@ set(DYN_ALGO_LAUNCHER_HEADERS DYNMarginCalculationLauncher.h DYNRobustnessAnalysisLauncher.h DYNMultiVariantInputs.h + DYNCriticalTimeLauncher.h ) add_library(dynawo_algorithms_Launcher SHARED ${DYN_ALGO_LAUNCHER_SOURCES}) diff --git a/sources/Launcher/DYNCriticalTimeLauncher.cpp b/sources/Launcher/DYNCriticalTimeLauncher.cpp new file mode 100644 index 00000000..ab69f1b7 --- /dev/null +++ b/sources/Launcher/DYNCriticalTimeLauncher.cpp @@ -0,0 +1,122 @@ +// +// Copyright (c) 2021, RTE (http://www.rte-france.com) +// See AUTHORS.txt +// All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, you can obtain one at http://mozilla.org/MPL/2.0/. +// SPDX-License-Identifier: MPL-2.0 +// +// This file is part of Dynawo, an hybrid C++/Modelica open source suite +// of simulation tools for power systems. +// + +/** + * @file CriticalTimeLauncher.cpp + * + * @brief Critical Time launcher: implementation of the algorithm and interaction with dynawo core + * + */ + +#ifdef WITH_OPENMP +#include +#endif + +#include +#include +#include +#include +#include "DYNCriticalTimeLauncher.h" +#include "DYNMultipleJobs.h" +#include "DYNAggrResXmlExporter.h" +#include "MacrosMessage.h" + +using multipleJobs::MultipleJobs; + +namespace DYNAlgorithms { + +void +CriticalTimeLauncher::setParametersAndLaunchSimulation() { + inputs_.readInputs(workingDirectory_, jobsFile_); + boost::shared_ptr job = inputs_.cloneJobEntry(); + SimulationParameters params; + boost::shared_ptr simulation = createAndInitSimulation(workingDirectory_, job, params, results_, inputs_); + + if (simulation) { + boost::shared_ptr modelMulti = boost::dynamic_pointer_cast(simulation->getModel()); + + const std::string& dydId = criticalTimeCalculation_->getDydId(); + const std::string& endPar = criticalTimeCalculation_->getEndPar(); + + if (modelMulti->findSubModelByName(dydId) != NULL) { + subModel_ = modelMulti->findSubModelByName(dydId); + subModel_->setParameterValue(endPar, DYN::PAR, tSup_, false); + subModel_->setSubModelParameters(); + } + simulate(simulation, results_); + } +} + +void +CriticalTimeLauncher::updateIndexes(double& tPrevious, double& curAccuracy, const double& multiplierRound) { + curAccuracy = std::abs(tSup_ - tPrevious); + double midDichotomy = std::round((std::abs(tSup_ - tPrevious) / 2) * multiplierRound) / multiplierRound; + double tmp = tSup_; + + if (results_.getSuccess()) + tSup_ += midDichotomy; + else + tSup_ -= midDichotomy; + + tPrevious = tmp; +} + +void +CriticalTimeLauncher::launch() { + criticalTimeCalculation_ = multipleJobs_->getCriticalTimeCalculation(); + if (!criticalTimeCalculation_) + throw DYNAlgorithmsError(CriticalTimeCalculationTaskNotFound); + + const double accuracy = criticalTimeCalculation_->getAccuracy(); + double curAccuracy = 1.; + const double multiplierRound = 1. / accuracy; + + tSup_ = criticalTimeCalculation_->getMaxValue(); + jobsFile_ = criticalTimeCalculation_->getJobsFile(); + const double tInf = criticalTimeCalculation_->getMinValue(); + double tPrevious = tSup_; + + // First simulation case. + setParametersAndLaunchSimulation(); + if (results_.getSuccess()) + return; + else + tSup_ -= std::round(((tSup_ - tInf) / 2.) * multiplierRound) / multiplierRound; + + while (curAccuracy > accuracy) { + setParametersAndLaunchSimulation(); + updateIndexes(tPrevious, curAccuracy, multiplierRound); + } + + // Check if the final result is calculated with a failed simulation + if (!results_.getSuccess()) + tSup_ -= accuracy; + + tSup_ = std::round(tSup_ * multiplierRound) / multiplierRound;; +} + +void +CriticalTimeLauncher::createOutputs(std::map& mapData, bool zipIt) const { + aggregatedResults::XmlExporter exporter; + if (zipIt) { + std::stringstream aggregatedResults; + exporter.exportCriticalTimeResultsToStream(tSup_, results_.getCriticalTimeMessageError(), aggregatedResults); + mapData["aggregatedResults.xml"] = aggregatedResults.str(); + storeOutputs(results_, mapData); + } else { + exporter.exportCriticalTimeResultsToFile(tSup_, results_.getCriticalTimeMessageError(), outputFileFullPath_); + writeOutputs(results_); + } +} + +} // namespace DYNAlgorithms diff --git a/sources/Launcher/DYNCriticalTimeLauncher.h b/sources/Launcher/DYNCriticalTimeLauncher.h new file mode 100644 index 00000000..f2c0a11d --- /dev/null +++ b/sources/Launcher/DYNCriticalTimeLauncher.h @@ -0,0 +1,80 @@ +// +// Copyright (c) 2021, RTE (http://www.rte-france.com) +// See AUTHORS.txt +// All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, you can obtain one at http://mozilla.org/MPL/2.0/. +// SPDX-License-Identifier: MPL-2.0 +// +// This file is part of Dynawo, an hybrid C++/Modelica open source suite +// of simulation tools for power systems. +// + +/** + * @file DYNMarginCriticalimeLauncher.h + * + * @brief CriticalTime algorithm launcher: header file + * + */ + +#ifndef LAUNCHER_DYNCRITICALTIMELAUNCHER_H_ +#define LAUNCHER_DYNCRITICALTIMELAUNCHER_H_ + +#include +#include +#include +#include +#include "DYNRobustnessAnalysisLauncher.h" +#include "DYNCriticalTimeCalculation.h" +#include "DYNError.h" + +namespace DYNAlgorithms { +class SimulationResults; +class CriticalTimeCalculation; +/** + * @brief Critical Time Calculation launcher class + * + * Class for critical time calculation launched by cvg + */ +class CriticalTimeLauncher : public RobustnessAnalysisLauncher { + public: + /** + * @brief Search critical time with a specific default in the simulation. We follow + * dichotomy's algorithm to find it. + */ + void launch(); + + /** + * @brief Launch the simulation with the new value calculted in the critical + * time algorithm + */ + void setParametersAndLaunchSimulation(); + + /** + * @brief Update superior born to find the right critical time + * and calcul the next time value we want to test. + * + * @param tPrevious previous value tested + * @param curAccuracy current accuracy + * @param multiplierRound value used to round results with accuracy + */ + void updateIndexes(double& tPrevious, double& curAccuracy, const double& multiplierRound); + + protected: + double tSup_; ///< value that will be updated until we find the critical time + std::string jobsFile_; ///< Job file of the simulation + SimulationResult results_; ///< results of the critical time calculation + boost::shared_ptr subModel_; ///< submodel for each simulation + boost::shared_ptr criticalTimeCalculation_; ///< critical time calculation + + private: + /** + * @copydoc RobustnessAnalysisLauncher::createOutputs() + */ + void createOutputs(std::map& mapData, bool zipIt) const; +}; +} // namespace DYNAlgorithms + + +#endif // LAUNCHER_DYNCRITICALTIMELAUNCHER_H_ diff --git a/sources/Launcher/DYNRobustnessAnalysisLauncher.cpp b/sources/Launcher/DYNRobustnessAnalysisLauncher.cpp index 0a075509..2c16e14c 100644 --- a/sources/Launcher/DYNRobustnessAnalysisLauncher.cpp +++ b/sources/Launcher/DYNRobustnessAnalysisLauncher.cpp @@ -402,6 +402,11 @@ RobustnessAnalysisLauncher::simulate(const boost::shared_ptr& s } catch (const DYN::MessageError& m) { std::cerr << m.what() << std::endl; Trace::error() << m.what() << Trace::endline; + + std::string m_str(m.what()); + std::replace(m_str.begin(), m_str.end(), '\n', ' '); + result.setCriticalTimeMessageError(m_str); + simulation->terminate(); result.setSuccess(false); result.setStatus(EXECUTION_PROBLEM_STATUS); diff --git a/sources/Launcher/test/TestRobustnessAnalysisLauncher.cpp b/sources/Launcher/test/TestRobustnessAnalysisLauncher.cpp index faaad04b..7a5c54f9 100644 --- a/sources/Launcher/test/TestRobustnessAnalysisLauncher.cpp +++ b/sources/Launcher/test/TestRobustnessAnalysisLauncher.cpp @@ -30,6 +30,7 @@ #include "MacrosMessage.h" #include "DYNMultipleJobs.h" #include "DYNMarginCalculation.h" +#include "DYNCriticalTimeCalculation.h" testing::Environment* initXmlEnvironment(); @@ -76,6 +77,25 @@ class MyLauncher : public RobustnessAnalysisLauncher { ASSERT_TRUE(exists("res/logs/log_MyScenario.log")); } + void launchCriticalTime() { + inputs_.readInputs(workingDirectory_, "MyJobs.jobs"); + boost::shared_ptr job = inputs_.cloneJobEntry(); + + SimulationParameters params; + boost::shared_ptr simu = createAndInitSimulation("res/CriticalTime", job, params, result_, inputs_); + ASSERT_TRUE(simu); + status_t status = simulate(simu, result_); + ASSERT_EQ(status, CONVERGENCE_STATUS); + ASSERT_EQ(result_.getStatus(), CONVERGENCE_STATUS); + ASSERT_TRUE(result_.getSuccess()); + + writeResults(); + ASSERT_TRUE(exists("res/CriticalTime/MyOutputFile.zip")); + + writeResults(); + ASSERT_TRUE(exists("res/CriticalTime/MyOutputFile.zip")); + } + void testInputFile(const std::string& inputFile) { ASSERT_EQ(inputFile_, inputFile); } @@ -116,6 +136,20 @@ class MyLauncher : public RobustnessAnalysisLauncher { ASSERT_EQ(mc->getScenarios()->getJobsFile(), "myScenarios.jobs"); } + void testMultipleJobsCriticalTime() { + assert(multipleJobs_); + assert(!multipleJobs_->getScenarios()); + assert(!multipleJobs_->getMarginCalculation()); + assert(multipleJobs_->getCriticalTimeCalculation()); + boost::shared_ptr ct = multipleJobs_->getCriticalTimeCalculation(); + ASSERT_EQ(ct->getAccuracy(), 0.001); + ASSERT_EQ(ct->getJobsFile(), "MyJobs.jobs"); + ASSERT_EQ(ct->getDydId(), "FAULT_GEN_1"); + ASSERT_EQ(ct->getEndPar(), "fault_tEnd"); + ASSERT_EQ(ct->getMinValue(), 1); + ASSERT_EQ(ct->getMaxValue(), 1.620); + } + protected: void createOutputs(std::map& mapData, bool) const { storeOutputs(result_, mapData); @@ -171,5 +205,48 @@ TEST(TestLauncher, TestRobustnessAnalysisLauncher) { launcher.launch(); } +TEST(TestLauncher, TestRobustnessAnalysisLauncherWithCriticalTime) { + MyLauncher launcher; + + launcher.testInputFile(""); + launcher.setInputFile("/home/MyInputFile"); + launcher.testInputFile("/home/MyInputFile"); + + launcher.testOutputFile(""); + launcher.setOutputFile("MyOutputFile"); + launcher.testOutputFile("MyOutputFile"); + + launcher.testDirectory(""); + launcher.setDirectory("MyDirectory"); + launcher.testDirectory("MyDirectory"); + + ASSERT_THROW_DYNAWO(launcher.init(), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::DirectoryDoesNotExist); + launcher.testWorkingDirectory(createAbsolutePath("MyDirectory", current_path())); + + launcher.setDirectory("/home/MyDirectory"); + ASSERT_THROW_DYNAWO(launcher.init(), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::DirectoryDoesNotExist); + launcher.testWorkingDirectory("/home/MyDirectory"); + + launcher.setDirectory(""); + ASSERT_THROW_DYNAWO(launcher.init(), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::FileDoesNotExist); + launcher.testWorkingDirectory(current_path()+"/"); + + launcher.setInputFile("res/MyDummyInputFile.xml"); + ASSERT_THROW_DYNAWO(launcher.init(), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::FileDoesNotExist); + + launcher.setInputFile("res/MyInputFile.txt"); + ASSERT_THROW_DYNAWO(launcher.init(), DYN::Error::GENERAL, DYNAlgorithms::KeyAlgorithmsError_t::InputFileFormatNotSupported); + + boost::shared_ptr archive = zip::ZipFileFactory::newInstance(); + archive->addEntry("res/CriticalTime/fic_MULTIPLE.xml"); + zip::ZipOutputStream::write("res/CriticalTime/MyInputFile.zip", archive); + launcher.setInputFile("MyInputFile.zip"); + launcher.setDirectory("res/CriticalTime"); + launcher.setOutputFile("MyOutputFile.zip"); + ASSERT_NO_THROW(launcher.init()); + launcher.testOutputFileFullPath(createAbsolutePath("res/CriticalTime/MyOutputFile.zip", current_path())); + launcher.testMultipleJobsCriticalTime(); + launcher.launchCriticalTime(); +} } // namespace DYNAlgorithms diff --git a/sources/Launcher/test/res/CriticalTime/MyCrv.crv b/sources/Launcher/test/res/CriticalTime/MyCrv.crv new file mode 100644 index 00000000..3f726487 --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/MyCrv.crv @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/Launcher/test/res/CriticalTime/MyDyd.dyd b/sources/Launcher/test/res/CriticalTime/MyDyd.dyd new file mode 100644 index 00000000..4c86e303 --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/MyDyd.dyd @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/Launcher/test/res/CriticalTime/MyIidm.iidm b/sources/Launcher/test/res/CriticalTime/MyIidm.iidm new file mode 100644 index 00000000..1ec775cf --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/MyIidm.iidm @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/Launcher/test/res/CriticalTime/MyJobs.jobs b/sources/Launcher/test/res/CriticalTime/MyJobs.jobs new file mode 100644 index 00000000..0c56d281 --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/MyJobs.jobs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/sources/Launcher/test/res/CriticalTime/MyPar.par b/sources/Launcher/test/res/CriticalTime/MyPar.par new file mode 100644 index 00000000..27a25aa1 --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/MyPar.par @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/Launcher/test/res/CriticalTime/fic_MULTIPLE.xml b/sources/Launcher/test/res/CriticalTime/fic_MULTIPLE.xml new file mode 100644 index 00000000..49242d0f --- /dev/null +++ b/sources/Launcher/test/res/CriticalTime/fic_MULTIPLE.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/sources/dynawo-algorithms.sh b/sources/dynawo-algorithms.sh index 8a41b221..8d0e7f9b 100755 --- a/sources/dynawo-algorithms.sh +++ b/sources/dynawo-algorithms.sh @@ -49,6 +49,7 @@ where [option] can be: CS ([args]) call Dynawo's launcher with given arguments setting LD_LIBRARY_PATH correctly SA ([args]) call a dynamic systematic analysis MC ([args]) call a margin calculation + CTC ([args]) call a critical time calculation --version show Dynawo version --help show this message" @@ -196,6 +197,33 @@ algo_SA() { return ${RETURN_CODE} } +algo_CTC() { + setEnv + + # launch critical time calculation + $DYNAWO_ALGORITHMS_INSTALL_DIR/bin/dynawoAlgorithms --simulationType=CTC $@ + RETURN_CODE=$? + + while (($#)); do + case $1 in + --input) + if [ ! -z "$2" ]; then + if [ -f "$2" ]; then + filter_timeline `dirname $2` + fi + fi + break + ;; + *) + shift + break + ;; + esac + done + + return ${RETURN_CODE} +} + if [ $# -eq 0 ]; then echo "$usage" exit 1 diff --git a/sources/main.cpp b/sources/main.cpp index ebe5616e..e9bd5025 100644 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -31,11 +31,13 @@ #include "DYNComputeLoadVariationLauncher.h" #include "DYNComputeSimulationLauncher.h" #include "DYNMPIContext.h" +#include "DYNCriticalTimeLauncher.h" using DYNAlgorithms::ComputeSimulationLauncher; using DYNAlgorithms::SystematicAnalysisLauncher; using DYNAlgorithms::MarginCalculationLauncher; using DYNAlgorithms::ComputeLoadVariationLauncher; +using DYNAlgorithms::CriticalTimeLauncher; namespace po = boost::program_options; @@ -43,6 +45,7 @@ static void launchSimulation(const std::string& jobFile, const std::string& outp static void launchMarginCalculation(const std::string& inputFile, const std::string& outputFile, const std::string& directory); static void launchSystematicAnalysis(const std::string& inputFile, const std::string& outputFile, const std::string& directory); static void launchLoadVariationCalculation(const std::string& inputFile, const std::string& outputFile, const std::string& directory, int variation); +static void launchCriticalTimeCalculation(const std::string& inputFile, const std::string& outputFile, const std::string& directory); int main(int argc, char** argv) { DYNAlgorithms::mpi::Context& mpiContext = DYNAlgorithms::mpi::context(); @@ -50,6 +53,11 @@ int main(int argc, char** argv) { std::string simulationType = ""; std::string inputFile = ""; std::string outputFile = ""; + + std::string simulationMC_SA_CS_CTC = "Set the simulation type to launch : MC (Margin calculation), SA (systematic analysis), CS (compute simulation)" + " or CTC (critical time calculation)"; + const char* allSimulationsType = simulationMC_SA_CS_CTC.c_str(); + std::vector directoryVec; int variation = -1; try { @@ -59,7 +67,7 @@ int main(int argc, char** argv) { desc.add_options() ("help,h", "Produce help message") ("simulationType", po::value(&simulationType)->required(), - "Set the simulation type to launch : MC (Margin calculation), SA (systematic analysis) or CS (compute simulation)") + allSimulationsType) ("input", po::value(&inputFile)->required(), "Set the input file of the simulation (*.zip or *.xml)") ("output", po::value(&outputFile), @@ -95,14 +103,14 @@ int main(int argc, char** argv) { } // launch simulation - if (simulationType != "MC" && simulationType != "SA" && simulationType != "CS") { + if (simulationType != "MC" && simulationType != "SA" && simulationType != "CS" && simulationType != "CTC") { std::cout << simulationType << " : unknown simulation type" << std::endl; std::cout << desc << std::endl; return 1; } - if ((simulationType == "SA" || simulationType == "MC") && outputFile == "") { - std::cout << "An output file. (*.zip or *.xml) is required for SA and MC simulations." << std::endl; + if ((simulationType == "SA" || simulationType == "MC" || simulationType == "CTC") && outputFile == "") { + std::cout << "An output file. (*.zip or *.xml) is required for SA, MC and CTC simulations." << std::endl; std::cout << desc << std::endl; return 1; } @@ -123,6 +131,8 @@ int main(int argc, char** argv) { launchSystematicAnalysis(inputFile, outputFile, directory); } else if (simulationType == "CS") { launchSimulation(inputFile, outputFile); + } else if (simulationType == "CTC") { + launchCriticalTimeCalculation(inputFile, outputFile, directory); } } catch (const char *s) { std::cerr << s << std::endl; @@ -195,3 +205,15 @@ void launchSystematicAnalysis(const std::string& inputFile, const std::string& o analysisLauncher->launch(); analysisLauncher->writeResults(); } + +void launchCriticalTimeCalculation(const std::string& inputFile, const std::string& outputFile, const std::string& directory) { + boost::shared_ptr criticalTimeLauncher = boost::shared_ptr(new CriticalTimeLauncher()); + criticalTimeLauncher->setInputFile(inputFile); + criticalTimeLauncher->setOutputFile(outputFile); + criticalTimeLauncher->setDirectory(directory); + + const bool initLog = true; + criticalTimeLauncher->init(initLog); + criticalTimeLauncher->launch(); + criticalTimeLauncher->writeResults(); +} diff --git a/util/envDynawoAlgorithms.sh b/util/envDynawoAlgorithms.sh index dde5ff03..d7cb442f 100755 --- a/util/envDynawoAlgorithms.sh +++ b/util/envDynawoAlgorithms.sh @@ -51,13 +51,15 @@ where [option] can be: SA ([args]) launch a systematic analysis MC ([args]) launch a margin calculation CS ([args]) launch a simple Dynawo simulation + CTC ([args]) launch a critical time calculation =========== Tests nrt ([-p regex] [-n name_filter]) run (filtered) non-regression tests and open the result in chosen browser version-validation clean all built items, then build them all SA-gdb ([args]) launch a systematic analysis with gdb MC-gdb ([args]) launch a margin calculation with gdb - CS-gdb ([args]) launch a simple Dynawo simulationwith gdb + CS-gdb ([args]) launch a simple Dynawo simulation with gdb + CTC-gdb ([args]) launch a critical time calculation with gdb build-tests build and launch dynawo-algorithms's unittest build-tests-coverage build/launch dynawo-algorithms's unittest and generate code coverage report unittest-gdb [arg] call unittest in gdb @@ -1011,6 +1013,12 @@ launch_MC() { return ${RETURN_CODE} } +launch_CTC() { + $DYNAWO_ALGORITHMS_INSTALL_DIR/bin/dynawoAlgorithms --simulationType CTC $@ + RETURN_CODE=$? + return ${RETURN_CODE} +} + launch_CS_gdb() { gdb -q --args $DYNAWO_ALGORITHMS_INSTALL_DIR/bin/dynawoAlgorithms --simulationType CS $@ RETURN_CODE=$? @@ -1033,6 +1041,12 @@ launch_MC_gdb() { return ${RETURN_CODE} } +launch_CTC_gdb() { + gdb -q --args $DYNAWO_ALGORITHMS_INSTALL_DIR/bin/dynawoAlgorithms --simulationType CTC $@ + RETURN_CODE=$? + return ${RETURN_CODE} +} + ################################# ########### Main script ######### if [ -n "$BASH_VERSION" ]; then @@ -1170,6 +1184,9 @@ case $MODE in CS) launch_CS ${ARGS} || error_exit "Dynawo simulation failed" ;; + CTC) + launch_CTC ${ARGS} || error_exit "Critical time calculation failed" + ;; SA-gdb) launch_SA_gdb ${ARGS} || error_exit "Systematic analysis failed" ;; @@ -1182,6 +1199,9 @@ case $MODE in launch_CS_gdb ${ARGS} || error_exit "Dynawo simulation failed" ;; + CTC-gdb) + launch_CTC_gdb ${ARGS} || error_exit "Critical time calculation failed" + ;; nrt) nrt ${ARGS} || error_exit "Error during Dynawo's non regression tests execution" ;;