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 f0ecb9b34b..081ca0d516 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 @@ -33,7 +33,6 @@ class SingleAdditionalConstraint std::set hours; unsigned int globalIndex = 0; unsigned int localIndex = 0; - bool isValidHoursRange() const; }; @@ -43,6 +42,7 @@ struct AdditionalConstraints std::string cluster_id; std::string variable; std::string operatorType; + bool enabled = true; // TODO a lot unused entries // std::array rhs = {}; std::vector rhs; @@ -55,6 +55,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 6a3df8996f..edc8d4d227 100644 --- a/src/libs/antares/study/parts/short-term-storage/additionalConstraints.cpp +++ b/src/libs/antares/study/parts/short-term-storage/additionalConstraints.cpp @@ -72,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 73d3a611f5..f26aff9929 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -107,12 +107,13 @@ static void loadHours(const std::string& hoursStr, AdditionalConstraints& additi } } -static bool readRHS(AdditionalConstraints& additionalConstraints, - const fs::path& rhsPath) +static bool readRHS(AdditionalConstraints& additionalConstraints, const fs::path& rhsPath) { - const auto ret = loadFile(rhsPath, - additionalConstraints.rhs); - if (ret) { fillIfEmpty(additionalConstraints.rhs, 0.0); } + const auto ret = loadFile(rhsPath, additionalConstraints.rhs); + if (ret) + { + fillIfEmpty(additionalConstraints.rhs, 0.0); + } return ret; } @@ -141,6 +142,10 @@ bool STStorageInput::loadAdditionalConstraints(const fs::path& parentPath) value.to(clusterName); additionalConstraints.cluster_id = transformNameIntoID(clusterName); } + else if (key == "enabled") + { + value.to(additionalConstraints.enabled); + } else if (key == "variable") { value.to(additionalConstraints.variable); @@ -155,13 +160,19 @@ bool STStorageInput::loadAdditionalConstraints(const fs::path& parentPath) } } - if (const auto rhsPath = parentPath / ( - "rhs_" + additionalConstraints.name - + ".txt"); !readRHS(additionalConstraints, rhsPath)) + // We don't want load RHS and link the STS time if the constraint is disabled + if (!additionalConstraints.enabled) + { + return true; + } + + if (const auto rhsPath = parentPath / ("rhs_" + additionalConstraints.name + ".txt"); + !readRHS(additionalConstraints, rhsPath)) { logs.error() << "Error while reading rhs file: " << rhsPath; return false; } + if (auto [ok, error_msg] = additionalConstraints.validate(); !ok) { logs.error() << "Invalid constraint in section: " << section->name; @@ -242,7 +253,7 @@ std::size_t STStorageInput::cumulativeConstraintCount() const cluster.additionalConstraints.end(), 0, [](size_t inner_constraint_count, const auto& additionalConstraints) - { return inner_constraint_count + additionalConstraints.constraints.size(); }); + { return inner_constraint_count + additionalConstraints.enabledConstraints(); }); }); } diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 34b1c5928a..3354ce29ce 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -27,9 +27,7 @@ class CumulationConstraint { public: - virtual void build( - unsigned int index) const - = 0; + virtual void build(unsigned int index) const = 0; virtual std::string name() const = 0; virtual ~CumulationConstraint() = default; @@ -38,13 +36,12 @@ class CumulationConstraint class WithdrawalCumulationConstraint: public CumulationConstraint { public: - WithdrawalCumulationConstraint(ConstraintBuilder& builder) : builder(builder) + WithdrawalCumulationConstraint(ConstraintBuilder& builder): + builder(builder) { } - void build( - unsigned int index - ) const override + void build(unsigned int index) const override { builder.ShortTermStorageWithdrawal(index, 1.0); } @@ -62,12 +59,12 @@ class WithdrawalCumulationConstraint: public CumulationConstraint class InjectionCumulationConstraint: public CumulationConstraint { public: - InjectionCumulationConstraint(ConstraintBuilder& builder): builder(builder) + InjectionCumulationConstraint(ConstraintBuilder& builder): + builder(builder) { } - void build( - unsigned int index) const override + void build(unsigned int index) const override { builder.ShortTermStorageInjection(index, 1.0); } @@ -85,20 +82,18 @@ class InjectionCumulationConstraint: public CumulationConstraint class NettingCumulationConstraint: public CumulationConstraint { public: - NettingCumulationConstraint(ConstraintBuilder& builder, - const ::ShortTermStorage::PROPERTIES& - short_term_storage_properties) : builder(builder), - short_term_storage_properties( - short_term_storage_properties) + NettingCumulationConstraint( + ConstraintBuilder& builder, + const ::ShortTermStorage::PROPERTIES& short_term_storage_properties): + builder(builder), + short_term_storage_properties(short_term_storage_properties) { } - void build( - unsigned int index) const override + void build(unsigned int index) const override { builder.ShortTermStorageInjection(index, short_term_storage_properties.injectionEfficiency) - .ShortTermStorageWithdrawal(index, - -short_term_storage_properties.withdrawalEfficiency); + .ShortTermStorageWithdrawal(index, -short_term_storage_properties.withdrawalEfficiency); } std::string name() const override @@ -113,9 +108,9 @@ class NettingCumulationConstraint: public CumulationConstraint }; std::unique_ptr cumulationConstraintFactory( - const std::string& variable, - ConstraintBuilder& builder, - const ShortTermStorage::PROPERTIES& short_term_storage_properties) + const std::string& variable, + ConstraintBuilder& builder, + const ShortTermStorage::PROPERTIES& short_term_storage_properties) { if (variable == "withdrawal") { @@ -127,8 +122,8 @@ std::unique_ptr cumulationConstraintFactory( } else if (variable == "netting") { - return std::make_unique< - NettingCumulationConstraint>(builder, short_term_storage_properties); + return std::make_unique(builder, + short_term_storage_properties); } throw std::invalid_argument("Invalid cumulation constraint type"); } @@ -162,17 +157,16 @@ void ShortTermStorageCumulation::add(int pays) // var = injection for InjectionCumulationConstraint // var = withdrawal for WithdrawalCumulationConstraint // var = injectionEfficiency * injection - withdrawalEfficiency * withdrawal for Netting - auto cumulationConstraint = cumulationConstraintFactory( - additionalConstraints.variable, - builder, - storage); + auto cumulationConstraint = cumulationConstraintFactory(additionalConstraints.variable, + builder, + storage); for (const auto& [hours, globalIndex, localIndex]: additionalConstraints.constraints) { namer.ShortTermStorageCumulation(cumulationConstraint->name(), builder.data.nombreDeContraintes, storage.name, additionalConstraints.name + "_" - + std::to_string(localIndex)); + + std::to_string(localIndex)); const auto index = storage.clusterGlobalIndex; data.CorrespondanceCntNativesCntOptimHebdomadaires .ShortTermStorageCumulation[globalIndex] diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 0f5c0e095f..19f3f26ec9 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -249,8 +249,8 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* { for (const auto& additionalConstraints: storage.additionalConstraints) { - ProblemeAResoudre->NombreDeContraintes += additionalConstraints.constraints - .size(); + ProblemeAResoudre->NombreDeContraintes += additionalConstraints + .enabledConstraints(); } } } diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 00140e1553..d9166226f1 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -60,15 +60,20 @@ static void importShortTermStorages( toInsert.penalizeVariationInjection = st.properties.penalizeVariationInjection; toInsert.penalizeVariationWithdrawal = st.properties.penalizeVariationWithdrawal; toInsert.name = st.properties.name; - toInsert.additionalConstraints = st.additionalConstraints; - for (auto& additionalConstraints: toInsert.additionalConstraints) + for (const auto& constraint: st.additionalConstraints) { - for (auto& [_, globalIndex, __]: additionalConstraints.constraints) + if (constraint.enabled) { - globalIndex = constraintGlobalIndex; - ++constraintGlobalIndex; + auto newConstraint = constraint; + for (auto& c: newConstraint.constraints) + { + c.globalIndex = constraintGlobalIndex; + ++constraintGlobalIndex; + } + toInsert.additionalConstraints.push_back(std::move(newConstraint)); } } + 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 67a6fc7d52..2c0134b0ab 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 @@ -886,7 +886,7 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinations, BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, bdata::make({"injection", "withdrawal", "netting"}) - ^ bdata::make({"less", "equal", "greater"}), + * bdata::make({"less", "equal", "greater"}), variable, op) { @@ -900,6 +900,7 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, iniFile << "cluster=clustera\n"; iniFile << "variable=" << variable << "\n"; iniFile << "operator=" << op << "\n"; + iniFile << "enabled=true\n"; iniFile << "hours=[1,2,3]\n"; iniFile.close(); @@ -919,13 +920,14 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, // Load constraints from the `.ini` file bool result = storageInput.loadAdditionalConstraints(testPath); + BOOST_CHECK_EQUAL(storageInput.cumulativeConstraintCount(), 1); // Assertions BOOST_CHECK_EQUAL(result, true); - // Validate loaded constraints auto& built_cluster = storageInput.storagesByIndex[0]; BOOST_REQUIRE_EQUAL(built_cluster.additionalConstraints.size(), 1); + const auto& loadedConstraint = built_cluster.additionalConstraints[0]; // Check variable, operator type, and rhs values @@ -943,4 +945,38 @@ BOOST_DATA_TEST_CASE(Validate_AllVariableOperatorCombinationsFromFile, } while (i < HOURS_PER_YEAR); } +BOOST_AUTO_TEST_CASE(Load_disabled) +{ + // Define the path for the test data + std::filesystem::path testPath = std::filesystem::temp_directory_path() / "test_data"; + std::filesystem::create_directory(testPath); + + // Write the `.ini` file for this test case + std::ofstream iniFile(testPath / "additional-constraints.ini"); + iniFile << "[constraint1]\n"; + iniFile << "cluster=clustera\n"; + iniFile << "variable=injection\n"; + iniFile << "operator=less\n"; + iniFile << "enabled=false\n"; + iniFile << "hours=[1,2,3]\n"; + iniFile.close(); + + + // Setup storage input and cluster + ShortTermStorage::STStorageInput storageInput; + ShortTermStorage::STStorageCluster cluster; + cluster.id = "clustera"; + storageInput.storagesByIndex.push_back(cluster); + + // Load constraints from the `.ini` file + bool result = storageInput.loadAdditionalConstraints(testPath); + BOOST_CHECK_EQUAL(storageInput.cumulativeConstraintCount(), 0); + + // Assertions + BOOST_CHECK_EQUAL(result, true); + // Validate loaded constraints + auto& built_cluster = storageInput.storagesByIndex[0]; + BOOST_REQUIRE_EQUAL(built_cluster.additionalConstraints.size(), 0); +} + BOOST_AUTO_TEST_SUITE_END()