From fde1daef6d4ecf40ca3ab744d51d9dff6360d0e3 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 13 Dec 2024 12:22:27 +0100 Subject: [PATCH 01/27] read and validate additional constraints --- src/libs/antares/study/CMakeLists.txt | 10 +- .../study/parts/short-term-storage/cluster.h | 33 +-- .../parts/short-term-storage/container.h | 48 +++-- .../AdditionalConstraint.cpp | 42 ++++ .../parts/short-term-storage/cluster.cpp | 95 ++++----- .../parts/short-term-storage/container.cpp | 192 +++++++++++------- 6 files changed, 251 insertions(+), 169 deletions(-) create mode 100644 src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 29a89fc631..e7336d020c 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -74,8 +74,8 @@ set(SRC_STUDY_PART_THERMAL include/antares/study/parts/thermal/cost_provider.h include/antares/study/parts/thermal/cluster.hxx parts/thermal/cluster.cpp - parts/thermal/scenarized_cost_provider.cpp - parts/thermal/constant_cost_provider.cpp + parts/thermal/scenarized_cost_provider.cpp + parts/thermal/constant_cost_provider.cpp include/antares/study/parts/thermal/cluster_list.h parts/thermal/cluster_list.cpp include/antares/study/parts/thermal/pollutant.h @@ -102,7 +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 parts/short-term-storage/cluster.cpp + parts/short-term-storage/AdditionalConstraint.cpp ) source_group("study\\part\\short-term-storage" FILES ${SRC_STUDY_PART_SHORT_TERM_SOTRAGE}) @@ -306,12 +308,12 @@ target_link_libraries(study ) target_include_directories(study - PUBLIC + PUBLIC $ # Make more than just study visible but it's the lesser evil for now ) -install(DIRECTORY include/antares +install(DIRECTORY include/antares DESTINATION "include" ) 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 b4074a28c8..03c45e04f8 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 @@ -28,24 +28,27 @@ #include "properties.h" #include "series.h" +#include "AdditionalConstraint.h" -namespace Antares::Data::ShortTermStorage -{ -class STStorageCluster -{ -public: - bool enabled() const; - bool validate() const; +namespace Antares::Data::ShortTermStorage { + class STStorageCluster { + public: + bool enabled() const; - bool loadFromSection(const IniFile::Section& section); - bool loadSeries(const std::filesystem::path& folder) const; + bool validate() const; - void saveProperties(IniFile& ini) const; - bool saveSeries(const std::string& path) const; + bool loadFromSection(const IniFile::Section §ion); - std::string id; + bool loadSeries(const std::filesystem::path &folder) const; - std::shared_ptr series = std::make_shared(); - mutable Properties properties; -}; + void saveProperties(IniFile &ini) const; + + bool saveSeries(const std::string &path) const; + + std::string id; + + std::shared_ptr series = std::make_shared(); + mutable Properties properties; + 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 90f8fafbce..5feb768185 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 @@ -21,29 +21,35 @@ #pragma once #include -#include #include #include "cluster.h" +#include "AdditionalConstraint.h" -namespace Antares::Data::ShortTermStorage -{ -class STStorageInput -{ -public: - bool validate() const; - /// 1. Read list.ini - bool createSTStorageClustersFromIniFile(const std::filesystem::path& path); - /// 2. Read ALL series - bool loadSeriesFromFolder(const std::filesystem::path& folder) const; - /// Number of enabled ST storages, ignoring disabled ST storages - std::size_t count() const; - /// erase disabled cluster from the vector - uint removeDisabledClusters(); - - bool saveToFolder(const std::string& folder) const; - bool saveDataSeriesToFolder(const std::string& folder) const; - - std::vector storagesByIndex; -}; +namespace Antares::Data::ShortTermStorage { + class STStorageInput { + public: + bool validate() const; + + /// 1. Read list.ini + bool createSTStorageClustersFromIniFile(const std::filesystem::path &path); + + /// 2. Read ALL series + bool loadSeriesFromFolder(const std::filesystem::path &folder) const; + + /// Number of enabled ST storages, ignoring disabled ST storages + std::size_t count() const; + + bool LoadConstraintsFromIniFile(const std::filesystem::path &filePath + ); + + /// erase disabled cluster from the vector + uint removeDisabledClusters(); + + bool saveToFolder(const std::string &folder) const; + + bool saveDataSeriesToFolder(const std::string &folder) const; + + std::vector storagesByIndex; + }; } // 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/AdditionalConstraint.cpp new file mode 100644 index 0000000000..302d25552c --- /dev/null +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp @@ -0,0 +1,42 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** 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 + +namespace Antares::Data::ShortTermStorage +{ +bool AdditionalConstraint::validate() const +{ + if (cluster_id.empty()) + return false; + + if (variable != "injection" && variable != "withdrawal" && variable != "netting") + return false; + + if (operatorType != "less" && operatorType != "equal" && operatorType != "greater") + return false; + + if (hours.empty() || *std::min_element(hours.begin(), hours.end()) < 1 || *std::max_element(hours.begin(), hours.end()) > 168) + return false; + + return true; +} +} // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/short-term-storage/cluster.cpp b/src/libs/antares/study/parts/short-term-storage/cluster.cpp index 787d1c85e6..50128bfe27 100644 --- a/src/libs/antares/study/parts/short-term-storage/cluster.cpp +++ b/src/libs/antares/study/parts/short-term-storage/cluster.cpp @@ -26,71 +26,56 @@ #include #include -namespace Antares::Data::ShortTermStorage -{ - -bool STStorageCluster::loadFromSection(const IniFile::Section& section) -{ - if (!section.firstProperty) - { - return false; - } - - for (auto* property = section.firstProperty; property; property = property->next) - { - if (property->key.empty()) - { - logs.warning() << "Loading clusters: `" << section.name << "`: Invalid key/value"; - continue; - } - if (!properties.loadKey(property)) - { - logs.warning() << "Loading clusters: `" << section.name << "`/`" << property->key - << "`: The property is unknown and ignored"; +namespace Antares::Data::ShortTermStorage { + bool STStorageCluster::loadFromSection(const IniFile::Section §ion) { + if (!section.firstProperty) { + return false; } - } - - if (properties.name.empty()) - { - return false; - } - id = transformNameIntoID(properties.name); + for (auto *property = section.firstProperty; property; property = property->next) { + if (property->key.empty()) { + logs.warning() << "Loading clusters: `" << section.name << "`: Invalid key/value"; + continue; + } + if (!properties.loadKey(property)) { + logs.warning() << "Loading clusters: `" << section.name << "`/`" << property->key + << "`: The property is unknown and ignored"; + } + } - return true; -} + if (properties.name.empty()) { + return false; + } -bool STStorageCluster::enabled() const -{ - return properties.enabled; -} + id = transformNameIntoID(properties.name); -bool STStorageCluster::validate() const -{ - if (!enabled()) - { return true; } - logs.debug() << "Validating properties and series for st storage: " << id; - return properties.validate() && series->validate(id); -} + bool STStorageCluster::enabled() const { + return properties.enabled; + } + + bool STStorageCluster::validate() const { + if (!enabled()) { + return true; + } -bool STStorageCluster::loadSeries(const std::filesystem::path& folder) const -{ - bool ret = series->loadFromFolder(folder); - series->fillDefaultSeriesIfEmpty(); // fill series if no file series - return ret; -} + logs.debug() << "Validating properties and series for st storage: " << id; + return properties.validate() && series->validate(id); + } -void STStorageCluster::saveProperties(IniFile& ini) const -{ - properties.save(ini); -} + bool STStorageCluster::loadSeries(const std::filesystem::path &folder) const { + bool ret = series->loadFromFolder(folder); + series->fillDefaultSeriesIfEmpty(); // fill series if no file series + return ret; + } -bool STStorageCluster::saveSeries(const std::string& path) const -{ - return series->saveToFolder(path); -} + void STStorageCluster::saveProperties(IniFile &ini) const { + properties.save(ini); + } + bool STStorageCluster::saveSeries(const std::string &path) const { + return series->saveToFolder(path); + } } // 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 bee1546ec4..6c3cd6338e 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -27,101 +27,145 @@ #include #include +#include #define SEP Yuni::IO::Separator namespace fs = std::filesystem; -namespace Antares::Data::ShortTermStorage -{ -bool STStorageInput::validate() const -{ - return std::ranges::all_of(storagesByIndex, [](auto& cluster) { return cluster.validate(); }); -} - -bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) -{ - const fs::path pathIni = path / "list.ini"; - IniFile ini; - if (!ini.open(pathIni)) - { - return false; +namespace Antares::Data::ShortTermStorage { + bool STStorageInput::validate() const { + return std::ranges::all_of(storagesByIndex, [](auto &cluster) { return cluster.validate(); }); } - if (!ini.firstSection) - { + bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path &path) { + const fs::path pathIni = path / "list.ini"; + IniFile ini; + if (!ini.open(pathIni)) { + return false; + } + + if (!ini.firstSection) { + return true; + } + + logs.debug() << " :: loading `" << pathIni << "`"; + + for (auto *section = ini.firstSection; section; section = section->next) { + STStorageCluster cluster; + if (!cluster.loadFromSection(*section)) { + return false; + } + + storagesByIndex.push_back(cluster); + } + + std::ranges::sort(storagesByIndex, + [](const auto &a, const auto &b) { return a.properties.name < b.properties.name; }); + return true; } - logs.debug() << " :: loading `" << pathIni << "`"; - - for (auto* section = ini.firstSection; section; section = section->next) - { - STStorageCluster cluster; - if (!cluster.loadFromSection(*section)) - { + bool STStorageInput::LoadConstraintsFromIniFile(const fs::path &parent_path) { + IniFile ini; + const auto pathIni = parent_path / "additional-constraints.ini"; + if (!ini.open(pathIni)) { + logs.error() << "Failed to open INI file: " << pathIni; return false; } - storagesByIndex.push_back(cluster); + for (auto *section = ini.firstSection; section; section = section->next) { + AdditionalConstraint constraint; + + for (auto *property = section->firstProperty; property; property = property->next) { + const std::string key = property->key; + const auto value = property->value; + + if (key == "cluster") { + // TODO do i have to transform the name to id? TransformNameIntoID + std::string clusterName; + value.to(clusterName); + constraint.cluster_id = transformNameIntoID(clusterName); + } else if (key == "variable") { + value.to(constraint.variable); + } else if (key == "operator") + value.to(constraint.operatorType); + else if (key == "hours") { + // std::string raw_value; + // value.to(raw_value); + std::stringstream ss(value.c_str()); + std::string hour; + while (std::getline(ss, hour, ',')) { + int hourVal = std::stoi(hour); + constraint.hours.push_back(hourVal); + } + } else if (key == "rhs") + property->value.to(constraint.rhs); + } + + if (!constraint.validate()) { + logs.error() << "Invalid constraint in section: " << section->name; + return false; + } + + + //TODO not the fastest way + for (auto &cluster: storagesByIndex) { + if (cluster.id == constraint.cluster_id) { + cluster.additional_constraints.push_back(constraint); + } else { + logs.warning() << " from file " << pathIni; + logs.warning() << "Constraint " << section->name << + "does not reference an existing cluster (" << cluster.id << + "),\n therefore it is ignored!"; + } + } + } + + return true; } - std::ranges::sort(storagesByIndex, - [](const auto& a, const auto& b) - { return a.properties.name < b.properties.name; }); - return true; -} + bool STStorageInput::loadSeriesFromFolder(const fs::path &folder) const { + if (folder.empty()) { + return false; + } + + bool ret = true; + + for (auto &cluster: storagesByIndex) { + fs::path seriesFolder = folder / cluster.id; + ret = cluster.loadSeries(seriesFolder) && ret; + } -bool STStorageInput::loadSeriesFromFolder(const fs::path& folder) const -{ - if (folder.empty()) - { - return false; + return ret; } - bool ret = true; + bool STStorageInput::saveToFolder(const std::string &folder) const { + // create empty list.ini if there's no sts in this area + Yuni::IO::Directory::Create(folder); + const std::string pathIni(folder + SEP + "list.ini"); + IniFile ini; + + logs.debug() << "saving file " << pathIni; + std::ranges::for_each(storagesByIndex, + [&ini](auto &storage) { return storage.saveProperties(ini); }); + + return ini.save(pathIni); + } - for (auto& cluster: storagesByIndex) - { - fs::path seriesFolder = folder / cluster.id; - ret = cluster.loadSeries(seriesFolder) && ret; + bool STStorageInput::saveDataSeriesToFolder(const std::string &folder) const { + Yuni::IO::Directory::Create(folder); + return std::ranges::all_of(storagesByIndex, + [&folder](auto &storage) { return storage.saveSeries(folder + SEP + storage.id); }); } - return ret; -} - -bool STStorageInput::saveToFolder(const std::string& folder) const -{ - // create empty list.ini if there's no sts in this area - Yuni::IO::Directory::Create(folder); - const std::string pathIni(folder + SEP + "list.ini"); - IniFile ini; - - logs.debug() << "saving file " << pathIni; - std::ranges::for_each(storagesByIndex, - [&ini](auto& storage) { return storage.saveProperties(ini); }); - - return ini.save(pathIni); -} - -bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const -{ - Yuni::IO::Directory::Create(folder); - return std::ranges::all_of(storagesByIndex, - [&folder](auto& storage) - { return storage.saveSeries(folder + SEP + storage.id); }); -} - -std::size_t STStorageInput::count() const -{ - return std::ranges::count_if(storagesByIndex, - [](const STStorageCluster& st) { return st.properties.enabled; }); -} - -uint STStorageInput::removeDisabledClusters() -{ - return std::erase_if(storagesByIndex, [](const auto& c) { return !c.enabled(); }); -} + std::size_t STStorageInput::count() const { + return std::ranges::count_if(storagesByIndex, + [](const STStorageCluster &st) { return st.properties.enabled; }); + } + uint STStorageInput::removeDisabledClusters() { + return std::erase_if(storagesByIndex, [](const auto &c) { return !c.enabled(); }); + } } // namespace Antares::Data::ShortTermStorage From 96caff51f09b4884c9b24f514a2721ae316552e6 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 13 Dec 2024 12:29:19 +0100 Subject: [PATCH 02/27] format --- .../AdditionalConstraint.cpp | 12 +- .../parts/short-term-storage/cluster.cpp | 93 ++++--- .../parts/short-term-storage/container.cpp | 250 ++++++++++-------- 3 files changed, 206 insertions(+), 149 deletions(-) diff --git a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp index 302d25552c..d3ad08e45e 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp @@ -19,6 +19,7 @@ ** along with Antares_Simulator. If not, see . */ #include "antares/study/parts/short-term-storage/AdditionalConstraint.h" + #include namespace Antares::Data::ShortTermStorage @@ -26,16 +27,25 @@ namespace Antares::Data::ShortTermStorage bool AdditionalConstraint::validate() const { if (cluster_id.empty()) + { return false; + } if (variable != "injection" && variable != "withdrawal" && variable != "netting") + { return false; + } if (operatorType != "less" && operatorType != "equal" && operatorType != "greater") + { return false; + } - if (hours.empty() || *std::min_element(hours.begin(), hours.end()) < 1 || *std::max_element(hours.begin(), hours.end()) > 168) + if (hours.empty() || *std::min_element(hours.begin(), hours.end()) < 1 + || *std::max_element(hours.begin(), hours.end()) > 168) + { return false; + } return true; } diff --git a/src/libs/antares/study/parts/short-term-storage/cluster.cpp b/src/libs/antares/study/parts/short-term-storage/cluster.cpp index 50128bfe27..cbfb7e679f 100644 --- a/src/libs/antares/study/parts/short-term-storage/cluster.cpp +++ b/src/libs/antares/study/parts/short-term-storage/cluster.cpp @@ -26,56 +26,69 @@ #include #include -namespace Antares::Data::ShortTermStorage { - bool STStorageCluster::loadFromSection(const IniFile::Section §ion) { - if (!section.firstProperty) { - return false; - } +namespace Antares::Data::ShortTermStorage +{ +bool STStorageCluster::loadFromSection(const IniFile::Section& section) +{ + if (!section.firstProperty) + { + return false; + } - for (auto *property = section.firstProperty; property; property = property->next) { - if (property->key.empty()) { - logs.warning() << "Loading clusters: `" << section.name << "`: Invalid key/value"; - continue; - } - if (!properties.loadKey(property)) { - logs.warning() << "Loading clusters: `" << section.name << "`/`" << property->key - << "`: The property is unknown and ignored"; - } + for (auto* property = section.firstProperty; property; property = property->next) + { + if (property->key.empty()) + { + logs.warning() << "Loading clusters: `" << section.name << "`: Invalid key/value"; + continue; } - - if (properties.name.empty()) { - return false; + if (!properties.loadKey(property)) + { + logs.warning() << "Loading clusters: `" << section.name << "`/`" << property->key + << "`: The property is unknown and ignored"; } - - id = transformNameIntoID(properties.name); - - return true; } - bool STStorageCluster::enabled() const { - return properties.enabled; + if (properties.name.empty()) + { + return false; } - bool STStorageCluster::validate() const { - if (!enabled()) { - return true; - } + id = transformNameIntoID(properties.name); - logs.debug() << "Validating properties and series for st storage: " << id; - return properties.validate() && series->validate(id); - } + return true; +} - bool STStorageCluster::loadSeries(const std::filesystem::path &folder) const { - bool ret = series->loadFromFolder(folder); - series->fillDefaultSeriesIfEmpty(); // fill series if no file series - return ret; - } +bool STStorageCluster::enabled() const +{ + return properties.enabled; +} - void STStorageCluster::saveProperties(IniFile &ini) const { - properties.save(ini); +bool STStorageCluster::validate() const +{ + if (!enabled()) + { + return true; } - bool STStorageCluster::saveSeries(const std::string &path) const { - return series->saveToFolder(path); - } + logs.debug() << "Validating properties and series for st storage: " << id; + return properties.validate() && series->validate(id); +} + +bool STStorageCluster::loadSeries(const std::filesystem::path& folder) const +{ + bool ret = series->loadFromFolder(folder); + series->fillDefaultSeriesIfEmpty(); // fill series if no file series + return ret; +} + +void STStorageCluster::saveProperties(IniFile& ini) const +{ + properties.save(ini); +} + +bool STStorageCluster::saveSeries(const std::string& path) const +{ + return series->saveToFolder(path); +} } // 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 6c3cd6338e..823bcf5575 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -33,139 +33,173 @@ namespace fs = std::filesystem; -namespace Antares::Data::ShortTermStorage { - bool STStorageInput::validate() const { - return std::ranges::all_of(storagesByIndex, [](auto &cluster) { return cluster.validate(); }); +namespace Antares::Data::ShortTermStorage +{ +bool STStorageInput::validate() const +{ + return std::ranges::all_of(storagesByIndex, [](auto& cluster) { return cluster.validate(); }); +} + +bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path& path) +{ + const fs::path pathIni = path / "list.ini"; + IniFile ini; + if (!ini.open(pathIni)) + { + return false; } - bool STStorageInput::createSTStorageClustersFromIniFile(const fs::path &path) { - const fs::path pathIni = path / "list.ini"; - IniFile ini; - if (!ini.open(pathIni)) { - return false; - } - - if (!ini.firstSection) { - return true; - } - - logs.debug() << " :: loading `" << pathIni << "`"; + if (!ini.firstSection) + { + return true; + } - for (auto *section = ini.firstSection; section; section = section->next) { - STStorageCluster cluster; - if (!cluster.loadFromSection(*section)) { - return false; - } + logs.debug() << " :: loading `" << pathIni << "`"; - storagesByIndex.push_back(cluster); + for (auto* section = ini.firstSection; section; section = section->next) + { + STStorageCluster cluster; + if (!cluster.loadFromSection(*section)) + { + return false; } - std::ranges::sort(storagesByIndex, - [](const auto &a, const auto &b) { return a.properties.name < b.properties.name; }); - - return true; + storagesByIndex.push_back(cluster); } - bool STStorageInput::LoadConstraintsFromIniFile(const fs::path &parent_path) { - IniFile ini; - const auto pathIni = parent_path / "additional-constraints.ini"; - if (!ini.open(pathIni)) { - logs.error() << "Failed to open INI file: " << pathIni; - return false; - } + std::ranges::sort(storagesByIndex, + [](const auto& a, const auto& b) + { return a.properties.name < b.properties.name; }); + + return true; +} + +bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) +{ + IniFile ini; + const auto pathIni = parent_path / "additional-constraints.ini"; + if (!ini.open(pathIni)) + { + logs.error() << "Failed to open INI file: " << pathIni; + return false; + } - for (auto *section = ini.firstSection; section; section = section->next) { - AdditionalConstraint constraint; - - for (auto *property = section->firstProperty; property; property = property->next) { - const std::string key = property->key; - const auto value = property->value; - - if (key == "cluster") { - // TODO do i have to transform the name to id? TransformNameIntoID - std::string clusterName; - value.to(clusterName); - constraint.cluster_id = transformNameIntoID(clusterName); - } else if (key == "variable") { - value.to(constraint.variable); - } else if (key == "operator") - value.to(constraint.operatorType); - else if (key == "hours") { - // std::string raw_value; - // value.to(raw_value); - std::stringstream ss(value.c_str()); - std::string hour; - while (std::getline(ss, hour, ',')) { - int hourVal = std::stoi(hour); - constraint.hours.push_back(hourVal); - } - } else if (key == "rhs") - property->value.to(constraint.rhs); + for (auto* section = ini.firstSection; section; section = section->next) + { + AdditionalConstraint constraint; + + for (auto* property = section->firstProperty; property; property = property->next) + { + const std::string key = property->key; + const auto value = property->value; + + if (key == "cluster") + { + // TODO do i have to transform the name to id? TransformNameIntoID + std::string clusterName; + value.to(clusterName); + constraint.cluster_id = transformNameIntoID(clusterName); } - - if (!constraint.validate()) { - logs.error() << "Invalid constraint in section: " << section->name; - return false; + else if (key == "variable") + { + value.to(constraint.variable); } - - - //TODO not the fastest way - for (auto &cluster: storagesByIndex) { - if (cluster.id == constraint.cluster_id) { - cluster.additional_constraints.push_back(constraint); - } else { - logs.warning() << " from file " << pathIni; - logs.warning() << "Constraint " << section->name << - "does not reference an existing cluster (" << cluster.id << - "),\n therefore it is ignored!"; + else if (key == "operator") + { + value.to(constraint.operatorType); + } + else if (key == "hours") + { + // std::string raw_value; + // value.to(raw_value); + std::stringstream ss(value.c_str()); + std::string hour; + while (std::getline(ss, hour, ',')) + { + int hourVal = std::stoi(hour); + constraint.hours.push_back(hourVal); } } + else if (key == "rhs") + { + property->value.to(constraint.rhs); + } } - return true; - } - - - bool STStorageInput::loadSeriesFromFolder(const fs::path &folder) const { - if (folder.empty()) { + if (!constraint.validate()) + { + logs.error() << "Invalid constraint in section: " << section->name; return false; } - bool ret = true; - - for (auto &cluster: storagesByIndex) { - fs::path seriesFolder = folder / cluster.id; - ret = cluster.loadSeries(seriesFolder) && ret; + // TODO not the fastest way + for (auto& cluster: storagesByIndex) + { + if (cluster.id == constraint.cluster_id) + { + cluster.additional_constraints.push_back(constraint); + } + else + { + logs.warning() << " from file " << pathIni; + logs.warning() << "Constraint " << section->name + << "does not reference an existing cluster (" << cluster.id + << "),\n therefore it is ignored!"; + } } - - return ret; } - bool STStorageInput::saveToFolder(const std::string &folder) const { - // create empty list.ini if there's no sts in this area - Yuni::IO::Directory::Create(folder); - const std::string pathIni(folder + SEP + "list.ini"); - IniFile ini; + return true; +} - logs.debug() << "saving file " << pathIni; - std::ranges::for_each(storagesByIndex, - [&ini](auto &storage) { return storage.saveProperties(ini); }); - - return ini.save(pathIni); +bool STStorageInput::loadSeriesFromFolder(const fs::path& folder) const +{ + if (folder.empty()) + { + return false; } - bool STStorageInput::saveDataSeriesToFolder(const std::string &folder) const { - Yuni::IO::Directory::Create(folder); - return std::ranges::all_of(storagesByIndex, - [&folder](auto &storage) { return storage.saveSeries(folder + SEP + storage.id); }); - } + bool ret = true; - std::size_t STStorageInput::count() const { - return std::ranges::count_if(storagesByIndex, - [](const STStorageCluster &st) { return st.properties.enabled; }); + for (auto& cluster: storagesByIndex) + { + fs::path seriesFolder = folder / cluster.id; + ret = cluster.loadSeries(seriesFolder) && ret; } - uint STStorageInput::removeDisabledClusters() { - return std::erase_if(storagesByIndex, [](const auto &c) { return !c.enabled(); }); - } + return ret; +} + +bool STStorageInput::saveToFolder(const std::string& folder) const +{ + // create empty list.ini if there's no sts in this area + Yuni::IO::Directory::Create(folder); + const std::string pathIni(folder + SEP + "list.ini"); + IniFile ini; + + logs.debug() << "saving file " << pathIni; + std::ranges::for_each(storagesByIndex, + [&ini](auto& storage) { return storage.saveProperties(ini); }); + + return ini.save(pathIni); +} + +bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const +{ + Yuni::IO::Directory::Create(folder); + return std::ranges::all_of(storagesByIndex, + [&folder](auto& storage) + { return storage.saveSeries(folder + SEP + storage.id); }); +} + +std::size_t STStorageInput::count() const +{ + return std::ranges::count_if(storagesByIndex, + [](const STStorageCluster& st) { return st.properties.enabled; }); +} + +uint STStorageInput::removeDisabledClusters() +{ + return std::erase_if(storagesByIndex, [](const auto& c) { return !c.enabled(); }); +} } // namespace Antares::Data::ShortTermStorage From d2123e69353c44cd57110075f973ea561d966500 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 13 Dec 2024 12:30:54 +0100 Subject: [PATCH 03/27] commit file --- .../short-term-storage/AdditionalConstraint.h | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraint.h 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/AdditionalConstraint.h new file mode 100644 index 0000000000..6b413d81b9 --- /dev/null +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/AdditionalConstraint.h @@ -0,0 +1,36 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include +#include + +namespace Antares::Data::ShortTermStorage { + struct AdditionalConstraint { + std::string cluster_id; + std::string variable; + std::string operatorType; + std::vector hours; + double rhs; + + bool validate() const; + }; +} // namespace Antares::Data::ShortTermStorage From 0cfd4abdd9cf26aa36946e3a02507610efe36178 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 13 Dec 2024 13:39:08 +0100 Subject: [PATCH 04/27] update --- src/libs/antares/study/area/list.cpp | 1 + .../short-term-storage/AdditionalConstraint.h | 1 + .../parts/short-term-storage/container.cpp | 2 +- .../opt_decompte_variables_et_contraintes.cpp | 38 +++++++++++-------- .../sim_structure_probleme_economique.h | 2 +- .../simulation/sim_calcul_economique.cpp | 2 +- 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index cf2624515f..7af3a6a5a7 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1199,6 +1199,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) fs::path folder = stsFolder / "clusters" / area->id.c_str(); ret = area->shortTermStorage.createSTStorageClustersFromIniFile(folder) && ret; + ret = area->shortTermStorage.LoadConstraintsFromIniFile(folder) && ret; } } else 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/AdditionalConstraint.h index 6b413d81b9..65ace7da11 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/AdditionalConstraint.h @@ -25,6 +25,7 @@ namespace Antares::Data::ShortTermStorage { struct AdditionalConstraint { + std::string name; std::string cluster_id; std::string variable; std::string operatorType; 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 823bcf5575..3bfe7e40a5 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -87,7 +87,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) for (auto* section = ini.firstSection; section; section = section->next) { AdditionalConstraint constraint; - + constraint.name = section->name.c_str(); for (auto* property = section->firstProperty; property; property = property->next) { const std::string key = property->key; diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index d1a0f00ea2..490d14d062 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -144,12 +144,12 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes += 2; /* 2 constraints bounding the overall energy generated over the period (10a in the reference document) */ - ProblemeAResoudre - ->NombreDeContraintes++; /* 1 constraint setting the level variation over the period - (10b in the reference document) */ - ProblemeAResoudre - ->NombreDeContraintes++; /* 1 constraint bounding the overall energy pumped over the - period (10c in the reference document) */ + ProblemeAResoudre->NombreDeContraintes++; + /* 1 constraint setting the level variation over the period + (10b in the reference document) */ + ProblemeAResoudre->NombreDeContraintes++; + /* 1 constraint bounding the overall energy pumped over the + period (10c in the reference document) */ } if (!Pump && TurbEntreBornes && !MonitorHourlyLev) @@ -192,16 +192,16 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes += 2; /* 2 constraints bounding the overall energy generated over the period (10a in the reference document) */ - ProblemeAResoudre - ->NombreDeContraintes++; /* 1 constraint setting the level variation over the period - (10b in the reference document) */ - ProblemeAResoudre - ->NombreDeContraintes++; /* 1 constraint bounding the overall energy pumped over the - period (10c in the reference document) */ - ProblemeAResoudre->NombreDeContraintes - += nombreDePasDeTempsPourUneOptimisation; /* T constraints expressing the level hourly - variations (14a in the reference - document) */ + ProblemeAResoudre->NombreDeContraintes++; + /* 1 constraint setting the level variation over the period + (10b in the reference document) */ + ProblemeAResoudre->NombreDeContraintes++; + /* 1 constraint bounding the overall energy pumped over the + period (10c in the reference document) */ + ProblemeAResoudre->NombreDeContraintes += nombreDePasDeTempsPourUneOptimisation; + /* T constraints expressing the level hourly + variations (14a in the reference + document) */ } if (!Pump && !TurbEntreBornes && MonitorHourlyLev) { @@ -245,6 +245,12 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes += 2 * nombreDePasDeTempsPourUneOptimisation; } + if (!storage.additional_constraints.empty()) + { + ProblemeAResoudre->NombreDeContraintes + += storage.additional_constraints.size() + * nombreDePasDeTempsPourUneOptimisation; + } } } } 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 d24fb25bc4..46468650b6 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 @@ -182,7 +182,7 @@ struct PROPERTIES bool penalizeVariationInjection; std::shared_ptr series; - + 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 3d29d3ee42..c6c36b1b14 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -59,7 +59,7 @@ static void importShortTermStorages( toInsert.penalizeVariationInjection = st.properties.penalizeVariationInjection; toInsert.penalizeVariationWithdrawal = st.properties.penalizeVariationWithdrawal; toInsert.name = st.properties.name; - + toInsert.additional_constraints = st.additional_constraints; toInsert.series = st.series; // TODO add missing properties, or use the same struct From b5b63a31dd5a68fe1f186db89120f7feb508e808 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Fri, 13 Dec 2024 17:44:22 +0100 Subject: [PATCH 05/27] update --- .../parts/short-term-storage/container.h | 3 + .../include/antares/study/runtime/runtime.h | 1 + .../parts/short-term-storage/container.cpp | 9 ++ src/libs/antares/study/runtime/runtime.cpp | 2 + src/solver/optimisation/CMakeLists.txt | 2 + .../ShortTermStorageCumulation.cpp | 94 +++++++++++++++++++ .../constraints/ConstraintBuilder.h | 5 + .../constraints/ShortTermStorageCumulation.h | 44 +++++++++ .../solver/optimisation/opt_rename_problem.h | 10 ++ .../optimisation/opt_rename_problem.cpp | 18 +++- .../simulation/sim_alloc_probleme_hebdo.h | 2 + .../sim_structure_probleme_economique.h | 1 + .../simulation/sim_alloc_probleme_hebdo.cpp | 10 ++ 13 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp create mode 100644 src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h 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 5feb768185..b087ff738f 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 @@ -51,5 +51,8 @@ namespace Antares::Data::ShortTermStorage { bool saveDataSeriesToFolder(const std::string &folder) const; std::vector storagesByIndex; + + /// Number cumulative - constraint + std::size_t cumulativeConstraintCount() const; }; } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/include/antares/study/runtime/runtime.h b/src/libs/antares/study/include/antares/study/runtime/runtime.h index 858719ab27..fe394199df 100644 --- a/src/libs/antares/study/include/antares/study/runtime/runtime.h +++ b/src/libs/antares/study/include/antares/study/runtime/runtime.h @@ -110,6 +110,7 @@ class StudyRuntimeInfos uint thermalPlantTotalCountMustRun; uint shortTermStorageCount = 0; + uint shortTermStorageCumulativeConstraintCount = 0; //! Override enable/disable TS generation per cluster bool thermalTSRefresh = false; 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 3bfe7e40a5..cff38dedbe 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -192,6 +192,15 @@ bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const { return storage.saveSeries(folder + SEP + storage.id); }); } +std::size_t STStorageInput::cumulativeConstraintCount() const +{ + size_t result = 0; + for (const auto& cluster: storagesByIndex) + { + result += cluster.additional_constraints.size(); + } +} + std::size_t STStorageInput::count() const { return std::ranges::count_if(storagesByIndex, diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 3bca4404a5..f571a8330b 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -94,6 +94,8 @@ static void StudyRuntimeInfosInitializeAllAreas(Study& study, StudyRuntimeInfos& r.thermalPlantTotalCountMustRun += area.thermal.list.enabledAndMustRunCount(); r.shortTermStorageCount += area.shortTermStorage.count(); + r.shortTermStorageCumulativeConstraintCount += area.shortTermStorage. + cumulativeConstraintCount(); } } diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index 57194b388a..ec98f298e8 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -82,7 +82,9 @@ set(RTESOLVER_OPT include/antares/solver/optimisation/constraints/ShortTermStorageLevel.h constraints/ShortTermStorageLevel.cpp include/antares/solver/optimisation/constraints/ShortTermStorageCostVariation.h + include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h constraints/ShortTermStorageCostVariation.cpp + constraints/ShortTermStorageCumulation.cpp constraints/ShortTermStorageCostVariationInjectionForward.cpp constraints/ShortTermStorageCostVariationInjectionBackward.cpp constraints/ShortTermStorageCostVariationWithdrawalForward.cpp diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp new file mode 100644 index 0000000000..926100c7bc --- /dev/null +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -0,0 +1,94 @@ +/* +* Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include "antares/solver/optimisation/constraints/ShortTermStorageCumulation.h" + +void ShortTermStorageCumulation::Injection(unsigned int index, +const ::ShortTermStorage::PROPERTIES& input + ){ + builder.ShortTermStorageInjection(index, 1.0); + } +void ShortTermStorageCumulation::Withdrawal(unsigned int index, +const ::ShortTermStorage::PROPERTIES& input + ){ + builder.ShortTermStorageWithdrawal(index, 1.0);} +void ShortTermStorageCumulation::Netting(unsigned int index, + const ::ShortTermStorage::PROPERTIES& input){ + + + builder.ShortTermStorageInjection(index, input.injectionEfficiency ). + ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); + } +auto getMemberFunction = [](const std::string& name) +-> void (ShortTermStorageCumulation::*)(unsigned int, + const ::ShortTermStorage::PROPERTIES& ) { + if (name == "withdrawal") { + return &ShortTermStorageCumulation::Withdrawal; + } else if (name == "injection") { + return &ShortTermStorageCumulation::Injection; + } + else if (name == "netting"){ + return &ShortTermStorageCumulation::Netting; + } + return nullptr; // Return null if no match + }; + + +char ConvertSign(const std::string& sign){ + if (sign == "greater") { + return '>'; + } + else if (sign == "less") { + return '<'; + } + else { + return '='; + } +} + +void ShortTermStorageCumulation::add(int pays){ + + ConstraintNamer namer(builder.data.NomDesContraintes); + namer.UpdateArea(builder.data.NomsDesPays[pays]); + + for (const auto& storage: data.ShortTermStorage[pays]) + { + for(const auto& constraint: storage.additional_constraints){ + + //sum (var[h]) sign rhs, h in list provied by user + + namer.ShortTermStorageLevel(builder.data.nombreDeContraintes, storage.name); + const auto index = storage.clusterGlobalIndex; + //TODO + data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] + = builder.data.nombreDeContraintes; + auto memberFunction = getMemberFunction(constraint.variable); + for (const auto& hour: constraint.hours){ + const int hourInTheYear = builder.data.weekInTheYear * 168 + hour-1; + builder.updateHourWithinWeek(hour-1); + (this->*memberFunction)(index, storage); + builder.SetOperator(ConvertSign(constraint.operatorType)) + .build(); + } + } + } +} diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h index b06af4614d..c819d30cc3 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h @@ -305,3 +305,8 @@ struct ShortTermStorageData const std::vector<::ShortTermStorage::AREA_INPUT>& ShortTermStorage; }; + +struct ShortTermStorageCumulativeConstraintData: ShortTermStorageData +{ + CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES CorrespondanceCntNativesCntOptimHebdomadaires; +}; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h new file mode 100644 index 0000000000..99bbea0584 --- /dev/null +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h @@ -0,0 +1,44 @@ +/* + * Copyright 2007-2024, RTE (https://www.rte-france.com) + * See AUTHORS.txt + * SPDX-License-Identifier: MPL-2.0 + * This file is part of Antares-Simulator, + * Adequacy and Performance assessment for interconnected energy networks. + * + * Antares_Simulator is free software: you can redistribute it and/or modify + * it under the terms of the Mozilla Public Licence 2.0 as published by + * the Mozilla Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Antares_Simulator is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Mozilla Public Licence 2.0 for more details. + * + * You should have received a copy of the Mozilla Public Licence 2.0 + * along with Antares_Simulator. If not, see . + */ + +#pragma once +#include "ConstraintBuilder.h" + +class ShortTermStorageCumulation: private ConstraintFactory +{ +public: + ShortTermStorageCumulation(ConstraintBuilder& builder, ShortTermStorageCumulativeConstraintData& data): + ConstraintFactory(builder), + data(data) + { + } + + void add(int pays); + void Injection(unsigned int index, + const ::ShortTermStorage::PROPERTIES& input); + void Withdrawal(unsigned int index, + const ::ShortTermStorage::PROPERTIES& input); + void Netting(unsigned int index, + const ::ShortTermStorage::PROPERTIES& input); + +private: + ShortTermStorageCumulativeConstraintData& data; +}; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h index f05b6eb15a..c7c3dff284 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h @@ -166,6 +166,11 @@ class ConstraintNamer: public Namer unsigned int constraint, const std::string& short_term_name); + void ShortTermStorageCumulation(const std::string& constraint_type, + unsigned int constraint, + const std::string& short_term_name, + const std::string& constraint_name); + private: void nameWithTimeGranularity(unsigned int constraint, const std::string& name, @@ -177,6 +182,11 @@ inline std::string TimeIdentifier(unsigned int timeStep, const std::string& time return timeStepType + "<" + std::to_string(timeStep) + ">"; } +inline std::string ShortTermStorageCumulationIdentifier(const std::string& name) +{ + return "Constraint<" + name + ">"; +} + inline std::string LocationIdentifier(const std::string& location, const std::string& locationType) { return locationType + "<" + location + ">"; diff --git a/src/solver/optimisation/opt_rename_problem.cpp b/src/solver/optimisation/opt_rename_problem.cpp index a92553e5e6..1e17479147 100644 --- a/src/solver/optimisation/opt_rename_problem.cpp +++ b/src/solver/optimisation/opt_rename_problem.cpp @@ -35,9 +35,9 @@ const std::string AREA("area"); std::string BuildName(const std::string& name, const std::string& location, - const std::string& timeIdentifier) + const std::string& additional_identifier) { - std::string result = name + SEPARATOR + location + SEPARATOR + timeIdentifier; + std::string result = name + SEPARATOR + location + SEPARATOR + additional_identifier; std::replace(result.begin(), result.end(), ' ', '*'); return result; } @@ -414,3 +414,17 @@ void ConstraintNamer::ShortTermStorageCostVariation(const std::string& constrain TimeIdentifier(timeStep_, HOUR)), constraint); } + +void ConstraintNamer::ShortTermStorageCumulation(const std::string& constraint_type, + unsigned int constraint, + const std::string& short_term_name, + const std::string& constraint_name) +{ + targetUpdater_.UpdateTargetAtIndex(BuildName(constraint_type, + LocationIdentifier(area_, AREA) + SEPARATOR + + "ShortTermStorage" + "<" + short_term_name + + ">", + ShortTermStorageCumulationIdentifier( + constraint_name)), + constraint); +} diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_alloc_probleme_hebdo.h b/src/solver/simulation/include/antares/solver/simulation/sim_alloc_probleme_hebdo.h index f1ed9bca0c..a4517115a8 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_alloc_probleme_hebdo.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_alloc_probleme_hebdo.h @@ -39,6 +39,8 @@ void SIM_AllocationLinks(PROBLEME_HEBDO& problem, void SIM_AllocationConstraints(PROBLEME_HEBDO& problem, const Antares::Data::Study& study, unsigned NombreDePasDeTemps); +void SIM_AllocationShortermStorageCumulation(PROBLEME_HEBDO& problem, + const Antares::Data::Study& study); void SIM_AllocateAreas(PROBLEME_HEBDO& problem, const Antares::Data::Study& study, 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 46468650b6..35051ba2d5 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 @@ -111,6 +111,7 @@ struct CORRESPONDANCES_DES_CONTRAINTES_JOURNALIERES struct CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES { std::vector NumeroDeContrainteDesContraintesCouplantes; + std::vector ShortTermStorageCumulation; }; struct VALEURS_DE_NTC_ET_RESISTANCES diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index d735191ff7..85f361371f 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -38,6 +38,7 @@ void SIM_AllocationProblemeHebdo(const Data::Study& study, SIM_AllocationProblemePasDeTemps(problem, study, NombreDePasDeTemps); SIM_AllocationLinks(problem, study.runtime.interconnectionsCount(), NombreDePasDeTemps); SIM_AllocationConstraints(problem, study, NombreDePasDeTemps); + SIM_AllocationShortermStorageCumulation(problem, study); SIM_AllocateAreas(problem, study, NombreDePasDeTemps); } catch (const std::bad_alloc& e) @@ -245,6 +246,15 @@ void SIM_AllocationLinks(PROBLEME_HEBDO& problem, const uint linkCount, unsigned } } +void SIM_AllocationShortermStorageCumulation(PROBLEME_HEBDO& problem, + const Antares::Data::Study& study) +{ + problem.CorrespondanceCntNativesCntOptimHebdomadaires + .ShortTermStorageCumulation.assign( + study.runtime.shortTermStorageCumulativeConstraintCount, + 0); +} + void SIM_AllocationConstraints(PROBLEME_HEBDO& problem, const Antares::Data::Study& study, unsigned NombreDePasDeTemps) From 2f230761a693a9403d0f701ae5309794203d0029 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 09:48:47 +0100 Subject: [PATCH 06/27] update --- src/libs/antares/study/parts/short-term-storage/container.cpp | 1 + .../optimisation/constraints/ShortTermStorageCumulation.cpp | 1 + 2 files changed, 2 insertions(+) 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 cff38dedbe..0f9b68de82 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -199,6 +199,7 @@ std::size_t STStorageInput::cumulativeConstraintCount() const { result += cluster.additional_constraints.size(); } + return result; } std::size_t STStorageInput::count() const diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 926100c7bc..5dd0d15379 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -72,6 +72,7 @@ void ShortTermStorageCumulation::add(int pays){ for (const auto& storage: data.ShortTermStorage[pays]) { + // TODO global index for constraints for data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] for(const auto& constraint: storage.additional_constraints){ //sum (var[h]) sign rhs, h in list provied by user From 8109806a497fc87afcfec377fa21e52c7eee760e Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 11:27:13 +0100 Subject: [PATCH 07/27] update --- .../short-term-storage/AdditionalConstraint.h | 2 + .../parts/short-term-storage/container.cpp | 4 +- src/libs/antares/study/runtime/runtime.cpp | 2 + .../ShortTermStorageCumulation.cpp | 46 +++++++++++-------- .../simulation/sim_calcul_economique.cpp | 6 +++ 5 files changed, 40 insertions(+), 20 deletions(-) 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/AdditionalConstraint.h index 65ace7da11..85d054dfe8 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/AdditionalConstraint.h @@ -32,6 +32,8 @@ namespace Antares::Data::ShortTermStorage { std::vector hours; double rhs; + unsigned int globalIndex = 0; + bool validate() const; }; } // 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 0f9b68de82..8c9333b991 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -80,8 +80,8 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) const auto pathIni = parent_path / "additional-constraints.ini"; if (!ini.open(pathIni)) { - logs.error() << "Failed to open INI file: " << pathIni; - return false; + logs.info() << "There is no: " << pathIni; + return true; } for (auto* section = ini.firstSection; section; section = section->next) diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index f571a8330b..0c4daeefb4 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -365,6 +365,8 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) logs.info() << " thermal clusters: " << thermalPlantTotalCount; logs.info() << " thermal clusters (must-run): " << thermalPlantTotalCountMustRun; logs.info() << " short-term storages: " << shortTermStorageCount; + logs.info() << " short-term storage cumulative constraints count: " << + shortTermStorageCumulativeConstraintCount; logs.info() << " binding constraints: " << study.bindingConstraints.activeConstraints().size(); logs.info() << " geographic trimming:" << (gd.geographicTrimming ? "true" : "false"); diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 5dd0d15379..707698a6b6 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -39,18 +39,24 @@ void ShortTermStorageCumulation::Netting(unsigned int index, ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); } auto getMemberFunction = [](const std::string& name) --> void (ShortTermStorageCumulation::*)(unsigned int, - const ::ShortTermStorage::PROPERTIES& ) { - if (name == "withdrawal") { - return &ShortTermStorageCumulation::Withdrawal; - } else if (name == "injection") { - return &ShortTermStorageCumulation::Injection; - } - else if (name == "netting"){ - return &ShortTermStorageCumulation::Netting; - } - return nullptr; // Return null if no match - }; +-> std::pair +{ + if (name == "withdrawal") + { + return {"WithdrawalSum", &ShortTermStorageCumulation::Withdrawal}; + } + else if (name == "injection") + { + return {"InjectionSum", &ShortTermStorageCumulation::Injection}; + } + else if (name == "netting") + { + return {"NettingSum", &ShortTermStorageCumulation::Netting}; + } + return {"", nullptr}; // Return null if no match +}; char ConvertSign(const std::string& sign){ @@ -76,15 +82,19 @@ void ShortTermStorageCumulation::add(int pays){ for(const auto& constraint: storage.additional_constraints){ //sum (var[h]) sign rhs, h in list provied by user - - namer.ShortTermStorageLevel(builder.data.nombreDeContraintes, storage.name); + auto [constraintType,memberFunction] = getMemberFunction(constraint.variable); + namer.ShortTermStorageCumulation(constraintType, + builder.data.nombreDeContraintes, + storage.name, + constraint.name + ); const auto index = storage.clusterGlobalIndex; //TODO - data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] - = builder.data.nombreDeContraintes; - auto memberFunction = getMemberFunction(constraint.variable); + data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[constraint + .globalIndex] + = builder.data.nombreDeContraintes; + for (const auto& hour: constraint.hours){ - const int hourInTheYear = builder.data.weekInTheYear * 168 + hour-1; builder.updateHourWithinWeek(hour-1); (this->*memberFunction)(index, storage); builder.SetOperator(ConvertSign(constraint.operatorType)) diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index c6c36b1b14..786b1b5aa6 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -39,6 +39,7 @@ static void importShortTermStorages( std::vector<::ShortTermStorage::AREA_INPUT>& ShortTermStorageOut) { int clusterGlobalIndex = 0; + int clusterCumulativeConstraintGlobalIndex = 0; for (uint areaIndex = 0; areaIndex != areas.size(); areaIndex++) { ShortTermStorageOut[areaIndex].resize(areas[areaIndex]->shortTermStorage.count()); @@ -60,6 +61,11 @@ 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) + { + constraint.globalIndex = clusterCumulativeConstraintGlobalIndex; + ++clusterCumulativeConstraintGlobalIndex; + } toInsert.series = st.series; // TODO add missing properties, or use the same struct From af38876f480774b3bfcf2ad6150178b428abc8a6 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 11:41:11 +0100 Subject: [PATCH 08/27] no warnror --- src/libs/antares/study/parts/short-term-storage/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8c9333b991..991952d59f 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -78,7 +78,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) { IniFile ini; const auto pathIni = parent_path / "additional-constraints.ini"; - if (!ini.open(pathIni)) + if (!ini.open(pathIni, false)) { logs.info() << "There is no: " << pathIni; return true; From 8c49f56ae7bcd4fe79efb6418864029e85cee476 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 11:57:53 +0100 Subject: [PATCH 09/27] active cumulation constraints --- .../optimisation/constraints/Group1.cpp | 20 +++++++++++++++++++ .../constraints/ConstraintBuilder.h | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/solver/optimisation/constraints/Group1.cpp b/src/solver/optimisation/constraints/Group1.cpp index 810b957aee..741149d9be 100644 --- a/src/solver/optimisation/constraints/Group1.cpp +++ b/src/solver/optimisation/constraints/Group1.cpp @@ -22,6 +22,7 @@ #include "antares/solver/optimisation/constraints/Group1.h" #include "antares/solver/optimisation/constraints/ShortTermStorageCostVariation.h" +#include "antares/solver/optimisation/constraints/ShortTermStorageCumulation.h" AreaBalanceData Group1::GetAreaBalanceData() { @@ -49,6 +50,15 @@ ShortTermStorageData Group1::GetShortTermStorageData() }; } +ShortTermStorageCumulativeConstraintData Group1::ShortTermStorageCumulativeConstraintData() +{ + return { + problemeHebdo_->CorrespondanceCntNativesCntOptim, + problemeHebdo_->ShortTermStorage, + problemeHebdo_->CorrespondanceCntNativesCntOptimHebdomadaires + }; +} + FlowDissociationData Group1::GetFlowDissociationData() { return {.CorrespondanceCntNativesCntOptim = problemeHebdo_->CorrespondanceCntNativesCntOptim, @@ -89,6 +99,11 @@ void Group1::BuildConstraints() ShortTermStorageCostVariationWithdrawalForward shortTermStorageCostVariationWithdrawalForward( builder_, shortTermStorageData); + + auto shortTermStorageCumulativeConstraintData = GetShortTermStorageCumulativeConstraintData(); + ShortTermStorageCumulation shortTermStorageCumulation(builder_, + shortTermStorageCumulativeConstraintData); + auto flowDissociationData = GetFlowDissociationData(); FlowDissociation flowDissociation(builder_, flowDissociationData); @@ -123,4 +138,9 @@ void Group1::BuildConstraints() bindingConstraintHour.add(pdt, cntCouplante); } } + + for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; pays++) + { + shortTermStorageCumulation.add(pays); + } } diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h index c819d30cc3..31019332d3 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h @@ -308,5 +308,5 @@ struct ShortTermStorageData struct ShortTermStorageCumulativeConstraintData: ShortTermStorageData { - CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES CorrespondanceCntNativesCntOptimHebdomadaires; + CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondanceCntNativesCntOptimHebdomadaires; }; From 30579a7fc8d4b5012525a63daf3b3abdf5fb5410 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 11:58:18 +0100 Subject: [PATCH 10/27] add missing file --- .../include/antares/solver/optimisation/constraints/Group1.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h index e5134edb6e..c74567716e 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h @@ -38,6 +38,9 @@ class Group1: public ConstraintGroup AreaBalanceData GetAreaBalanceData(); FictitiousLoadData GetFictitiousLoadData(); ShortTermStorageData GetShortTermStorageData(); + + ShortTermStorageCumulativeConstraintData GetShortTermStorageCumulativeConstraintData(); + FlowDissociationData GetFlowDissociationData(); BindingConstraintHourData GetBindingConstraintHourData(); }; From 3addd90226523e717bad4ee3672031dda103c051 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 12:01:04 +0100 Subject: [PATCH 11/27] add data --- src/solver/optimisation/constraints/Group1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/optimisation/constraints/Group1.cpp b/src/solver/optimisation/constraints/Group1.cpp index 741149d9be..6c9620f3e0 100644 --- a/src/solver/optimisation/constraints/Group1.cpp +++ b/src/solver/optimisation/constraints/Group1.cpp @@ -50,7 +50,7 @@ ShortTermStorageData Group1::GetShortTermStorageData() }; } -ShortTermStorageCumulativeConstraintData Group1::ShortTermStorageCumulativeConstraintData() +ShortTermStorageCumulativeConstraintData Group1::GetShortTermStorageCumulativeConstraintData() { return { problemeHebdo_->CorrespondanceCntNativesCntOptim, From f141935208ef9513ebb5401349a3156304c346b8 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 12:17:31 +0100 Subject: [PATCH 12/27] update --- .../constraints/ShortTermStorageCumulation.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 707698a6b6..f10a686269 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -79,8 +79,8 @@ void ShortTermStorageCumulation::add(int pays){ for (const auto& storage: data.ShortTermStorage[pays]) { // TODO global index for constraints for data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] - for(const auto& constraint: storage.additional_constraints){ - + for (const auto& constraint: storage.additional_constraints) + { //sum (var[h]) sign rhs, h in list provied by user auto [constraintType,memberFunction] = getMemberFunction(constraint.variable); namer.ShortTermStorageCumulation(constraintType, @@ -94,12 +94,13 @@ void ShortTermStorageCumulation::add(int pays){ .globalIndex] = builder.data.nombreDeContraintes; - for (const auto& hour: constraint.hours){ - builder.updateHourWithinWeek(hour-1); - (this->*memberFunction)(index, storage); - builder.SetOperator(ConvertSign(constraint.operatorType)) - .build(); + for (const auto& hour: constraint.hours) + { + builder.updateHourWithinWeek(hour - 1); + (this->*memberFunction)(index, storage); } + builder.SetOperator(ConvertSign(constraint.operatorType)) + .build(); } } } From 02f25498287111dce0057d2f257abcd515c4f2b4 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 12:28:20 +0100 Subject: [PATCH 13/27] compute rhs --- ...opt_gestion_second_membre_cas_lineaire.cpp | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) 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 36bb303964..407074bd5e 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp @@ -43,6 +43,28 @@ static void shortTermStorageLevelsRHS( } } +static void shortTermStorageCumulationRHS( + const std::vector<::ShortTermStorage::AREA_INPUT>& shortTermStorageInput, + int numberOfAreas, + std::vector& SecondMembre, + const CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& + CorrespondancesDesContraintesHebdomadaires) +{ + for (int areaIndex = 0; areaIndex < numberOfAreas; areaIndex++) + { + for (auto& storage: shortTermStorageInput[areaIndex]) + { + for (const auto& constraint: storage.additional_constraints) + { + const int clusterGlobalIndex = storage.clusterGlobalIndex; + int cnt = CorrespondancesDesContraintesHebdomadaires.ShortTermStorageCumulation + [constraint.globalIndex]; + SecondMembre[cnt] = constraint.rhs; + } + } + } +} + void OPT_InitialiserLeSecondMembreDuProblemeLineaire(PROBLEME_HEBDO* problemeHebdo, int PremierPdtDeLIntervalle, int DernierPdtDeLIntervalle, @@ -145,7 +167,6 @@ void OPT_InitialiserLeSecondMembreDuProblemeLineaire(PROBLEME_HEBDO* problemeHeb ProblemeAResoudre->SecondMembre, CorrespondanceCntNativesCntOptim, hourInTheYear); - for (uint32_t interco = 0; interco < problemeHebdo->NombreDInterconnexions; interco++) { if (const COUTS_DE_TRANSPORT& CoutDeTransport = problemeHebdo->CoutDeTransport[interco]; @@ -377,6 +398,10 @@ void OPT_InitialiserLeSecondMembreDuProblemeLineaire(PROBLEME_HEBDO* problemeHeb } } + shortTermStorageCumulationRHS(problemeHebdo->ShortTermStorage, + problemeHebdo->NombreDePays, + ProblemeAResoudre->SecondMembre, + problemeHebdo->CorrespondanceCntNativesCntOptimHebdomadaires); if (problemeHebdo->OptimisationAvecCoutsDeDemarrage) { OPT_InitialiserLeSecondMembreDuProblemeLineaireCoutsDeDemarrage(problemeHebdo, From cdac67491f241198521b0d637445941050a0c5a2 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 15:16:39 +0100 Subject: [PATCH 14/27] update nb cnt --- .../optimisation/opt_decompte_variables_et_contraintes.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 490d14d062..79c29c58ab 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -247,9 +247,7 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* } if (!storage.additional_constraints.empty()) { - ProblemeAResoudre->NombreDeContraintes - += storage.additional_constraints.size() - * nombreDePasDeTempsPourUneOptimisation; + ProblemeAResoudre->NombreDeContraintes += storage.additional_constraints.size(); } } } From 81c2ab400e820d0f316551cb225ce9571346da1e Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 16:26:50 +0100 Subject: [PATCH 15/27] remove unused var --- .../optimisation/opt_gestion_second_membre_cas_lineaire.cpp | 1 - 1 file changed, 1 deletion(-) 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 407074bd5e..cfa41290a6 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp @@ -56,7 +56,6 @@ static void shortTermStorageCumulationRHS( { for (const auto& constraint: storage.additional_constraints) { - const int clusterGlobalIndex = storage.clusterGlobalIndex; int cnt = CorrespondancesDesContraintesHebdomadaires.ShortTermStorageCumulation [constraint.globalIndex]; SecondMembre[cnt] = constraint.rhs; From 2d129d8e15c6eadf342b117a956e2133e62725ec Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 16:32:02 +0100 Subject: [PATCH 16/27] remove unused var and apply clang-format --- .../short-term-storage/AdditionalConstraint.h | 24 +++--- .../study/parts/short-term-storage/cluster.h | 32 ++++---- .../parts/short-term-storage/container.h | 43 +++++----- src/libs/antares/study/runtime/runtime.cpp | 8 +- .../optimisation/constraints/Group1.cpp | 6 +- .../ShortTermStorageCumulation.cpp | 79 ++++++++++--------- .../constraints/ShortTermStorageCumulation.h | 12 ++- ...opt_gestion_second_membre_cas_lineaire.cpp | 13 ++- .../optimisation/opt_rename_problem.cpp | 13 ++- .../simulation/sim_alloc_probleme_hebdo.cpp | 6 +- 10 files changed, 119 insertions(+), 117 deletions(-) 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/AdditionalConstraint.h index 85d054dfe8..811c6b6e92 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/AdditionalConstraint.h @@ -23,17 +23,19 @@ #include #include -namespace Antares::Data::ShortTermStorage { - struct AdditionalConstraint { - std::string name; - std::string cluster_id; - std::string variable; - std::string operatorType; - std::vector hours; - double rhs; +namespace Antares::Data::ShortTermStorage +{ +struct AdditionalConstraint +{ + std::string name; + std::string cluster_id; + std::string variable; + std::string operatorType; + std::vector hours; + double rhs; - unsigned int globalIndex = 0; + unsigned int globalIndex = 0; - bool validate() const; - }; + bool validate() 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 03c45e04f8..df74a350b0 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,29 +26,31 @@ #include +#include "AdditionalConstraint.h" #include "properties.h" #include "series.h" -#include "AdditionalConstraint.h" -namespace Antares::Data::ShortTermStorage { - class STStorageCluster { - public: - bool enabled() const; +namespace Antares::Data::ShortTermStorage +{ +class STStorageCluster +{ +public: + bool enabled() const; - bool validate() const; + bool validate() const; - bool loadFromSection(const IniFile::Section §ion); + bool loadFromSection(const IniFile::Section& section); - bool loadSeries(const std::filesystem::path &folder) const; + bool loadSeries(const std::filesystem::path& folder) const; - void saveProperties(IniFile &ini) const; + void saveProperties(IniFile& ini) const; - bool saveSeries(const std::string &path) const; + bool saveSeries(const std::string& path) const; - std::string id; + std::string id; - std::shared_ptr series = std::make_shared(); - mutable Properties properties; - std::vector additional_constraints; - }; + std::shared_ptr series = std::make_shared(); + mutable Properties properties; + 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 b087ff738f..d4e0233b5c 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,36 +23,37 @@ #include #include -#include "cluster.h" #include "AdditionalConstraint.h" +#include "cluster.h" -namespace Antares::Data::ShortTermStorage { - class STStorageInput { - public: - bool validate() const; +namespace Antares::Data::ShortTermStorage +{ +class STStorageInput +{ +public: + bool validate() const; - /// 1. Read list.ini - bool createSTStorageClustersFromIniFile(const std::filesystem::path &path); + /// 1. Read list.ini + bool createSTStorageClustersFromIniFile(const std::filesystem::path& path); - /// 2. Read ALL series - bool loadSeriesFromFolder(const std::filesystem::path &folder) const; + /// 2. Read ALL series + bool loadSeriesFromFolder(const std::filesystem::path& folder) const; - /// Number of enabled ST storages, ignoring disabled ST storages - std::size_t count() const; + /// Number of enabled ST storages, ignoring disabled ST storages + std::size_t count() const; - bool LoadConstraintsFromIniFile(const std::filesystem::path &filePath - ); + bool LoadConstraintsFromIniFile(const std::filesystem::path& filePath); - /// erase disabled cluster from the vector - uint removeDisabledClusters(); + /// erase disabled cluster from the vector + uint removeDisabledClusters(); - bool saveToFolder(const std::string &folder) const; + bool saveToFolder(const std::string& folder) const; - bool saveDataSeriesToFolder(const std::string &folder) const; + bool saveDataSeriesToFolder(const std::string& folder) const; - std::vector storagesByIndex; + std::vector storagesByIndex; - /// Number cumulative - constraint - std::size_t cumulativeConstraintCount() const; - }; + /// Number cumulative - constraint + std::size_t cumulativeConstraintCount() const; +}; } // namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 0c4daeefb4..32bfb0f28e 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -94,8 +94,8 @@ static void StudyRuntimeInfosInitializeAllAreas(Study& study, StudyRuntimeInfos& r.thermalPlantTotalCountMustRun += area.thermal.list.enabledAndMustRunCount(); r.shortTermStorageCount += area.shortTermStorage.count(); - r.shortTermStorageCumulativeConstraintCount += area.shortTermStorage. - cumulativeConstraintCount(); + r.shortTermStorageCumulativeConstraintCount += area.shortTermStorage + .cumulativeConstraintCount(); } } @@ -365,8 +365,8 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) logs.info() << " thermal clusters: " << thermalPlantTotalCount; logs.info() << " thermal clusters (must-run): " << thermalPlantTotalCountMustRun; logs.info() << " short-term storages: " << shortTermStorageCount; - logs.info() << " short-term storage cumulative constraints count: " << - shortTermStorageCumulativeConstraintCount; + logs.info() << " short-term storage cumulative constraints count: " + << shortTermStorageCumulativeConstraintCount; logs.info() << " binding constraints: " << study.bindingConstraints.activeConstraints().size(); logs.info() << " geographic trimming:" << (gd.geographicTrimming ? "true" : "false"); diff --git a/src/solver/optimisation/constraints/Group1.cpp b/src/solver/optimisation/constraints/Group1.cpp index 6c9620f3e0..be8383d822 100644 --- a/src/solver/optimisation/constraints/Group1.cpp +++ b/src/solver/optimisation/constraints/Group1.cpp @@ -52,11 +52,9 @@ ShortTermStorageData Group1::GetShortTermStorageData() ShortTermStorageCumulativeConstraintData Group1::GetShortTermStorageCumulativeConstraintData() { - return { - problemeHebdo_->CorrespondanceCntNativesCntOptim, + return {problemeHebdo_->CorrespondanceCntNativesCntOptim, problemeHebdo_->ShortTermStorage, - problemeHebdo_->CorrespondanceCntNativesCntOptimHebdomadaires - }; + problemeHebdo_->CorrespondanceCntNativesCntOptimHebdomadaires}; } FlowDissociationData Group1::GetFlowDissociationData() diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index f10a686269..7df86685c1 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -1,5 +1,5 @@ /* -* Copyright 2007-2024, RTE (https://www.rte-france.com) + * Copyright 2007-2024, RTE (https://www.rte-france.com) * See AUTHORS.txt * SPDX-License-Identifier: MPL-2.0 * This file is part of Antares-Simulator, @@ -23,25 +23,28 @@ #include "antares/solver/optimisation/constraints/ShortTermStorageCumulation.h" void ShortTermStorageCumulation::Injection(unsigned int index, -const ::ShortTermStorage::PROPERTIES& input - ){ + const ::ShortTermStorage::PROPERTIES& input) +{ builder.ShortTermStorageInjection(index, 1.0); - } +} + void ShortTermStorageCumulation::Withdrawal(unsigned int index, -const ::ShortTermStorage::PROPERTIES& input - ){ - builder.ShortTermStorageWithdrawal(index, 1.0);} -void ShortTermStorageCumulation::Netting(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input){ + const ::ShortTermStorage::PROPERTIES& input) +{ + builder.ShortTermStorageWithdrawal(index, 1.0); +} +void ShortTermStorageCumulation::Netting(unsigned int index, + const ::ShortTermStorage::PROPERTIES& input) +{ + builder.ShortTermStorageInjection(index, input.injectionEfficiency) + .ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); +} - builder.ShortTermStorageInjection(index, input.injectionEfficiency ). - ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); - } auto getMemberFunction = [](const std::string& name) --> std::pair + -> std::pair { if (name == "withdrawal") { @@ -58,49 +61,51 @@ auto getMemberFunction = [](const std::string& name) return {"", nullptr}; // Return null if no match }; - -char ConvertSign(const std::string& sign){ - if (sign == "greater") { +char ConvertSign(const std::string& sign) +{ + if (sign == "greater") + { return '>'; } - else if (sign == "less") { - return '<'; - } - else { - return '='; - } + else if (sign == "less") + { + return '<'; + } + else + { + return '='; + } } -void ShortTermStorageCumulation::add(int pays){ - +void ShortTermStorageCumulation::add(int pays) +{ ConstraintNamer namer(builder.data.NomDesContraintes); namer.UpdateArea(builder.data.NomsDesPays[pays]); for (const auto& storage: data.ShortTermStorage[pays]) { - // TODO global index for constraints for data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] + // TODO global index for constraints for + // data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] for (const auto& constraint: storage.additional_constraints) { - //sum (var[h]) sign rhs, h in list provied by user - auto [constraintType,memberFunction] = getMemberFunction(constraint.variable); + // sum (var[h]) sign rhs, h in list provied by user + auto [constraintType, memberFunction] = getMemberFunction(constraint.variable); namer.ShortTermStorageCumulation(constraintType, builder.data.nombreDeContraintes, storage.name, - constraint.name - ); + constraint.name); const auto index = storage.clusterGlobalIndex; - //TODO - data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[constraint - .globalIndex] - = builder.data.nombreDeContraintes; + // TODO + data.CorrespondanceCntNativesCntOptimHebdomadaires + .ShortTermStorageCumulation[constraint.globalIndex] + = builder.data.nombreDeContraintes; for (const auto& hour: constraint.hours) { builder.updateHourWithinWeek(hour - 1); (this->*memberFunction)(index, storage); } - builder.SetOperator(ConvertSign(constraint.operatorType)) - .build(); + builder.SetOperator(ConvertSign(constraint.operatorType)).build(); } } } diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h index 99bbea0584..572ad77821 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h @@ -25,19 +25,17 @@ class ShortTermStorageCumulation: private ConstraintFactory { public: - ShortTermStorageCumulation(ConstraintBuilder& builder, ShortTermStorageCumulativeConstraintData& data): + ShortTermStorageCumulation(ConstraintBuilder& builder, + ShortTermStorageCumulativeConstraintData& data): ConstraintFactory(builder), data(data) { } void add(int pays); - void Injection(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input); - void Withdrawal(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input); - void Netting(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input); + void Injection(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); + void Withdrawal(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); + void Netting(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); private: ShortTermStorageCumulativeConstraintData& data; 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 cfa41290a6..c04d416f00 100644 --- a/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_second_membre_cas_lineaire.cpp @@ -44,11 +44,10 @@ static void shortTermStorageLevelsRHS( } static void shortTermStorageCumulationRHS( - const std::vector<::ShortTermStorage::AREA_INPUT>& shortTermStorageInput, - int numberOfAreas, - std::vector& SecondMembre, - const CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& - CorrespondancesDesContraintesHebdomadaires) + const std::vector<::ShortTermStorage::AREA_INPUT>& shortTermStorageInput, + int numberOfAreas, + std::vector& SecondMembre, + const CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondancesDesContraintesHebdomadaires) { for (int areaIndex = 0; areaIndex < numberOfAreas; areaIndex++) { @@ -56,8 +55,8 @@ static void shortTermStorageCumulationRHS( { for (const auto& constraint: storage.additional_constraints) { - int cnt = CorrespondancesDesContraintesHebdomadaires.ShortTermStorageCumulation - [constraint.globalIndex]; + int cnt = CorrespondancesDesContraintesHebdomadaires + .ShortTermStorageCumulation[constraint.globalIndex]; SecondMembre[cnt] = constraint.rhs; } } diff --git a/src/solver/optimisation/opt_rename_problem.cpp b/src/solver/optimisation/opt_rename_problem.cpp index 1e17479147..b385c0f8f5 100644 --- a/src/solver/optimisation/opt_rename_problem.cpp +++ b/src/solver/optimisation/opt_rename_problem.cpp @@ -420,11 +420,10 @@ void ConstraintNamer::ShortTermStorageCumulation(const std::string& constraint_t const std::string& short_term_name, const std::string& constraint_name) { - targetUpdater_.UpdateTargetAtIndex(BuildName(constraint_type, - LocationIdentifier(area_, AREA) + SEPARATOR - + "ShortTermStorage" + "<" + short_term_name - + ">", - ShortTermStorageCumulationIdentifier( - constraint_name)), - constraint); + targetUpdater_.UpdateTargetAtIndex( + BuildName(constraint_type, + LocationIdentifier(area_, AREA) + SEPARATOR + "ShortTermStorage" + "<" + + short_term_name + ">", + ShortTermStorageCumulationIdentifier(constraint_name)), + constraint); } diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 85f361371f..78785f0fd3 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -249,10 +249,8 @@ void SIM_AllocationLinks(PROBLEME_HEBDO& problem, const uint linkCount, unsigned void SIM_AllocationShortermStorageCumulation(PROBLEME_HEBDO& problem, const Antares::Data::Study& study) { - problem.CorrespondanceCntNativesCntOptimHebdomadaires - .ShortTermStorageCumulation.assign( - study.runtime.shortTermStorageCumulativeConstraintCount, - 0); + problem.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation + .assign(study.runtime.shortTermStorageCumulativeConstraintCount, 0); } void SIM_AllocationConstraints(PROBLEME_HEBDO& problem, From 7fa9009ad07f49c5c06457ec02d9192ad95cbd91 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 17:46:39 +0100 Subject: [PATCH 17/27] update --- .../short-term-storage/AdditionalConstraint.h | 18 ++++++++++--- .../AdditionalConstraint.cpp | 27 ++++++++++++++++--- .../parts/short-term-storage/container.cpp | 3 ++- 3 files changed, 40 insertions(+), 8 deletions(-) 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/AdditionalConstraint.h index 811c6b6e92..2f3252aeed 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/AdditionalConstraint.h @@ -21,21 +21,33 @@ #pragma once #include -#include +#include namespace Antares::Data::ShortTermStorage { -struct AdditionalConstraint + + struct AdditionalConstraint { std::string name; std::string cluster_id; std::string variable; std::string operatorType; - std::vector hours; + std::set hours; double rhs; unsigned int globalIndex = 0; bool validate() const; + + bool isValidVariable() const; + + bool isValidOperatorType() const; + + bool isValidHoursRange() const; + + mutable std::string error_message = ""; + + std::string getErrorMessage() const { return error_message; } + }; } // 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/AdditionalConstraint.cpp index d3ad08e45e..c74e70c812 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp @@ -28,25 +28,44 @@ bool AdditionalConstraint::validate() const { if (cluster_id.empty()) { + error_message = "Cluster ID is empty."; return false; } - if (variable != "injection" && variable != "withdrawal" && variable != "netting") + if (!isValidVariable()) { + error_message = "Invalid variable type. Must be 'injection', 'withdrawal', or 'netting'."; return false; } - if (operatorType != "less" && operatorType != "equal" && operatorType != "greater") + if (!isValidOperatorType()) { + error_message = "Invalid operator type. Must be 'less', 'equal', or 'greater'."; return false; } - if (hours.empty() || *std::min_element(hours.begin(), hours.end()) < 1 - || *std::max_element(hours.begin(), hours.end()) > 168) + if (!isValidHoursRange()) { + error_message = "Hours set contains invalid values. Must be between 1 and 168."; return false; } + error_message.clear(); return true; } + + bool AdditionalConstraint::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; + + } + + bool AdditionalConstraint::isValidVariable() const { + return variable == "injection" || variable == "withdrawal" || variable == "netting"; + } + + bool AdditionalConstraint::isValidOperatorType() const { + return operatorType == "less" || operatorType == "equal" || operatorType == "greater"; + } } // 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 991952d59f..fedc0c98e4 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -117,7 +117,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) while (std::getline(ss, hour, ',')) { int hourVal = std::stoi(hour); - constraint.hours.push_back(hourVal); + constraint.hours.insert(hourVal); } } else if (key == "rhs") @@ -129,6 +129,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) if (!constraint.validate()) { logs.error() << "Invalid constraint in section: " << section->name; + logs.error() << constraint.getErrorMessage(); return false; } From e422a1740034625b4ae8eeaedfb4a79a417694ba Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Mon, 16 Dec 2024 17:50:57 +0100 Subject: [PATCH 18/27] print proper error message --- .../short-term-storage/AdditionalConstraint.h | 20 +++++++------- .../AdditionalConstraint.cpp | 27 +++++++++---------- 2 files changed, 24 insertions(+), 23 deletions(-) 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/AdditionalConstraint.h index 2f3252aeed..8373de0be2 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/AdditionalConstraint.h @@ -20,34 +20,36 @@ */ #pragma once -#include #include +#include namespace Antares::Data::ShortTermStorage { - struct AdditionalConstraint +struct AdditionalConstraint { std::string name; std::string cluster_id; std::string variable; std::string operatorType; - std::set hours; + std::set hours; double rhs; unsigned int globalIndex = 0; bool validate() const; - bool isValidVariable() const; - - bool isValidOperatorType() const; + bool isValidVariable() const; - bool isValidHoursRange() const; + bool isValidOperatorType() const; - mutable std::string error_message = ""; + bool isValidHoursRange() const; - std::string getErrorMessage() const { return error_message; } + mutable std::string error_message = ""; + std::string getErrorMessage() const + { + return error_message; + } }; } // 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/AdditionalConstraint.cpp index c74e70c812..c0f3972a78 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp @@ -20,8 +20,6 @@ */ #include "antares/study/parts/short-term-storage/AdditionalConstraint.h" -#include - namespace Antares::Data::ShortTermStorage { bool AdditionalConstraint::validate() const @@ -54,18 +52,19 @@ bool AdditionalConstraint::validate() const return true; } - bool AdditionalConstraint::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; - - } +bool AdditionalConstraint::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; +} - bool AdditionalConstraint::isValidVariable() const { - return variable == "injection" || variable == "withdrawal" || variable == "netting"; - } +bool AdditionalConstraint::isValidVariable() const +{ + return variable == "injection" || variable == "withdrawal" || variable == "netting"; +} - bool AdditionalConstraint::isValidOperatorType() const { - return operatorType == "less" || operatorType == "equal" || operatorType == "greater"; - } +bool AdditionalConstraint::isValidOperatorType() const +{ + return operatorType == "less" || operatorType == "equal" || operatorType == "greater"; +} } // namespace Antares::Data::ShortTermStorage From 938d7269b809e347004f0b5257db306e0db3b4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 17 Dec 2024 13:56:47 +0100 Subject: [PATCH 19/27] Fix find cluster logic (#2537) --- .../parts/short-term-storage/container.cpp | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 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 fedc0c98e4..3b3de48cbe 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -133,20 +133,19 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) return false; } - // TODO not the fastest way - for (auto& cluster: storagesByIndex) + auto it = std::find_if(storagesByIndex.begin(), + storagesByIndex.end(), + [&constraint](const STStorageCluster& cluster) + {return cluster.id == constraint.cluster_id; }); + if (it == storagesByIndex.end()) { - if (cluster.id == constraint.cluster_id) - { - cluster.additional_constraints.push_back(constraint); - } - else - { - logs.warning() << " from file " << pathIni; - logs.warning() << "Constraint " << section->name - << "does not reference an existing cluster (" << cluster.id - << "),\n therefore it is ignored!"; - } + logs.warning() << " from file " << pathIni; + logs.warning() << "Constraint " << section->name + << " does not reference an existing cluster"; + } + else + { + it->additional_constraints.push_back(constraint); } } From 5fea2ae966b9fb40c5ea3ed409d3285808c6b74b Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Tue, 17 Dec 2024 14:05:29 +0100 Subject: [PATCH 20/27] Formatting --- src/libs/antares/study/parts/short-term-storage/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3b3de48cbe..609b55e1b5 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -136,7 +136,7 @@ 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; }); + { return cluster.id == constraint.cluster_id; }); if (it == storagesByIndex.end()) { logs.warning() << " from file " << pathIni; From 25f008892ea024f60ed4a4732f101dd8d4abc15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Tue, 17 Dec 2024 14:15:51 +0100 Subject: [PATCH 21/27] Remove getMemberFunction, use factory pattern (#2536) --- .../ShortTermStorageCumulation.cpp | 104 +++++++++++++----- .../constraints/ShortTermStorageCumulation.h | 3 - 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index 7df86685c1..f428b113ee 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -19,48 +19,94 @@ * along with Antares_Simulator. If not, see . */ -#pragma once #include "antares/solver/optimisation/constraints/ShortTermStorageCumulation.h" -void ShortTermStorageCumulation::Injection(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input) -{ - builder.ShortTermStorageInjection(index, 1.0); -} +#include +#include -void ShortTermStorageCumulation::Withdrawal(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input) +class CumulationConstraint { - builder.ShortTermStorageWithdrawal(index, 1.0); -} +public: + virtual void build(ConstraintBuilder& builder, + unsigned int index, + const ::ShortTermStorage::PROPERTIES& input) const + = 0; + virtual std::string name() const = 0; + virtual ~CumulationConstraint() = default; +}; -void ShortTermStorageCumulation::Netting(unsigned int index, - const ::ShortTermStorage::PROPERTIES& input) +class WithdrawalCumulationConstraint: public CumulationConstraint { - builder.ShortTermStorageInjection(index, input.injectionEfficiency) - .ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); -} +public: + void build(ConstraintBuilder& builder, + unsigned int index, + const ::ShortTermStorage::PROPERTIES&) const override + { + builder.ShortTermStorageWithdrawal(index, 1.0); + } -auto getMemberFunction = [](const std::string& name) - -> std::pair + std::string name() const override + { + return "WithdrawalSum"; + } + + virtual ~WithdrawalCumulationConstraint() = default; +}; + +class InjectionCumulationConstraint: public CumulationConstraint { - if (name == "withdrawal") +public: + void build(ConstraintBuilder& builder, + unsigned int index, + const ::ShortTermStorage::PROPERTIES&) const override + { + builder.ShortTermStorageInjection(index, 1.0); + } + + std::string name() const override { - return {"WithdrawalSum", &ShortTermStorageCumulation::Withdrawal}; + return "InjectionSum"; } - else if (name == "injection") + + virtual ~InjectionCumulationConstraint() = default; +}; + +class NettingCumulationConstraint: public CumulationConstraint +{ +public: + void build(ConstraintBuilder& builder, + unsigned int index, + const ::ShortTermStorage::PROPERTIES& input) const override { - return {"InjectionSum", &ShortTermStorageCumulation::Injection}; + builder.ShortTermStorageInjection(index, input.injectionEfficiency) + .ShortTermStorageWithdrawal(index, -input.withdrawalEfficiency); } - else if (name == "netting") + + std::string name() const override { - return {"NettingSum", &ShortTermStorageCumulation::Netting}; + return "NettingSum"; } - return {"", nullptr}; // Return null if no match + + virtual ~NettingCumulationConstraint() = default; }; +std::unique_ptr cumulationConstraintFromVariable(const std::string& variable) +{ + if (variable == "withdrawal") + { + return std::make_unique(); + } + else if (variable == "injection") + { + return std::make_unique(); + } + else if (variable == "netting") + { + return std::make_unique(); + } + throw std::invalid_argument("Invalid cumulation constraint type"); +} + char ConvertSign(const std::string& sign) { if (sign == "greater") @@ -89,8 +135,8 @@ void ShortTermStorageCumulation::add(int pays) for (const auto& constraint: storage.additional_constraints) { // sum (var[h]) sign rhs, h in list provied by user - auto [constraintType, memberFunction] = getMemberFunction(constraint.variable); - namer.ShortTermStorageCumulation(constraintType, + auto constraintHelper = cumulationConstraintFromVariable(constraint.variable); + namer.ShortTermStorageCumulation(constraintHelper->name(), builder.data.nombreDeContraintes, storage.name, constraint.name); @@ -103,7 +149,7 @@ void ShortTermStorageCumulation::add(int pays) for (const auto& hour: constraint.hours) { builder.updateHourWithinWeek(hour - 1); - (this->*memberFunction)(index, storage); + constraintHelper->build(builder, index, storage); } builder.SetOperator(ConvertSign(constraint.operatorType)).build(); } diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h index 572ad77821..5aa710b956 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h @@ -33,9 +33,6 @@ class ShortTermStorageCumulation: private ConstraintFactory } void add(int pays); - void Injection(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); - void Withdrawal(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); - void Netting(unsigned int index, const ::ShortTermStorage::PROPERTIES& input); private: ShortTermStorageCumulativeConstraintData& data; From db1e44f543a0a5dadf1517537d543396620a858b Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Tue, 17 Dec 2024 14:44:16 +0100 Subject: [PATCH 22/27] upd --- .../study/parts/short-term-storage/container.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 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 609b55e1b5..5eb2971359 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -22,6 +22,7 @@ #include "antares/study/parts/short-term-storage/container.h" #include +#include #include #include @@ -194,12 +195,13 @@ bool STStorageInput::saveDataSeriesToFolder(const std::string& folder) const std::size_t STStorageInput::cumulativeConstraintCount() const { - size_t result = 0; - for (const auto& cluster: storagesByIndex) - { - result += cluster.additional_constraints.size(); - } - return result; + return std::accumulate(storagesByIndex.begin(), + storagesByIndex.end(), + 0., + [](double acc, const auto& cluster) + { + return cluster.additional_constraints.size(); + }); } std::size_t STStorageInput::count() const From 2dc8d749ac839f040c1dd8642a92eb5e77e89559 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 18 Dec 2024 16:57:20 +0100 Subject: [PATCH 23/27] fix constraint count --- .../study/parts/short-term-storage/container.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 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 5eb2971359..5af19456ed 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -111,8 +111,6 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) } else if (key == "hours") { - // std::string raw_value; - // value.to(raw_value); std::stringstream ss(value.c_str()); std::string hour; while (std::getline(ss, hour, ',')) @@ -129,9 +127,9 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) if (!constraint.validate()) { - logs.error() << "Invalid constraint in section: " << section->name; - logs.error() << constraint.getErrorMessage(); - return false; + throw std::runtime_error( + "Invalid constraint in section: " + section->name + "\n" + constraint. + getErrorMessage()); } auto it = std::find_if(storagesByIndex.begin(), @@ -197,10 +195,10 @@ std::size_t STStorageInput::cumulativeConstraintCount() const { return std::accumulate(storagesByIndex.begin(), storagesByIndex.end(), - 0., - [](double acc, const auto& cluster) + 0, + [](int acc, const auto& cluster) { - return cluster.additional_constraints.size(); + return acc + cluster.additional_constraints.size(); }); } From df8a20f1afa0156c8323c72462a7a672dff0dbf3 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 18 Dec 2024 17:05:29 +0100 Subject: [PATCH 24/27] update --- src/solver/optimisation/constraints/Group1.cpp | 2 +- .../constraints/ShortTermStorageCumulation.cpp | 14 +++++++------- .../constraints/ShortTermStorageCumulation.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/solver/optimisation/constraints/Group1.cpp b/src/solver/optimisation/constraints/Group1.cpp index be8383d822..61de7cf2b3 100644 --- a/src/solver/optimisation/constraints/Group1.cpp +++ b/src/solver/optimisation/constraints/Group1.cpp @@ -137,7 +137,7 @@ void Group1::BuildConstraints() } } - for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; pays++) + for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; ++pays) { shortTermStorageCumulation.add(pays); } diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index f428b113ee..c44413318b 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -50,7 +50,7 @@ class WithdrawalCumulationConstraint: public CumulationConstraint return "WithdrawalSum"; } - virtual ~WithdrawalCumulationConstraint() = default; + ~WithdrawalCumulationConstraint() override = default; }; class InjectionCumulationConstraint: public CumulationConstraint @@ -68,7 +68,7 @@ class InjectionCumulationConstraint: public CumulationConstraint return "InjectionSum"; } - virtual ~InjectionCumulationConstraint() = default; + ~InjectionCumulationConstraint() override = default; }; class NettingCumulationConstraint: public CumulationConstraint @@ -87,7 +87,7 @@ class NettingCumulationConstraint: public CumulationConstraint return "NettingSum"; } - virtual ~NettingCumulationConstraint() = default; + ~NettingCumulationConstraint() override = default; }; std::unique_ptr cumulationConstraintFromVariable(const std::string& variable) @@ -130,18 +130,18 @@ void ShortTermStorageCumulation::add(int pays) for (const auto& storage: data.ShortTermStorage[pays]) { - // TODO global index for constraints for - // data.CorrespondanceCntNativesCntOptimHebdomadaires.ShortTermStorageCumulation[index] for (const auto& constraint: storage.additional_constraints) { - // sum (var[h]) sign rhs, h in list provied by user + // 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; - // TODO data.CorrespondanceCntNativesCntOptimHebdomadaires .ShortTermStorageCumulation[constraint.globalIndex] = builder.data.nombreDeContraintes; diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h index 5aa710b956..2c4c540158 100644 --- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h +++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ShortTermStorageCumulation.h @@ -22,7 +22,7 @@ #pragma once #include "ConstraintBuilder.h" -class ShortTermStorageCumulation: private ConstraintFactory +class ShortTermStorageCumulation: ConstraintFactory { public: ShortTermStorageCumulation(ConstraintBuilder& builder, From 9719ae85aac6fe0fb040eae9d0fc987eb694949c Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 18 Dec 2024 17:09:49 +0100 Subject: [PATCH 25/27] format --- .../antares/study/parts/short-term-storage/container.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 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 5af19456ed..db2bbbf070 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -127,9 +127,8 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) if (!constraint.validate()) { - throw std::runtime_error( - "Invalid constraint in section: " + section->name + "\n" + constraint. - getErrorMessage()); + throw std::runtime_error("Invalid constraint in section: " + section->name + "\n" + + constraint.getErrorMessage()); } auto it = std::find_if(storagesByIndex.begin(), @@ -197,9 +196,7 @@ std::size_t STStorageInput::cumulativeConstraintCount() const storagesByIndex.end(), 0, [](int acc, const auto& cluster) - { - return acc + cluster.additional_constraints.size(); - }); + { return acc + cluster.additional_constraints.size(); }); } std::size_t STStorageInput::count() const From f7878b01f7d2dee5a0f26b6512bbf44ac88b4f60 Mon Sep 17 00:00:00 2001 From: Abdoulbari Zakir Date: Wed, 18 Dec 2024 17:15:04 +0100 Subject: [PATCH 26/27] update --- .../constraints/ShortTermStorageCumulation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp index c44413318b..f6e684db83 100644 --- a/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp +++ b/src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp @@ -107,13 +107,13 @@ std::unique_ptr cumulationConstraintFromVariable(const std throw std::invalid_argument("Invalid cumulation constraint type"); } -char ConvertSign(const std::string& sign) +char ConvertSense(const std::string& sense) { - if (sign == "greater") + if (sense == "greater") { return '>'; } - else if (sign == "less") + else if (sense == "less") { return '<'; } @@ -151,7 +151,7 @@ void ShortTermStorageCumulation::add(int pays) builder.updateHourWithinWeek(hour - 1); constraintHelper->build(builder, index, storage); } - builder.SetOperator(ConvertSign(constraint.operatorType)).build(); + builder.SetOperator(ConvertSense(constraint.operatorType)).build(); } } } From 9a81f67ca82d7ae55315a5c86f071c234c2eddc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Thu, 19 Dec 2024 13:26:36 +0100 Subject: [PATCH 27/27] Remove getErrorMessage, use dedicated struct (#2542) --- .../short-term-storage/AdditionalConstraint.h | 18 ++++++++---------- .../AdditionalConstraint.cpp | 17 ++++++----------- .../parts/short-term-storage/container.cpp | 8 +++++--- 3 files changed, 19 insertions(+), 24 deletions(-) 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/AdditionalConstraint.h index 8373de0be2..e16b991a05 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/AdditionalConstraint.h @@ -37,19 +37,17 @@ struct AdditionalConstraint unsigned int globalIndex = 0; - bool validate() const; + struct ValidateResult + { + bool ok; + std::string error_msg; + }; - bool isValidVariable() const; + ValidateResult validate() const; +private: + bool isValidVariable() const; bool isValidOperatorType() const; - bool isValidHoursRange() const; - - mutable std::string error_message = ""; - - std::string getErrorMessage() const - { - return error_message; - } }; } // 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/AdditionalConstraint.cpp index c0f3972a78..2ca904041c 100644 --- a/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp +++ b/src/libs/antares/study/parts/short-term-storage/AdditionalConstraint.cpp @@ -22,34 +22,29 @@ namespace Antares::Data::ShortTermStorage { -bool AdditionalConstraint::validate() const +AdditionalConstraint::ValidateResult AdditionalConstraint::validate() const { if (cluster_id.empty()) { - error_message = "Cluster ID is empty."; - return false; + return {false, "Cluster ID is empty."}; } if (!isValidVariable()) { - error_message = "Invalid variable type. Must be 'injection', 'withdrawal', or 'netting'."; - return false; + return {false, "Invalid variable type. Must be 'injection', 'withdrawal', or 'netting'."}; } if (!isValidOperatorType()) { - error_message = "Invalid operator type. Must be 'less', 'equal', or 'greater'."; - return false; + return {false, "Invalid operator type. Must be 'less', 'equal', or 'greater'."}; } if (!isValidHoursRange()) { - error_message = "Hours set contains invalid values. Must be between 1 and 168."; - return false; + return {false, "Hours set contains invalid values. Must be between 1 and 168."}; } - error_message.clear(); - return true; + return {true, ""}; } bool AdditionalConstraint::isValidHoursRange() const 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 db2bbbf070..39a958c5c7 100644 --- a/src/libs/antares/study/parts/short-term-storage/container.cpp +++ b/src/libs/antares/study/parts/short-term-storage/container.cpp @@ -125,10 +125,11 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) } } - if (!constraint.validate()) + if (auto ret = constraint.validate(); !ret.ok) { - throw std::runtime_error("Invalid constraint in section: " + section->name + "\n" - + constraint.getErrorMessage()); + logs.error() << "Invalid constraint in section: " << section->name; + logs.error() << ret.error_msg; + return false; } auto it = std::find_if(storagesByIndex.begin(), @@ -140,6 +141,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path) logs.warning() << " from file " << pathIni; logs.warning() << "Constraint " << section->name << " does not reference an existing cluster"; + return false; } else {