From 11c120eaa2fcc5ec310b881f26560d1a4ca11992 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Thu, 19 Dec 2024 18:54:05 +0100 Subject: [PATCH 01/11] update --- src/libs/antares/study/CMakeLists.txt | 4 +- ...alConstraint.h => AdditionalConstraints.h} | 21 ++++++-- .../study/parts/short-term-storage/cluster.h | 4 +- .../parts/short-term-storage/container.h | 1 - .../study/parts/short-term-storage/series.h | 2 +- ...nstraint.cpp => AdditionalConstraints.cpp} | 31 +++++++---- .../parts/short-term-storage/container.cpp | 51 ++++++++++++++----- .../study/parts/short-term-storage/series.cpp | 14 ++--- .../ShortTermStorageCumulation.cpp | 34 +++++++------ .../sim_structure_probleme_economique.h | 2 +- .../simulation/sim_calcul_economique.cpp | 9 ++-- 11 files changed, 115 insertions(+), 58 deletions(-) rename src/libs/antares/study/include/antares/study/parts/short-term-storage/{AdditionalConstraint.h => AdditionalConstraints.h} (81%) rename src/libs/antares/study/parts/short-term-storage/{AdditionalConstraint.cpp => AdditionalConstraints.cpp} (67%) diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index e7336d020c..dd82930032 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -102,9 +102,9 @@ set(SRC_STUDY_PART_SHORT_TERM_STORAGE parts/short-term-storage/series.cpp include/antares/study/parts/short-term-storage/series.h include/antares/study/parts/short-term-storage/cluster.h - include/antares/study/parts/short-term-storage/AdditionalConstraint.h + include/antares/study/parts/short-term-storage/AdditionalConstraints.h parts/short-term-storage/cluster.cpp - parts/short-term-storage/AdditionalConstraint.cpp + parts/short-term-storage/AdditionalConstraints.cpp ) source_group("study\\part\\short-term-storage" FILES ${SRC_STUDY_PART_SHORT_TERM_SOTRAGE}) diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraint.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h similarity index 81% rename from src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraint.h rename to src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h index e16b991a05..7e27c9a60f 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraint.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h @@ -22,20 +22,30 @@ #pragma once #include #include +#include namespace Antares::Data::ShortTermStorage { +struct SingleAdditionalConstraint +{ + std::set hours; + unsigned int globalIndex = 0; + unsigned int localIndex = 0; + + bool isValidHoursRange() const; +}; -struct AdditionalConstraint +struct AdditionalConstraints { std::string name; std::string cluster_id; std::string variable; std::string operatorType; - std::set hours; - double rhs; + // TODO a lot unused entries + //std::array rhs = {}; + std::vector rhs = {}; - unsigned int globalIndex = 0; + std::vector constraints = {}; struct ValidateResult { @@ -48,6 +58,7 @@ struct AdditionalConstraint private: bool isValidVariable() const; bool isValidOperatorType() const; - bool isValidHoursRange() const; + + bool isValidHours() const; }; } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h index df74a350b0..c117111efe 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/cluster.h @@ -26,7 +26,7 @@ #include -#include "AdditionalConstraint.h" +#include "AdditionalConstraints.h" #include "properties.h" #include "series.h" @@ -51,6 +51,6 @@ class STStorageCluster std::shared_ptr series = std::make_shared(); mutable Properties properties; - std::vector additional_constraints; + std::vector additional_constraints; }; } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/container.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/container.h index d4e0233b5c..65dc8145bc 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/container.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/container.h @@ -23,7 +23,6 @@ #include #include -#include "AdditionalConstraint.h" #include "cluster.h" namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h index 80f90b94f2..1f53a220fe 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h @@ -63,5 +63,5 @@ class Series bool loadFile(const std::filesystem::path& folder, std::vector& vect); bool writeVectorToFile(const std::string& path, const std::vector& vect); - +void fillIfEmpty(std::vector& v, double value); } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp similarity index 67% rename from src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp rename to src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp index 2ca904041c..8775ffe561 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp @@ -18,11 +18,12 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ -#include "antares/study/parts/short-term-storage/AdditionalConstraint.h" +#include "antares/study/parts/short-term-storage/AdditionalConstraints.h" +#include namespace Antares::Data::ShortTermStorage { -AdditionalConstraint::ValidateResult AdditionalConstraint::validate() const +AdditionalConstraints::ValidateResult AdditionalConstraints::validate() const { if (cluster_id.empty()) { @@ -39,26 +40,38 @@ AdditionalConstraint::ValidateResult AdditionalConstraint::validate() const return {false, "Invalid operator type. Must be 'less', 'equal', or 'greater'."}; } - if (!isValidHoursRange()) + if (!isValidHours()) { - return {false, "Hours set contains invalid values. Must be between 1 and 168."}; + return {false, "Hours sets contains invalid values. Must be between 1 and 168."}; } return {true, ""}; } - -bool AdditionalConstraint::isValidHoursRange() const +bool SingleAdditionalConstraint::isValidHoursRange() const { // `hours` is a sorted set; begin() gives the smallest and prev(end()) gives the largest. - return !hours.empty() && *hours.begin() >= 1 && *std::prev(hours.end()) <= 168; + return !hours.empty() && *hours.begin() + >= 1 && *std::prev( + hours.end()) <= 168; } -bool AdditionalConstraint::isValidVariable() const +bool AdditionalConstraints::isValidHours() const +{ + return std::ranges::all_of(constraints.begin(), + constraints.end(), + [](const auto& constraint) + { + return constraint.isValidHoursRange(); + }); +} + + +bool AdditionalConstraints::isValidVariable() const { return variable == "injection" || variable == "withdrawal" || variable == "netting"; } -bool AdditionalConstraint::isValidOperatorType() const +bool AdditionalConstraints::isValidOperatorType() const { return operatorType == "less" || operatorType == "equal" || operatorType == "greater"; } diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 39a958c5c7..897c234550 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -87,7 +88,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) for (auto* section = ini.firstSection; section; section = section->next) { - AdditionalConstraint constraint; + AdditionalConstraints constraint; constraint.name = section->name.c_str(); for (auto* property = section->firstProperty; property; property = property->next) { @@ -111,24 +112,50 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) } else if (key == "hours") { - std::stringstream ss(value.c_str()); - std::string hour; - while (std::getline(ss, hour, ',')) + // + // std::stringstream ss(value.c_str()); + // std::string hour; + // while (std::getline(ss, hour, ',')) + // { + // int hourVal = std::stoi(hour); + // constraint.hours.insert(hourVal); + // } + + // Split the `hours` field into multiple groups + std::string hoursStr = value.c_str(); + std::regex groupRegex(R"(\[(.*?)\])"); + // Match each group enclosed in square brackets + auto groupsBegin = std::sregex_iterator(hoursStr.begin(), + hoursStr.end(), + groupRegex); + auto groupsEnd = std::sregex_iterator(); + for (auto it = groupsBegin; it != groupsEnd; ++it) { - int hourVal = std::stoi(hour); - constraint.hours.insert(hourVal); + // Extract the contents of the square brackets + std::string group = (*it)[1].str(); + std::stringstream ss(group); + std::string hour; + std::set hourSet; + + while (std::getline(ss, hour, ',')) + { + int hourVal = std::stoi(hour); + hourSet.insert(hourVal); + } + + constraint.hours.push_back(hourSet); // Add this group to the `hours` vector } } - else if (key == "rhs") - { - property->value.to(constraint.rhs); - } + + // try to read the rhs + loadFile(parent_path / ("rhs_" + constraint.name + ".txt"), constraint.rhs); + fillIfEmpty(constraint.rhs, 0.0); } - if (auto ret = constraint.validate(); !ret.ok) + if (auto [ok, error_msg] = constraint.validate(); !ok) { logs.error() << "Invalid constraint in section: " << section->name; - logs.error() << ret.error_msg; + logs.error() << error_msg; return false; } diff --git a/src/libs/antares/study/parts/short-term-storage/series.cpp b/src/libs/antares/study/parts/short-term-storage/series.cpp index 6c341c948d..4ee93d8a73 100644 --- a/src/libs/antares/study/parts/short-term-storage/series.cpp +++ b/src/libs/antares/study/parts/short-term-storage/series.cpp @@ -107,16 +107,16 @@ bool loadFile(const fs::path& path, std::vector& vect) return true; } -void Series::fillDefaultSeriesIfEmpty() +void fillIfEmpty(std::vector& v, double value) { - auto fillIfEmpty = [](std::vector& v, double value) + if (v.empty()) { - if (v.empty()) - { - v.resize(HOURS_PER_YEAR, value); - } - }; + v.resize(HOURS_PER_YEAR, value); + } +}; +void Series::fillDefaultSeriesIfEmpty() +{ fillIfEmpty(maxInjectionModulation, 1.0); fillIfEmpty(maxWithdrawalModulation, 1.0); fillIfEmpty(inflows, 0.0); diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index f6e684db83..f00d39d56e 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -130,28 +130,32 @@ void ShortTermStorageCumulation::add(int pays) for (const auto& storage: data.ShortTermStorage[pays]) { - for (const auto& constraint: storage.additional_constraints) + for (const auto& additional_constraints: storage.additional_constraints) { // sum (var[h]) sign rhs, h in list provided by user where: // var = injection for InjectionCumulationConstraint // var = withdrawal for WithdrawalCumulationConstraint // var = injectionEfficiency * injection - withdrawalEfficiency * withdrawal for Netting - auto constraintHelper = cumulationConstraintFromVariable(constraint.variable); - namer.ShortTermStorageCumulation(constraintHelper->name(), - builder.data.nombreDeContraintes, - storage.name, - constraint.name); - const auto index = storage.clusterGlobalIndex; - data.CorrespondanceCntNativesCntOptimHebdomadaires - .ShortTermStorageCumulation[constraint.globalIndex] - = builder.data.nombreDeContraintes; - - for (const auto& hour: constraint.hours) + auto constraintHelper = cumulationConstraintFromVariable( + additional_constraints.variable); + for (auto& constraint: additional_constraints.constraints) { - builder.updateHourWithinWeek(hour - 1); - constraintHelper->build(builder, index, storage); + namer.ShortTermStorageCumulation(constraintHelper->name() +, + builder.data.nombreDeContraintes, + storage.name, + additional_constraints.name); + const auto index = storage.clusterGlobalIndex; + data.CorrespondanceCntNativesCntOptimHebdomadaires + .ShortTermStorageCumulation[additional_constraints.globalIndex] + = builder.data.nombreDeContraintes; + + for (const auto& hour: additional_constraints.hours) + { + builder.updateHourWithinWeek(hour - 1); + constraintHelper->build(builder, index, storage); + } + builder.SetOperator(ConvertSense(additional_constraints.operatorType)).build(); } - builder.SetOperator(ConvertSense(constraint.operatorType)).build(); } } } diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index 35051ba2d5..52b7e8dc0d 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -183,7 +183,7 @@ struct PROPERTIES bool penalizeVariationInjection; std::shared_ptr series; - std::vector additional_constraints; + std::vector additional_constraints; int clusterGlobalIndex; std::string name; }; diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 786b1b5aa6..cdecaaa1cd 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -61,10 +61,13 @@ static void importShortTermStorages( toInsert.penalizeVariationWithdrawal = st.properties.penalizeVariationWithdrawal; toInsert.name = st.properties.name; toInsert.additional_constraints = st.additional_constraints; - for (auto& constraint: toInsert.additional_constraints) + for (auto& additional_constraints: toInsert.additional_constraints) { - constraint.globalIndex = clusterCumulativeConstraintGlobalIndex; - ++clusterCumulativeConstraintGlobalIndex; + for (auto& [_, globalIndex]: additional_constraints.constraints) + { + globalIndex = clusterCumulativeConstraintGlobalIndex; + ++clusterCumulativeConstraintGlobalIndex; + } } toInsert.series = st.series; From f100200599c2abbe18319e2ddfc87cc0c1705679 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 11:36:07 +0100 Subject: [PATCH 02/11] update --- .../parts/short-term-storage/container.cpp | 32 +++++++++++-------- .../ShortTermStorageCumulation.cpp | 15 +++++---- .../opt_decompte_variables_et_contraintes.cpp | 6 +++- ...opt_gestion_second_membre_cas_lineaire.cpp | 29 +++++++++++++---- .../simulation/sim_calcul_economique.cpp | 2 +- 5 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 897c234550..5dee3106dc 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -88,8 +88,8 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) for (auto* section = ini.firstSection; section; section = section->next) { - AdditionalConstraints constraint; - constraint.name = section->name.c_str(); + AdditionalConstraints additional_constraints; + additional_constraints.name = section->name.c_str(); for (auto* property = section->firstProperty; property; property = property->next) { const std::string key = property->key; @@ -100,15 +100,15 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) // TODO do i have to transform the name to id? TransformNameIntoID std::string clusterName; value.to(clusterName); - constraint.cluster_id = transformNameIntoID(clusterName); + additional_constraints.cluster_id = transformNameIntoID(clusterName); } else if (key == "variable") { - value.to(constraint.variable); + value.to(additional_constraints.variable); } else if (key == "operator") { - value.to(constraint.operatorType); + value.to(additional_constraints.operatorType); } else if (key == "hours") { @@ -129,6 +129,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) hoursStr.end(), groupRegex); auto groupsEnd = std::sregex_iterator(); + unsigned int localIndex = 0; for (auto it = groupsBegin; it != groupsEnd; ++it) { // Extract the contents of the square brackets @@ -142,17 +143,20 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) int hourVal = std::stoi(hour); hourSet.insert(hourVal); } - - constraint.hours.push_back(hourSet); // Add this group to the `hours` vector + // Add this group to the `hours` vec + additional_constraints.constraints.push_back( + {.hours = hourSet, .localIndex = localIndex}); + ++localIndex; } } // try to read the rhs - loadFile(parent_path / ("rhs_" + constraint.name + ".txt"), constraint.rhs); - fillIfEmpty(constraint.rhs, 0.0); + loadFile(parent_path / ("rhs_" + additional_constraints.name + ".txt"), + additional_constraints.rhs); + fillIfEmpty(additional_constraints.rhs, 0.0); } - if (auto [ok, error_msg] = constraint.validate(); !ok) + if (auto [ok, error_msg] = additional_constraints.validate(); !ok) { logs.error() << "Invalid constraint in section: " << section->name; logs.error() << error_msg; @@ -161,8 +165,10 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) auto it = std::find_if(storagesByIndex.begin(), storagesByIndex.end(), - [&constraint](const STStorageCluster& cluster) - { return cluster.id == constraint.cluster_id; }); + [&additional_constraints](const STStorageCluster& cluster) + { + return cluster.id == additional_constraints.cluster_id; + }); if (it == storagesByIndex.end()) { logs.warning() << " from file " << pathIni; @@ -172,7 +178,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) } else { - it->additional_constraints.push_back(constraint); + it->additional_constraints.push_back(additional_constraints); } } diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index f00d39d56e..bf6cf51f94 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -138,18 +138,19 @@ void ShortTermStorageCumulation::add(int pays) // var = injectionEfficiency * injection - withdrawalEfficiency * withdrawal for Netting auto constraintHelper = cumulationConstraintFromVariable( additional_constraints.variable); - for (auto& constraint: additional_constraints.constraints) + for (const auto& [hours, globalIndex, localIndex]: additional_constraints.constraints) { - namer.ShortTermStorageCumulation(constraintHelper->name() +, - builder.data.nombreDeContraintes, - storage.name, - additional_constraints.name); + namer.ShortTermStorageCumulation( + constraintHelper->name() + std::to_string(localIndex), + builder.data.nombreDeContraintes, + storage.name, + additional_constraints.name); const auto index = storage.clusterGlobalIndex; data.CorrespondanceCntNativesCntOptimHebdomadaires - .ShortTermStorageCumulation[additional_constraints.globalIndex] + .ShortTermStorageCumulation[globalIndex] = builder.data.nombreDeContraintes; - for (const auto& hour: additional_constraints.hours) + for (const auto& hour: hours) { builder.updateHourWithinWeek(hour - 1); constraintHelper->build(builder, index, storage); diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 79c29c58ab..7de6203d69 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -247,7 +247,11 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* } if (!storage.additional_constraints.empty()) { - ProblemeAResoudre->NombreDeContraintes += storage.additional_constraints.size(); + for (const auto& additional_constraints: storage.additional_constraints) + { + ProblemeAResoudre->NombreDeContraintes += additional_constraints.constraints + .size(); + } } } } diff --git a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp index c04d416f00..c3d0d16f95 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp @@ -19,6 +19,8 @@ ** along with Antares_Simulator. If not, see . */ +#include + #include "antares/solver/simulation/sim_structure_probleme_economique.h" double OPT_SommeDesPminThermiques(const PROBLEME_HEBDO*, int, uint); @@ -47,17 +49,32 @@ static void shortTermStorageCumulationRHS( const std::vector<::ShortTermStorage::AREA_INPUT>& shortTermStorageInput, int numberOfAreas, std::vector& SecondMembre, - const CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondancesDesContraintesHebdomadaires) + const CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondancesDesContraintesHebdomadaires, + int weekFirstHour) { for (int areaIndex = 0; areaIndex < numberOfAreas; areaIndex++) { for (auto& storage: shortTermStorageInput[areaIndex]) { - for (const auto& constraint: storage.additional_constraints) + for (const auto& additional_constraints: storage.additional_constraints) { - int cnt = CorrespondancesDesContraintesHebdomadaires + for (const auto& constraint: additional_constraints.constraints) + { + const int cnt = CorrespondancesDesContraintesHebdomadaires .ShortTermStorageCumulation[constraint.globalIndex]; - SecondMembre[cnt] = constraint.rhs; + + SecondMembre[cnt] = std::accumulate(constraint.hours.begin(), + constraint.hours.end(), + 0.0, + [weekFirstHour, &additional_constraints + ]( + const double sum, + const int hour) + { + return sum + additional_constraints.rhs[ + weekFirstHour + hour - 1]; + }); + } } } } @@ -395,11 +412,11 @@ void OPT_InitialiserLeSecondMembreDuProblemeLineaire(PROBLEME_HEBDO* problemeHeb } } } - shortTermStorageCumulationRHS(problemeHebdo->ShortTermStorage, problemeHebdo->NombreDePays, ProblemeAResoudre->SecondMembre, - problemeHebdo->CorrespondanceCntNativesCntOptimHebdomadaires); + problemeHebdo->CorrespondanceCntNativesCntOptimHebdomadaires, + weekFirstHour); if (problemeHebdo->OptimisationAvecCoutsDeDemarrage) { OPT_InitialiserLeSecondMembreDuProblemeLineaireCoutsDeDemarrage(problemeHebdo, diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index cdecaaa1cd..ace517889e 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -63,7 +63,7 @@ static void importShortTermStorages( toInsert.additional_constraints = st.additional_constraints; for (auto& additional_constraints: toInsert.additional_constraints) { - for (auto& [_, globalIndex]: additional_constraints.constraints) + for (auto& [_, globalIndex,__]: additional_constraints.constraints) { globalIndex = clusterCumulativeConstraintGlobalIndex; ++clusterCumulativeConstraintGlobalIndex; From 88698d48df1468898ef3d2771a15e79f9cc73801 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 11:53:55 +0100 Subject: [PATCH 03/11] read new folder --- src/libs/antares/study/area/list.cpp | 10 ++++++---- .../study/parts/short-term-storage/container.cpp | 11 +++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 7af3a6a5a7..868c3d5490 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1194,12 +1194,14 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) if (fs::exists(stsFolder)) { - for (const auto& [id, area]: areas) + for (const auto& area: areas | std::views::values) { - fs::path folder = stsFolder / "clusters" / area->id.c_str(); + fs::path cluster_folder = stsFolder / "clusters" / area->id.c_str(); + ret = area->shortTermStorage.createSTStorageClustersFromIniFile(cluster_folder) && + ret; - ret = area->shortTermStorage.createSTStorageClustersFromIniFile(folder) && ret; - ret = area->shortTermStorage.LoadConstraintsFromIniFile(folder) && ret; + const auto constraints_folder = stsFolder / "constraints" / area->id.c_str(); + ret = area->shortTermStorage.LoadConstraintsFromIniFile(cluster_folder) && ret; } } else diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 5dee3106dc..1e46be0a5f 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -163,12 +163,11 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) return false; } - auto it = std::find_if(storagesByIndex.begin(), - storagesByIndex.end(), - [&additional_constraints](const STStorageCluster& cluster) - { - return cluster.id == additional_constraints.cluster_id; - }); + auto it = std::ranges::find_if(storagesByIndex, + [&additional_constraints](const STStorageCluster& cluster) + { + return cluster.id == additional_constraints.cluster_id; + }); if (it == storagesByIndex.end()) { logs.warning() << " from file " << pathIni; From ffb6a42788fe56be20d5063f300dd45988de00fe Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 12:31:16 +0100 Subject: [PATCH 04/11] update outer-inner constraint count --- src/libs/antares/study/area/list.cpp | 2 +- .../parts/short-term-storage/container.cpp | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 868c3d5490..153ff7c19b 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1201,7 +1201,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) ret; const auto constraints_folder = stsFolder / "constraints" / area->id.c_str(); - ret = area->shortTermStorage.LoadConstraintsFromIniFile(cluster_folder) && ret; + ret = area->shortTermStorage.LoadConstraintsFromIniFile(constraints_folder) && ret; } } else diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 1e46be0a5f..25077864b5 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -149,13 +149,13 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) ++localIndex; } } - - // try to read the rhs - loadFile(parent_path / ("rhs_" + additional_constraints.name + ".txt"), - additional_constraints.rhs); - fillIfEmpty(additional_constraints.rhs, 0.0); } + // try to read the rhs + loadFile(parent_path / ("rhs_" + additional_constraints.name + ".txt"), + additional_constraints.rhs); + fillIfEmpty(additional_constraints.rhs, 0.0); + if (auto [ok, error_msg] = additional_constraints.validate(); !ok) { logs.error() << "Invalid constraint in section: " << section->name; @@ -229,8 +229,19 @@ std::size_t STStorageInput::cumulativeConstraintCount() const return std::accumulate(storagesByIndex.begin(), storagesByIndex.end(), 0, - [](int acc, const auto& cluster) - { return acc + cluster.additional_constraints.size(); }); + [](size_t outer_constraint_count, const auto& cluster) + { + return outer_constraint_count + std::accumulate( + cluster.additional_constraints.begin(), + cluster.additional_constraints.end(), + 0, + [](size_t inner_constraint_count, + const auto& additional_constraints) + { + return inner_constraint_count + + additional_constraints.constraints.size(); + }); + }); } std::size_t STStorageInput::count() const From de7c893e8ba0748584e89d9e19247d0f21976bae Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 12:35:30 +0100 Subject: [PATCH 05/11] update unpacked constraints --- .../optimisation/constraints/ShortTermStorageCumulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index bf6cf51f94..d72adac1e2 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -141,10 +141,10 @@ void ShortTermStorageCumulation::add(int pays) for (const auto& [hours, globalIndex, localIndex]: additional_constraints.constraints) { namer.ShortTermStorageCumulation( - constraintHelper->name() + std::to_string(localIndex), + constraintHelper->name(), builder.data.nombreDeContraintes, storage.name, - additional_constraints.name); + additional_constraints.name + std::to_string(localIndex)); const auto index = storage.clusterGlobalIndex; data.CorrespondanceCntNativesCntOptimHebdomadaires .ShortTermStorageCumulation[globalIndex] From 1fcc874ed0790971d226939c83bf8fffca7b5ebb Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 12:41:08 +0100 Subject: [PATCH 06/11] update name of unpacked constraints --- .../optimisation/constraints/ShortTermStorageCumulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index d72adac1e2..82796aabd3 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -144,7 +144,7 @@ void ShortTermStorageCumulation::add(int pays) constraintHelper->name(), builder.data.nombreDeContraintes, storage.name, - additional_constraints.name + std::to_string(localIndex)); + additional_constraints.name + "_" + std::to_string(localIndex)); const auto index = storage.clusterGlobalIndex; data.CorrespondanceCntNativesCntOptimHebdomadaires .ShortTermStorageCumulation[globalIndex] From be9f17416e2af328d9e4101be5627b8ff6132326 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 14:38:31 +0100 Subject: [PATCH 07/11] update --- .../study/parts/short-term-storage/container.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libs/antares/study/parts/short-term-storage/container.cpp b/src/libs/antares/study/parts/short-term-storage/container.cpp index 25077864b5..51ef512005 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -143,10 +143,13 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) int hourVal = std::stoi(hour); hourSet.insert(hourVal); } - // Add this group to the `hours` vec - additional_constraints.constraints.push_back( - {.hours = hourSet, .localIndex = localIndex}); - ++localIndex; + if (!hourSet.empty()) + { + // Add this group to the `hours` vec + additional_constraints.constraints.push_back( + {.hours = hourSet, .localIndex = localIndex}); + ++localIndex; + } } } } From 11169e18aac70a867d289abe7d31330c90dd1abb Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 15:30:52 +0100 Subject: [PATCH 08/11] add UT --- .../short-term-storage-input-output.cpp | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 265135c7d4..16451dc2e5 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -30,6 +30,7 @@ #include #include "antares/study/parts/short-term-storage/container.h" +#include "antares/study/parts/short-term-storage/AdditionalConstraints.h" using namespace std; using namespace Antares::Data; @@ -451,3 +452,84 @@ BOOST_FIXTURE_TEST_CASE(check_series_save, Fixture) } BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(AdditionalConstraintsTests) + +BOOST_AUTO_TEST_CASE(Validate_ClusterIdEmpty) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = ""; // Cluster ID is empty + constraints.variable = "injection"; + constraints.operatorType = "less"; + + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, false); + BOOST_CHECK_EQUAL(error_msg, "Cluster ID is empty."); +} + +BOOST_AUTO_TEST_CASE(Validate_InvalidVariable) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = "ClusterA"; + constraints.variable = "invalid"; // Invalid variable type + constraints.operatorType = "less"; + + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, false); + BOOST_CHECK_EQUAL(error_msg, + "Invalid variable type. Must be 'injection', 'withdrawal', or 'netting'."); +} + +BOOST_AUTO_TEST_CASE(Validate_InvalidOperatorType) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = "ClusterA"; + constraints.variable = "injection"; + constraints.operatorType = "invalid"; // Invalid operator type + + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, false); + BOOST_CHECK_EQUAL(error_msg, + "Invalid operator type. Must be 'less', 'equal', or 'greater'."); +} + +BOOST_AUTO_TEST_CASE(Validate_InvalidHours) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = "ClusterA"; + constraints.variable = "injection"; + constraints.operatorType = "less"; + + ShortTermStorage::SingleAdditionalConstraint constraint; + constraint.hours = {0, 169}; // Invalid hours range (out of 1-168) + constraints.constraints.push_back(constraint); + + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, false); + BOOST_CHECK_EQUAL(error_msg, + "Hours sets contains invalid values. Must be between 1 and 168."); +} + +BOOST_AUTO_TEST_CASE(Validate_ValidConstraints) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = "ClusterA"; + constraints.variable = "injection"; + constraints.operatorType = "less"; + + ShortTermStorage::SingleAdditionalConstraint constraint1; + constraint1.hours = {1, 2, 3}; // Valid hours + + ShortTermStorage::SingleAdditionalConstraint constraint2; + constraint2.hours = {100, 150, 168}; // Valid hours + + constraints.constraints.push_back(constraint1); + constraints.constraints.push_back(constraint2); + + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, true); + BOOST_CHECK(error_msg.empty()); +} + +BOOST_AUTO_TEST_SUITE_END() + From cf2e4bcf51fea52f880138d452f80b8661a181a9 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 16:09:07 +0100 Subject: [PATCH 09/11] add UT --- .../short-term-storage-input-output.cpp | 253 +++++++++++++++++- 1 file changed, 248 insertions(+), 5 deletions(-) diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 16451dc2e5..c5e74d4d8d 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -29,6 +29,7 @@ #include +#include "antares/antares/constants.h" #include "antares/study/parts/short-term-storage/container.h" #include "antares/study/parts/short-term-storage/AdditionalConstraints.h" @@ -500,14 +501,24 @@ BOOST_AUTO_TEST_CASE(Validate_InvalidHours) constraints.variable = "injection"; constraints.operatorType = "less"; - ShortTermStorage::SingleAdditionalConstraint constraint; - constraint.hours = {0, 169}; // Invalid hours range (out of 1-168) - constraints.constraints.push_back(constraint); + // Case 1: Empty hours + ShortTermStorage::SingleAdditionalConstraint constraint1; + constraint1.hours = {}; // Invalid: empty + constraints.constraints.push_back(constraint1); + + // Case 2: Out of range + ShortTermStorage::SingleAdditionalConstraint constraint2; + constraint2.hours = {120, 169}; // Invalid: out of range + constraints.constraints.push_back(constraint2); + + // Case 3: Below minimum + ShortTermStorage::SingleAdditionalConstraint constraint3; + constraint3.hours = {0, 1}; // Invalid: below minimum + constraints.constraints.push_back(constraint3); auto [ok, error_msg] = constraints.validate(); BOOST_CHECK_EQUAL(ok, false); - BOOST_CHECK_EQUAL(error_msg, - "Hours sets contains invalid values. Must be between 1 and 168."); + BOOST_CHECK_EQUAL(error_msg, "Hours sets contains invalid values. Must be between 1 and 168."); } BOOST_AUTO_TEST_CASE(Validate_ValidConstraints) @@ -531,5 +542,237 @@ BOOST_AUTO_TEST_CASE(Validate_ValidConstraints) BOOST_CHECK(error_msg.empty()); } +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidFile) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=cluster1\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "cluster1"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + + BOOST_CHECK_EQUAL(result, true); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints.size(), 1); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints[0].name, + "constraint1"); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidHours) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=ClusterA\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[0,1]\n"; // Invalid hours + iniFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "ClusterA"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(result, false); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidHoursFormats) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=cluster1\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1],[1],[3,2,1]\n"; // Valid formats + iniFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "cluster1"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(result, true); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MissingFile) +{ + ShortTermStorage::STStorageInput storageInput; + bool result = storageInput.LoadConstraintsFromIniFile("nonexistent_path"); + BOOST_CHECK_EQUAL(result, true); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidConstraint) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=cluster1\n"; + iniFile << "variable=invalid\n"; // Invalid variable + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "cluster1"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(result, false); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidRhs) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=cluster1\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + std::ofstream rhsFile(testPath / "rhs_constraint1.txt"); + for (int i = 0; i < HOURS_PER_YEAR; ++i) + { + rhsFile << i * 1.0 << "\n"; + } + rhsFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "cluster1"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + + BOOST_CHECK_EQUAL(result, true); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints[0].rhs.size(), + HOURS_PER_YEAR); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints[0].rhs[0], 0.0); + BOOST_CHECK_EQUAL( + storageInput.storagesByIndex[0].additional_constraints[0].rhs[HOURS_PER_YEAR - 1], + HOURS_PER_YEAR - 1); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MissingRhsFile) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=cluster1\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "cluster1"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + + BOOST_CHECK_EQUAL(result, true); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints[0].rhs.size(), + HOURS_PER_YEAR); + BOOST_CHECK_EQUAL(storageInput.storagesByIndex[0].additional_constraints[0].rhs[0], 0.0); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MalformedRhsFile) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=ClusterA\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + std::ofstream rhsFile(testPath / "rhs_constraint1.txt"); + rhsFile << "1.0\n2.0\ninvalid\n4.0\n"; // Malformed line + rhsFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "ClusterA"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(result, false); + + std::filesystem::remove_all(testPath); +} + +BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_IncompleteRhsFile) +{ + std::filesystem::path testPath = "test_data"; + std::filesystem::create_directory(testPath); + + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=ClusterA\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + std::ofstream rhsFile(testPath / "rhs_constraint1.txt"); + for (int i = 0; i < 10; ++i) + { + rhsFile << i * 1.0 << "\n"; + } + rhsFile.close(); + + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "ClusterA"; + storageInput.storagesByIndex.push_back(cluster); + + bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(result, false); + + std::filesystem::remove_all(testPath); +} + BOOST_AUTO_TEST_SUITE_END() From c0b684eb1e029eea02ad662e9fb6610a78c3e677 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 16:16:10 +0100 Subject: [PATCH 10/11] use tmp dir as test dir --- .../short-term-storage-input-output.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index c5e74d4d8d..3f50330597 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -544,7 +544,7 @@ BOOST_AUTO_TEST_CASE(Validate_ValidConstraints) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidFile) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -572,7 +572,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidFile) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidHours) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -596,7 +596,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidHours) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidHoursFormats) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -627,7 +627,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MissingFile) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidConstraint) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -651,7 +651,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_InvalidConstraint) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidRhs) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -689,7 +689,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidRhs) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MissingRhsFile) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -717,7 +717,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MissingRhsFile) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MalformedRhsFile) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); @@ -745,7 +745,7 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_MalformedRhsFile) BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_IncompleteRhsFile) { - std::filesystem::path testPath = "test_data"; + std::filesystem::path testPath = getFolder() / "test_data"; std::filesystem::create_directory(testPath); std::ofstream iniFile(testPath / "additional-constraints.ini"); From d2b66c9cf2df9904de75bcb85bd0ccc91ec320ea Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 20 Dec 2024 16:47:16 +0100 Subject: [PATCH 11/11] add test --- .../short-term-storage-input-output.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 3f50330597..72dd788ffa 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -26,6 +26,7 @@ #include #include +#include #include @@ -774,5 +775,31 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_IncompleteRhsFile) std::filesystem::remove_all(testPath); } +// Test data for parameterization +namespace bdata = boost::unit_test::data; + +BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinations, + bdata::make({"injection", "withdrawal", "netting"}) ^ + bdata::make({"less", "equal", "greater"}), + variable, + op) +{ + ShortTermStorage::AdditionalConstraints constraints; + constraints.cluster_id = "ClusterA"; + constraints.variable = variable; + constraints.operatorType = op; + + // Create constraints with valid hours + constraints.constraints.push_back(ShortTermStorage::SingleAdditionalConstraint{{1, 2, 3}}); + constraints.constraints.push_back(ShortTermStorage::SingleAdditionalConstraint{{50, 100, 150}}); + constraints.constraints. + push_back(ShortTermStorage::SingleAdditionalConstraint{{120, 121, 122}}); + + // Validate the constraints + auto [ok, error_msg] = constraints.validate(); + BOOST_CHECK_EQUAL(ok, true); + BOOST_CHECK(error_msg.empty()); +} + BOOST_AUTO_TEST_SUITE_END()