diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h index e6302680f8..238a25d425 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/series.h @@ -28,7 +28,7 @@ class Series { public: // check if series values are valid - bool validate() const; + bool validate(const std::string& id = "") const; // load all series files with folder path bool loadFromFolder(const std::string& folder); @@ -42,13 +42,17 @@ class Series std::vector lowerRuleCurve; std::vector upperRuleCurve; + std::vector costInjection; + std::vector costWithdrawal; + std::vector costLevel; + private: - bool validateSizes() const; - bool validateMaxInjection() const; - bool validateMaxWithdrawal() const; - bool validateRuleCurves() const; - bool validateUpperRuleCurve() const; - bool validateLowerRuleCurve() const; + bool validateSizes(const std::string&) const; + bool validateMaxInjection(const std::string&) const; + bool validateMaxWithdrawal(const std::string&) const; + bool validateRuleCurves(const std::string&) const; + bool validateUpperRuleCurve(const std::string&) const; + bool validateLowerRuleCurve(const std::string&) const; }; bool loadFile(const std::string& folder, std::vector& vect); 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 fe06ace18e..fc2ee8c263 100644 --- a/src/libs/antares/study/parts/short-term-storage/cluster.cpp +++ b/src/libs/antares/study/parts/short-term-storage/cluster.cpp @@ -73,7 +73,7 @@ bool STStorageCluster::validate() const } logs.debug() << "Validating properties and series for st storage: " << id; - return properties.validate() && series->validate(); + return properties.validate() && series->validate(id); } bool STStorageCluster::loadSeries(const std::string& folder) const diff --git a/src/libs/antares/study/parts/short-term-storage/series.cpp b/src/libs/antares/study/parts/short-term-storage/series.cpp index bda3bc0ed2..43354fff88 100644 --- a/src/libs/antares/study/parts/short-term-storage/series.cpp +++ b/src/libs/antares/study/parts/short-term-storage/series.cpp @@ -43,6 +43,10 @@ bool Series::loadFromFolder(const std::string& folder) ret = loadFile(folder + SEP + "lower-rule-curve.txt", lowerRuleCurve) && ret; ret = loadFile(folder + SEP + "upper-rule-curve.txt", upperRuleCurve) && ret; + ret = loadFile(folder + SEP + "cost-injection.txt", costInjection) && ret; + ret = loadFile(folder + SEP + "cost-withdrawal.txt", costWithdrawal) && ret; + ret = loadFile(folder + SEP + "cost-level.txt", costLevel) && ret; + return ret; } @@ -55,7 +59,7 @@ bool loadFile(const std::string& path, std::vector& vect) std::ifstream file; file.open(path); - if (!file) + if (!file.is_open()) { logs.debug() << "File not found: " << path; return true; @@ -112,6 +116,10 @@ void Series::fillDefaultSeriesIfEmpty() fillIfEmpty(inflows, 0.0); fillIfEmpty(lowerRuleCurve, 0.0); fillIfEmpty(upperRuleCurve, 1.0); + + fillIfEmpty(costInjection, 0.0); + fillIfEmpty(costWithdrawal, 0.0); + fillIfEmpty(costLevel, 0.0); } bool Series::saveToFolder(const std::string& folder) const @@ -134,6 +142,10 @@ bool Series::saveToFolder(const std::string& folder) const checkWrite("lower-rule-curve.txt", lowerRuleCurve); checkWrite("upper-rule-curve.txt", upperRuleCurve); + checkWrite("cost-injection.txt", costInjection); + checkWrite("cost-withdrawal.txt", costWithdrawal); + checkWrite("cost-level.txt", costLevel); + return ret; } @@ -158,47 +170,65 @@ bool writeVectorToFile(const std::string& path, const std::vector& vect) return true; } -bool Series::validate() const +bool Series::validate(const std::string& id) const { - return validateSizes() && validateMaxInjection() && validateMaxWithdrawal() - && validateRuleCurves(); + return validateSizes(id) && validateMaxInjection(id) && validateMaxWithdrawal(id) + && validateRuleCurves(id); } -static bool checkVectBetweenZeroOne(const std::vector& v, const std::string& name) +static bool checkVectBetweenZeroOne(const std::string& name, + const std::string& id, + const std::vector& v) { if (!std::all_of(v.begin(), v.end(), [](double d) { return (d >= 0.0 && d <= 1.0); })) { - logs.warning() << "Values for " << name << " series should be between 0 and 1"; + logs.warning() << "Short-term storage " << id << " Values for " << name + << " values should be between 0 and 1"; return false; } return true; } -bool Series::validateSizes() const +static bool checkSize(const std::string& seriesFilename, + const std::string& id, + const std::vector& v) { - if (maxInjectionModulation.size() != HOURS_PER_YEAR - || maxWithdrawalModulation.size() != HOURS_PER_YEAR || inflows.size() != HOURS_PER_YEAR - || lowerRuleCurve.size() != HOURS_PER_YEAR || upperRuleCurve.size() != HOURS_PER_YEAR) + if (v.size() != HOURS_PER_YEAR) { - logs.warning() << "Size of series for short term storage is wrong"; + logs.warning() << "Short-term storage " << id + << " Invalid size for file: " << seriesFilename << ". Got " << v.size() + << " lines, expected " << HOURS_PER_YEAR; return false; } + return true; } -bool Series::validateMaxInjection() const +bool Series::validateSizes(const std::string& id) const +{ + return checkSize("PMAX-injection.txt", id, maxInjectionModulation) + && checkSize("PMAX-withdrawal.txt", id, maxWithdrawalModulation) + && checkSize("inflows.txt", id, inflows) + && checkSize("lower-rule-curve.txt", id, lowerRuleCurve) + && checkSize("upper-rule-curve.txt", id, upperRuleCurve) + && checkSize("cost-injection.txt", id, costInjection) + && checkSize("cost-withdrawal.txt", id, costWithdrawal) + && checkSize("cost-level.txt", id, costLevel); +} + +bool Series::validateMaxInjection(const std::string& id) const { - return checkVectBetweenZeroOne(maxInjectionModulation, "PMAX injection"); + return checkVectBetweenZeroOne("PMAX injection", id, maxInjectionModulation); } -bool Series::validateMaxWithdrawal() const +bool Series::validateMaxWithdrawal(const std::string& id) const { - return checkVectBetweenZeroOne(maxWithdrawalModulation, "PMAX withdrawal"); + return checkVectBetweenZeroOne("PMAX withdrawal", id, maxWithdrawalModulation); } -bool Series::validateRuleCurves() const +bool Series::validateRuleCurves(const std::string& id) const { - if (!validateUpperRuleCurve() || !validateLowerRuleCurve()) + if (!validateUpperRuleCurve(id) || !validateLowerRuleCurve(id)) { return false; } @@ -207,21 +237,22 @@ bool Series::validateRuleCurves() const { if (lowerRuleCurve[i] > upperRuleCurve[i]) { - logs.warning() << "Lower rule curve greater than upper at line: " << i + 1; + logs.warning() << "Short-term storage " << id + << " Lower rule curve greater than upper at line: " << i + 1; return false; } } return true; } -bool Series::validateUpperRuleCurve() const +bool Series::validateUpperRuleCurve(const std::string& id) const { - return checkVectBetweenZeroOne(upperRuleCurve, "upper rule curve"); + return checkVectBetweenZeroOne("upper rule curve", id, upperRuleCurve); } -bool Series::validateLowerRuleCurve() const +bool Series::validateLowerRuleCurve(const std::string& id) const { - return checkVectBetweenZeroOne(maxInjectionModulation, "lower rule curve"); + return checkVectBetweenZeroOne("lower rule curve", id, maxInjectionModulation); } } // namespace Antares::Data::ShortTermStorage diff --git a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp index 857561f616..9831750143 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp @@ -24,7 +24,6 @@ #include "antares/solver/optimisation/opt_fonctions.h" #include "antares/solver/optimisation/opt_structure_probleme_a_resoudre.h" #include "antares/solver/simulation/sim_extern_variables_globales.h" -#include "antares/solver/simulation/sim_spread_generator.h" #include "antares/solver/simulation/sim_structure_donnees.h" #include "antares/solver/simulation/simulation.h" @@ -38,7 +37,6 @@ static void shortTermStorageCost( VariableManagement::VariableManager& variableManager, std::vector& linearCost) { - SIM::SpreadGenerator spreadGenerator; for (int pays = 0; pays < NombreDePays; ++pays) { for (const auto& storage: shortTermStorageInput[pays]) @@ -52,16 +50,15 @@ static void shortTermStorageCost( pdtJour); varLevel >= 0) { - linearCost[varLevel] = 0; + linearCost[varLevel] = storage.series->costLevel[pdtHebdo]; } - const double cost = spreadGenerator.generate(); if (const int varInjection = variableManager.ShortTermStorageInjection( clusterGlobalIndex, pdtJour); varInjection >= 0) { - linearCost[varInjection] = storage.withdrawalEfficiency * cost; + linearCost[varInjection] = storage.series->costInjection[pdtHebdo]; } if (const int varWithdrawal = variableManager.ShortTermStorageWithdrawal( @@ -69,7 +66,7 @@ static void shortTermStorageCost( pdtJour); varWithdrawal >= 0) { - linearCost[varWithdrawal] = storage.injectionEfficiency * cost; + linearCost[varWithdrawal] = storage.series->costWithdrawal[pdtHebdo]; } } } diff --git a/src/solver/simulation/CMakeLists.txt b/src/solver/simulation/CMakeLists.txt index fbfeb17f6a..d31ea04dfe 100644 --- a/src/solver/simulation/CMakeLists.txt +++ b/src/solver/simulation/CMakeLists.txt @@ -11,8 +11,6 @@ set(SRC_SIMULATION include/antares/solver/simulation/sim_structure_probleme_economique.h sim_variables_globales.cpp include/antares/solver/simulation/sim_constants.h - include/antares/solver/simulation/sim_spread_generator.h - sim_spread_generator.cpp include/antares/solver/simulation/simulation.h include/antares/solver/simulation/solver.h include/antares/solver/simulation/solver.hxx diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h b/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h deleted file mode 100644 index c28ec9a75a..0000000000 --- a/src/solver/simulation/include/antares/solver/simulation/sim_spread_generator.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 - -namespace SIM -{ -class SpreadGenerator -{ - static constexpr double rangeDefault = 1.e-3; - -public: - explicit SpreadGenerator(double range = rangeDefault); - void reset(unsigned int seed); - double generate(); - -private: - Antares::MersenneTwister mt_; - const double range_; -}; -} // namespace SIM diff --git a/src/solver/simulation/sim_spread_generator.cpp b/src/solver/simulation/sim_spread_generator.cpp deleted file mode 100644 index 734cb92da6..0000000000 --- a/src/solver/simulation/sim_spread_generator.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -** 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/solver/simulation/sim_spread_generator.h" - -namespace SIM -{ -SpreadGenerator::SpreadGenerator(double range): - range_(range) -{ -} - -void SpreadGenerator::reset(unsigned int seed) -{ - mt_.reset(seed); -} - -double SpreadGenerator::generate() -{ - return mt_.next() * range_; -} -} // namespace SIM diff --git a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp index 99152e42d0..d7de940912 100644 --- a/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp +++ b/src/tests/src/libs/antares/study/short-term-storage-input/short-term-storage-input-output.cpp @@ -51,6 +51,10 @@ void resizeFillVectors(ShortTermStorage::Series& series, double value, unsigned series.inflows.resize(size, value); series.lowerRuleCurve.resize(size, value); series.upperRuleCurve.resize(size, value); + + series.costInjection.resize(size, value); + series.costWithdrawal.resize(size, value); + series.costLevel.resize(size, value); } void createIndividualFileSeries(const std::string& path, double value, unsigned int size) @@ -88,6 +92,10 @@ void createFileSeries(double value, unsigned int size) createIndividualFileSeries(folder + SEP + "inflows.txt", value, size); createIndividualFileSeries(folder + SEP + "lower-rule-curve.txt", value, size); createIndividualFileSeries(folder + SEP + "upper-rule-curve.txt", value, size); + + createIndividualFileSeries(folder + SEP + "cost-injection.txt", value, size); + createIndividualFileSeries(folder + SEP + "cost-withdrawal.txt", value, size); + createIndividualFileSeries(folder + SEP + "cost-level.txt", value, size); } void createFileSeries(unsigned int size) @@ -99,6 +107,10 @@ void createFileSeries(unsigned int size) createIndividualFileSeries(folder + SEP + "inflows.txt", size); createIndividualFileSeries(folder + SEP + "lower-rule-curve.txt", size); createIndividualFileSeries(folder + SEP + "upper-rule-curve.txt", size); + + createIndividualFileSeries(folder + SEP + "cost-injection.txt", size); + createIndividualFileSeries(folder + SEP + "cost-withdrawal.txt", size); + createIndividualFileSeries(folder + SEP + "cost-level.txt", size); } void createIniFile(bool enabled) @@ -176,6 +188,10 @@ struct Fixture std::filesystem::remove(folder + SEP + "inflows.txt"); std::filesystem::remove(folder + SEP + "lower-rule-curve.txt"); std::filesystem::remove(folder + SEP + "upper-rule-curve.txt"); + + std::filesystem::remove(folder + SEP + "cost-injection.txt"); + std::filesystem::remove(folder + SEP + "cost-withdrawal.txt"); + std::filesystem::remove(folder + SEP + "cost-level.txt"); } std::string folder = getFolder();