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