From dea29db6082bfafa02bac164eefc43979d463fc9 Mon Sep 17 00:00:00 2001 From: Guillaume PIERRE Date: Tue, 2 Jul 2024 13:48:10 +0200 Subject: [PATCH 1/2] Fix infeasible analyzer : several corrections --- .../constraint.cpp | 27 +++++-------- .../constraint-slack-analysis.h | 3 +- .../infeasible-problem-analysis/constraint.h | 1 + .../infeasible-problem-analysis/report.h | 6 +-- .../infeasible-problem-analysis/report.cpp | 38 +++++++++---------- .../antares/solver/simulation/solver.hxx | 6 +-- 6 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 0e95848ad9..8c6ba4ea03 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include namespace { @@ -40,24 +42,7 @@ Constraint::Constraint(const std::string& input, const double slackValue): std::size_t Constraint::extractItems() { - const auto beg = mInput.begin(); - const auto end = mInput.end(); - std::size_t newPos = 0; - const std::size_t sepSize = 2; - const std::size_t inputSize = mInput.size(); - for (std::size_t pos = 0; pos < inputSize; pos = newPos + sepSize) - { - newPos = mInput.find("::", pos); - if (newPos == std::string::npos) - { - mItems.emplace_back(beg + pos, end); - break; - } - if (newPos > pos) - { - mItems.emplace_back(beg + pos, beg + newPos); - } - } + boost::algorithm::split_regex(mItems, mInput, boost::regex("::")); return mItems.size(); } @@ -158,6 +143,10 @@ ConstraintType Constraint::getType() const { return ConstraintType::hydro_reservoir_level; } + if (mItems.at(0) == "HydroPower") + { + return ConstraintType::hydro_production_weekly; + } if (mItems.at(0) == "Level") { return ConstraintType::short_term_storage_level; @@ -209,6 +198,8 @@ std::string Constraint::prettyPrint() const case ConstraintType::hydro_reservoir_level: return "Hydro reservoir constraint at area '" + getAreaName() + "' at hour " + getTimeStepInYear(); + case ConstraintType::hydro_production_weekly: + return "Hydro weekly production at area '" + getAreaName() + "'"; case ConstraintType::short_term_storage_level: return "Short-term-storage reservoir constraint at area '" + getAreaName() + "' in STS '" + getSTSName() + "' at hour " + getTimeStepInYear(); diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h index a298b6b026..bb56228b2f 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint-slack-analysis.h @@ -57,7 +57,8 @@ class ConstraintSlackAnalysis: public UnfeasibilityAnalysis std::vector slackVariables_; const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly::|" - "^FictiveLoads::|^Level::"; + "^FictiveLoads::|^Level::|" + "^HydroPower::"; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h index aba82e7f21..4de1bac328 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h @@ -32,6 +32,7 @@ enum class ConstraintType binding_constraint_weekly, fictitious_load, hydro_reservoir_level, + hydro_production_weekly, short_term_storage_level, none }; diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index 6ebb919fb1..2939f86081 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -49,8 +49,8 @@ class InfeasibleProblemReport void extractItems(); void logSuspiciousConstraints(); - std::vector mConstraints; - std::map mTypes; - const unsigned int nbVariables = 10; + std::vector constraints_; + std::map nbConstraintsByType_; + const unsigned int nbMaxVariables = 10; }; } // namespace Antares::Optimization diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index 28e72109bf..c23d72f5ea 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -40,7 +40,7 @@ static bool compareSlackSolutions(const Antares::Optimization::Constraint& a, namespace Antares::Optimization { InfeasibleProblemReport::InfeasibleProblemReport( - const std::vector& slackVariables) + const std::vector& slackVariables) { turnSlackVarsIntoConstraints(slackVariables); sortConstraints(); @@ -48,72 +48,72 @@ InfeasibleProblemReport::InfeasibleProblemReport( } void InfeasibleProblemReport::turnSlackVarsIntoConstraints( - const std::vector& slackVariables) + const std::vector& slackVariables) { for (const MPVariable* slack: slackVariables) { - mConstraints.emplace_back(slack->name(), slack->solution_value()); + constraints_.emplace_back(slack->name(), slack->solution_value()); } } void InfeasibleProblemReport::sortConstraints() { - std::sort(std::begin(mConstraints), std::end(mConstraints), ::compareSlackSolutions); + std::sort(std::begin(constraints_), std::end(constraints_), ::compareSlackSolutions); } void InfeasibleProblemReport::trimConstraints() { - if (nbVariables <= mConstraints.size()) - { - mConstraints.resize(nbVariables); - } + unsigned int nbConstraints = constraints_.size(); + constraints_.resize(std::min(nbMaxVariables, nbConstraints)); } void InfeasibleProblemReport::extractItems() { - for (auto& c: mConstraints) + for (auto& c: constraints_) { if (c.extractItems() == 0) { return; } - mTypes[c.getType()]++; + nbConstraintsByType_[c.getType()]++; } } void InfeasibleProblemReport::logSuspiciousConstraints() { Antares::logs.error() << "The following constraints are suspicious (first = most suspicious)"; - for (const auto& c: mConstraints) + for (const auto& c: constraints_) { Antares::logs.error() << c.prettyPrint(); } Antares::logs.error() << "Possible causes of infeasibility:"; - if (mTypes[ConstraintType::hydro_reservoir_level] > 0) + if (nbConstraintsByType_[ConstraintType::hydro_reservoir_level] > 0) { Antares::logs.error() << "* Hydro reservoir impossible to manage with cumulative options " "\"hard bounds without heuristic\""; } - if (mTypes[ConstraintType::fictitious_load] > 0) + if (nbConstraintsByType_[ConstraintType::hydro_production_weekly] > 0) + { + Antares::logs.error() << "* impossible to generate exactly the weekly hydro target"; + } + if (nbConstraintsByType_[ConstraintType::fictitious_load] > 0) { Antares::logs.error() << "* Last resort shedding status,"; } - if (mTypes[ConstraintType::short_term_storage_level] > 0) + if (nbConstraintsByType_[ConstraintType::short_term_storage_level] > 0) { Antares::logs.error() << "* Short-term storage reservoir level impossible to manage. Please check inflows, " "lower & upper curves and initial level (if prescribed),"; } - const unsigned int bcCount = mTypes[ConstraintType::binding_constraint_hourly] - + mTypes[ConstraintType::binding_constraint_daily] - + mTypes[ConstraintType::binding_constraint_weekly]; + const unsigned int bcCount = nbConstraintsByType_[ConstraintType::binding_constraint_hourly] + + nbConstraintsByType_[ConstraintType::binding_constraint_daily] + + nbConstraintsByType_[ConstraintType::binding_constraint_weekly]; if (bcCount > 0) { Antares::logs.error() << "* Binding constraints,"; } - - Antares::logs.error() << "* Negative hurdle costs on lines with infinite capacity (rare)."; } void InfeasibleProblemReport::prettyPrint() diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 093cb1e350..e545fc3bf8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -321,6 +321,9 @@ void ISimulation::run() } else { + // Export ts-numbers into output + TimeSeriesNumbers::StoreTimeSeriesNumbersIntoOuput(study, pResultWriter); + if (not ImplementationType::simulationBegin()) { return; @@ -358,9 +361,6 @@ void ISimulation::run() ImplementationType::variables.simulationEnd(); - // Export ts-numbers into output - TimeSeriesNumbers::StoreTimeSeriesNumbersIntoOuput(study, pResultWriter); - // Spatial clusters // Notifying all variables to perform the final spatial clusters. // This must be done only when all variables have finished to compute their From 23394ed67c1e130da902fe4ea3c5c8f4a6054e09 Mon Sep 17 00:00:00 2001 From: Guillaume PIERRE Date: Tue, 2 Jul 2024 15:08:43 +0200 Subject: [PATCH 2/2] [skip ci] Fix infeasible analyzer : renaming --- .../constraint.cpp | 38 +++++++++---------- .../infeasible-problem-analysis/constraint.h | 8 ++-- .../infeasible-problem-analysis/report.h | 2 +- .../infeasible-problem-analysis/report.cpp | 6 +-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/solver/infeasible-problem-analysis/constraint.cpp b/src/solver/infeasible-problem-analysis/constraint.cpp index 8c6ba4ea03..86033e141c 100644 --- a/src/solver/infeasible-problem-analysis/constraint.cpp +++ b/src/solver/infeasible-problem-analysis/constraint.cpp @@ -34,21 +34,21 @@ const std::string kUnknown = ""; namespace Antares::Optimization { -Constraint::Constraint(const std::string& input, const double slackValue): - mInput(input), - mSlackValue(slackValue) +Constraint::Constraint(const std::string& name, const double slackValue): + name_(name), + slackValue_(slackValue) { } -std::size_t Constraint::extractItems() +std::size_t Constraint::extractComponentsFromName() { - boost::algorithm::split_regex(mItems, mInput, boost::regex("::")); - return mItems.size(); + boost::algorithm::split_regex(nameComponents_, name_, boost::regex("::")); + return nameComponents_.size(); } double Constraint::getSlackValue() const { - return mSlackValue; + return slackValue_; } class StringIsNotWellFormated: public std::runtime_error @@ -102,7 +102,7 @@ std::string Constraint::getAreaName() const { return ""; } - return StringBetweenAngleBrackets(mItems.at(1)); + return StringBetweenAngleBrackets(nameComponents_.at(1)); } std::string Constraint::getTimeStepInYear() const @@ -114,7 +114,7 @@ std::string Constraint::getTimeStepInYear() const case ConstraintType::fictitious_load: case ConstraintType::hydro_reservoir_level: case ConstraintType::short_term_storage_level: - return StringBetweenAngleBrackets(mItems.at(mItems.size() - 2)); + return StringBetweenAngleBrackets(nameComponents_.at(nameComponents_.size() - 2)); default: return kUnknown; } @@ -122,32 +122,32 @@ std::string Constraint::getTimeStepInYear() const ConstraintType Constraint::getType() const { - assert(mItems.size() > 1); - if (mItems.at(1) == "hourly") + assert(nameComponents_.size() > 1); + if (nameComponents_.at(1) == "hourly") { return ConstraintType::binding_constraint_hourly; } - if (mItems.at(1) == "daily") + if (nameComponents_.at(1) == "daily") { return ConstraintType::binding_constraint_daily; } - if (mItems.at(1) == "weekly") + if (nameComponents_.at(1) == "weekly") { return ConstraintType::binding_constraint_weekly; } - if (mItems.at(0) == "FictiveLoads") + if (nameComponents_.at(0) == "FictiveLoads") { return ConstraintType::fictitious_load; } - if (mItems.at(0) == "AreaHydroLevel") + if (nameComponents_.at(0) == "AreaHydroLevel") { return ConstraintType::hydro_reservoir_level; } - if (mItems.at(0) == "HydroPower") + if (nameComponents_.at(0) == "HydroPower") { return ConstraintType::hydro_production_weekly; } - if (mItems.at(0) == "Level") + if (nameComponents_.at(0) == "Level") { return ConstraintType::short_term_storage_level; } @@ -161,7 +161,7 @@ std::string Constraint::getBindingConstraintName() const case ConstraintType::binding_constraint_hourly: case ConstraintType::binding_constraint_daily: case ConstraintType::binding_constraint_weekly: - return mItems.at(0); + return nameComponents_.at(0); default: return kUnknown; } @@ -171,7 +171,7 @@ std::string Constraint::getSTSName() const { if (getType() == ConstraintType::short_term_storage_level) { - return StringBetweenAngleBrackets(mItems.at(2)); + return StringBetweenAngleBrackets(nameComponents_.at(2)); } else { diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h index 4de1bac328..92bab3c87b 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/constraint.h @@ -48,14 +48,14 @@ class Constraint double getSlackValue() const; // Extract items, check consistency - std::size_t extractItems(); + std::size_t extractComponentsFromName(); std::string prettyPrint() const; ConstraintType getType() const; private: - std::string mInput; - std::vector mItems; - double mSlackValue; + std::string name_; + std::vector nameComponents_; + double slackValue_; // Get specific items std::string getAreaName() const; diff --git a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h index 2939f86081..334e09c979 100644 --- a/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h +++ b/src/solver/infeasible-problem-analysis/include/antares/solver/infeasible-problem-analysis/report.h @@ -46,7 +46,7 @@ class InfeasibleProblemReport const std::vector& slackVariables); void sortConstraints(); void trimConstraints(); - void extractItems(); + void sortConstraintsByType(); void logSuspiciousConstraints(); std::vector constraints_; diff --git a/src/solver/infeasible-problem-analysis/report.cpp b/src/solver/infeasible-problem-analysis/report.cpp index c23d72f5ea..6d16b0b605 100644 --- a/src/solver/infeasible-problem-analysis/report.cpp +++ b/src/solver/infeasible-problem-analysis/report.cpp @@ -67,11 +67,11 @@ void InfeasibleProblemReport::trimConstraints() constraints_.resize(std::min(nbMaxVariables, nbConstraints)); } -void InfeasibleProblemReport::extractItems() +void InfeasibleProblemReport::sortConstraintsByType() { for (auto& c: constraints_) { - if (c.extractItems() == 0) + if (c.extractComponentsFromName() == 0) { return; } @@ -118,7 +118,7 @@ void InfeasibleProblemReport::logSuspiciousConstraints() void InfeasibleProblemReport::prettyPrint() { - extractItems(); + sortConstraintsByType(); logSuspiciousConstraints(); }