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