diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h index 7e27c9a60f..705c84d8e8 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraints.h @@ -31,7 +31,6 @@ struct SingleAdditionalConstraint std::set hours; unsigned int globalIndex = 0; unsigned int localIndex = 0; - bool isValidHoursRange() const; }; @@ -41,8 +40,9 @@ struct AdditionalConstraints std::string cluster_id; std::string variable; std::string operatorType; + bool enabled = true; // TODO a lot unused entries - //std::array rhs = {}; + // std::array rhs = {}; std::vector rhs = {}; std::vector constraints = {}; @@ -53,6 +53,9 @@ struct AdditionalConstraints std::string error_msg; }; + // Number of enabled constraints + std::size_t enabledConstraints() const; + ValidateResult validate() const; private: diff --git a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp index 8775ffe561..5bbeaa7df6 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraints.cpp @@ -19,6 +19,7 @@ ** along with Antares_Simulator. If not, see . */ #include "antares/study/parts/short-term-storage/AdditionalConstraints.h" + #include namespace Antares::Data::ShortTermStorage @@ -47,12 +48,11 @@ AdditionalConstraints::ValidateResult AdditionalConstraints::validate() const return {true, ""}; } + 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 AdditionalConstraints::isValidHours() const @@ -60,12 +60,9 @@ bool AdditionalConstraints::isValidHours() const return std::ranges::all_of(constraints.begin(), constraints.end(), [](const auto& constraint) - { - return constraint.isValidHoursRange(); - }); + { return constraint.isValidHoursRange(); }); } - bool AdditionalConstraints::isValidVariable() const { return variable == "injection" || variable == "withdrawal" || variable == "netting"; @@ -75,4 +72,9 @@ bool AdditionalConstraints::isValidOperatorType() const { return operatorType == "less" || operatorType == "equal" || operatorType == "greater"; } + +std::size_t AdditionalConstraints::enabledConstraints() const +{ + return enabled ? constraints.size() : 0; +} } // namespace Antares::Data::ShortTermStorage 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 51ef512005..18e5c35596 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -102,6 +102,10 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) value.to(clusterName); additional_constraints.cluster_id = transformNameIntoID(clusterName); } + else if (key == "enabled") + { + value.to(additional_constraints.enabled); + } else if (key == "variable") { value.to(additional_constraints.variable); @@ -147,7 +151,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) { // Add this group to the `hours` vec additional_constraints.constraints.push_back( - {.hours = hourSet, .localIndex = localIndex}); + {.hours = hourSet, .localIndex = localIndex}); ++localIndex; } } @@ -168,9 +172,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) auto it = std::ranges::find_if(storagesByIndex, [&additional_constraints](const STStorageCluster& cluster) - { - return cluster.id == additional_constraints.cluster_id; - }); + { return cluster.id == additional_constraints.cluster_id; }); if (it == storagesByIndex.end()) { logs.warning() << " from file " << pathIni; @@ -234,16 +236,16 @@ std::size_t STStorageInput::cumulativeConstraintCount() const 0, [](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(); - }); + 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.enabledConstraints(); + }); }); } diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 82796aabd3..a6aafb6cda 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -137,18 +137,18 @@ void ShortTermStorageCumulation::add(int pays) // var = withdrawal for WithdrawalCumulationConstraint // var = injectionEfficiency * injection - withdrawalEfficiency * withdrawal for Netting auto constraintHelper = cumulationConstraintFromVariable( - additional_constraints.variable); + additional_constraints.variable); for (const auto& [hours, globalIndex, localIndex]: additional_constraints.constraints) { - namer.ShortTermStorageCumulation( - constraintHelper->name(), - builder.data.nombreDeContraintes, - storage.name, - additional_constraints.name + "_" + std::to_string(localIndex)); + namer.ShortTermStorageCumulation(constraintHelper->name(), + builder.data.nombreDeContraintes, + storage.name, + additional_constraints.name + "_" + + std::to_string(localIndex)); const auto index = storage.clusterGlobalIndex; data.CorrespondanceCntNativesCntOptimHebdomadaires - .ShortTermStorageCumulation[globalIndex] - = builder.data.nombreDeContraintes; + .ShortTermStorageCumulation[globalIndex] + = builder.data.nombreDeContraintes; for (const auto& hour: hours) { diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index ace517889e..82de057a94 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -60,15 +60,19 @@ static void importShortTermStorages( toInsert.penalizeVariationInjection = st.properties.penalizeVariationInjection; toInsert.penalizeVariationWithdrawal = st.properties.penalizeVariationWithdrawal; toInsert.name = st.properties.name; - toInsert.additional_constraints = st.additional_constraints; - for (auto& additional_constraints: toInsert.additional_constraints) + for (auto& constr: st.additional_constraints) { - for (auto& [_, globalIndex,__]: additional_constraints.constraints) + if (constr.enabled) { - globalIndex = clusterCumulativeConstraintGlobalIndex; - ++clusterCumulativeConstraintGlobalIndex; + for (auto c: constr.constraints) + { + c.globalIndex = clusterCumulativeConstraintGlobalIndex; + ++clusterCumulativeConstraintGlobalIndex; + } + toInsert.additional_constraints.push_back(constr); } } + toInsert.series = st.series; // TODO add missing properties, or use the same struct 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 c09065f510..d01a56c9df 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 @@ -22,18 +22,18 @@ #define WIN32_LEAN_AND_MEAN +#include #include #include -#include -#include #include +#include #include #include "antares/antares/constants.h" -#include "antares/study/parts/short-term-storage/container.h" #include "antares/study/parts/short-term-storage/AdditionalConstraints.h" +#include "antares/study/parts/short-term-storage/container.h" using namespace std; using namespace Antares::Data; @@ -492,8 +492,7 @@ BOOST_AUTO_TEST_CASE(Validate_InvalidOperatorType) 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_CHECK_EQUAL(error_msg, "Invalid operator type. Must be 'less', 'equal', or 'greater'."); } BOOST_AUTO_TEST_CASE(Validate_InvalidHours) @@ -683,8 +682,8 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_ValidRhs) 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); + storageInput.storagesByIndex[0].additional_constraints[0].rhs[HOURS_PER_YEAR - 1], + HOURS_PER_YEAR - 1); std::filesystem::remove_all(testPath); } @@ -730,12 +729,9 @@ BOOST_AUTO_TEST_CASE(Load2ConstraintsFromIniFile) BOOST_CHECK_EQUAL(constraint1.operatorType, "less"); BOOST_CHECK_EQUAL(constraint1.variable, "injection"); BOOST_CHECK_EQUAL(constraint1.cluster_id, cluster.id); - BOOST_CHECK_EQUAL(constraint1.rhs.size(), - HOURS_PER_YEAR); + BOOST_CHECK_EQUAL(constraint1.rhs.size(), HOURS_PER_YEAR); BOOST_CHECK_EQUAL(constraint1.rhs[0], 0.0); - BOOST_CHECK_EQUAL( - constraint1.rhs[HOURS_PER_YEAR - 1], - HOURS_PER_YEAR - 1); + BOOST_CHECK_EQUAL(constraint1.rhs[HOURS_PER_YEAR - 1], HOURS_PER_YEAR - 1); //------- constraint2 ---------- @@ -745,12 +741,9 @@ BOOST_AUTO_TEST_CASE(Load2ConstraintsFromIniFile) BOOST_CHECK_EQUAL(constraint2.variable, "withdrawal"); BOOST_CHECK_EQUAL(constraint2.cluster_id, cluster.id); - BOOST_CHECK_EQUAL(constraint2.rhs.size(), - HOURS_PER_YEAR); + BOOST_CHECK_EQUAL(constraint2.rhs.size(), HOURS_PER_YEAR); BOOST_CHECK_EQUAL(constraint2.rhs[0], 0.0); - BOOST_CHECK_EQUAL( - constraint2.rhs[HOURS_PER_YEAR - 1], - 0.0); + BOOST_CHECK_EQUAL(constraint2.rhs[HOURS_PER_YEAR - 1], 0.0); std::filesystem::remove_all(testPath); } @@ -846,8 +839,8 @@ BOOST_AUTO_TEST_CASE(LoadConstraintsFromIniFile_IncompleteRhsFile) namespace bdata = boost::unit_test::data; BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinations, - bdata::make({"injection", "withdrawal", "netting"}) ^ - bdata::make({"less", "equal", "greater"}), + bdata::make({"injection", "withdrawal", "netting"}) + ^ bdata::make({"less", "equal", "greater"}), variable, op) { @@ -859,8 +852,8 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinations, // 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}}); + constraints.constraints.push_back( + ShortTermStorage::SingleAdditionalConstraint{{120, 121, 122}}); // Validate the constraints auto [ok, error_msg] = constraints.validate(); @@ -868,12 +861,12 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinations, BOOST_CHECK(error_msg.empty()); } - BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, - bdata::make({"injection", "withdrawal", "netting"}) ^ - bdata::make({"less", "equal", "greater"}), + bdata::make({"injection", "withdrawal", "netting"}) + * bdata::make({"less", "equal", "greater"}) * bdata::make({true, false}), variable, - op) + op, + enabled) { // Define the path for the test data std::filesystem::path testPath = std::filesystem::temp_directory_path() / "test_data"; @@ -885,6 +878,8 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, iniFile << "cluster=clustera\n"; iniFile << "variable=" << variable << "\n"; iniFile << "operator=" << op << "\n"; + iniFile << std::boolalpha; + iniFile << "enabled=" << enabled << "\n"; iniFile << "hours=[1,2,3]\n"; iniFile.close(); @@ -904,14 +899,17 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, // Load constraints from the `.ini` file bool result = storageInput.LoadConstraintsFromIniFile(testPath); + BOOST_CHECK_EQUAL(storageInput.cumulativeConstraintCount(), enabled ? 1 : 0); // Assertions BOOST_CHECK_EQUAL(result, true); - // Validate loaded constraints auto& built_cluster = storageInput.storagesByIndex[0]; + BOOST_REQUIRE_EQUAL(built_cluster.additional_constraints.size(), 1); const auto& loadedConstraint = built_cluster.additional_constraints[0]; + BOOST_CHECK_EQUAL(loadedConstraint.enabled, enabled); + BOOST_CHECK_EQUAL(loadedConstraint.enabledConstraints(), enabled ? 1 : 0); // Check variable, operator type, and rhs values BOOST_CHECK_EQUAL(loadedConstraint.variable, variable); @@ -929,4 +927,3 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, } BOOST_AUTO_TEST_SUITE_END() -