From a8bfb5b3fbbed37c5a4b1720d920721c7187a7f2 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 12 Mar 2024 13:42:38 +0100 Subject: [PATCH 001/101] Add thermal interface struct --- src/tools/ts-generator/CMakeLists.txt | 1 + .../antares/ts-generator/thermal_interface.h | 50 +++++++++++++++++++ src/tools/ts-generator/main.cpp | 2 + 3 files changed, 53 insertions(+) create mode 100644 src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h diff --git a/src/tools/ts-generator/CMakeLists.txt b/src/tools/ts-generator/CMakeLists.txt index cea38ae0cd..2d54a8cc37 100644 --- a/src/tools/ts-generator/CMakeLists.txt +++ b/src/tools/ts-generator/CMakeLists.txt @@ -1,5 +1,6 @@ set(SRCS main.cpp + include/antares/ts-generator/thermal_interface.h ) set(execname "antares-ts-generator") diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h new file mode 100644 index 0000000000..7517211e3b --- /dev/null +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -0,0 +1,50 @@ +/* +** 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::TsGenerator +{ + +struct thermalInterface +{ + std::array foDuration; + std::array poDuration; + std::array foRate; + std::array poRate; + std::array npoMin; + std::array npoMax; + + unsigned unitCount; + float nominalCapacity; + + double forcedVolatility; + double plannedVolatility; + + Data::ThermalLaw forcedLaw = Data::thermalLawUniform; + Data::ThermalLaw plannedLaw = Data::thermalLawUniform; + +}; + +} // namespace Antares::TsGenerator diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index fe87ec47db..a543dcbb4c 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -34,6 +34,8 @@ #include #include +#include + using namespace Antares; From 7fd7fc7d7989bc8948589fbcab56f0e81aa92cd4 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 12 Mar 2024 19:13:45 +0100 Subject: [PATCH 002/101] Add preproVector, add template to convert to interface --- src/tools/ts-generator/CMakeLists.txt | 1 + .../antares/ts-generator/thermal_interface.h | 25 ++++++++++--- src/tools/ts-generator/main.cpp | 1 + src/tools/ts-generator/thermal_interface.cpp | 37 +++++++++++++++++++ 4 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 src/tools/ts-generator/thermal_interface.cpp diff --git a/src/tools/ts-generator/CMakeLists.txt b/src/tools/ts-generator/CMakeLists.txt index 2d54a8cc37..4da4bcbcb7 100644 --- a/src/tools/ts-generator/CMakeLists.txt +++ b/src/tools/ts-generator/CMakeLists.txt @@ -1,5 +1,6 @@ set(SRCS main.cpp + thermal_interface.cpp include/antares/ts-generator/thermal_interface.h ) diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index 7517211e3b..36e55496cc 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -27,14 +27,24 @@ namespace Antares::TsGenerator { +class preproVector +{ +public: + preproVector() : mVec(8760) {} + double& operator[](std::size_t idx) { return mVec[idx];} + +private: + std::vector mVec; +}; + struct thermalInterface { - std::array foDuration; - std::array poDuration; - std::array foRate; - std::array poRate; - std::array npoMin; - std::array npoMax; + preproVector foDuration; + preproVector poDuration; + preproVector foRate; + preproVector poRate; + preproVector npoMin; + preproVector npoMax; unsigned unitCount; float nominalCapacity; @@ -47,4 +57,7 @@ struct thermalInterface }; +template +std::vector convertToInterface(T list); + } // namespace Antares::TsGenerator diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index a543dcbb4c..cd2a3955e1 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -153,6 +153,7 @@ int main(int argc, char *argv[]) for (auto& c : clusters) logs.debug() << c->id(); + /* auto clustersInterface = TsGenerator::convertToInterface(clusters); */ return TSGenerator::GenerateThermalTimeSeries(*study, clusters, 0, *resultWriter); } diff --git a/src/tools/ts-generator/thermal_interface.cpp b/src/tools/ts-generator/thermal_interface.cpp new file mode 100644 index 0000000000..8f72ce69ad --- /dev/null +++ b/src/tools/ts-generator/thermal_interface.cpp @@ -0,0 +1,37 @@ +/* +** 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 + +namespace Antares::TsGenerator +{ + +template +std::vector convertToInterface(T list) +{ + std::vector clusters; + clusters.resize(list.size()); + + return clusters; +} + + +} // namespace Antares::TsGenerator From 8027c680805bba97b767110b3fa7b53625ca5e5e Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 10:27:31 +0100 Subject: [PATCH 003/101] template in c++ --- src/tools/ts-generator/CMakeLists.txt | 1 - .../antares/ts-generator/thermal_interface.h | 10 ++++- src/tools/ts-generator/thermal_interface.cpp | 37 ------------------- 3 files changed, 8 insertions(+), 40 deletions(-) delete mode 100644 src/tools/ts-generator/thermal_interface.cpp diff --git a/src/tools/ts-generator/CMakeLists.txt b/src/tools/ts-generator/CMakeLists.txt index 4da4bcbcb7..2d54a8cc37 100644 --- a/src/tools/ts-generator/CMakeLists.txt +++ b/src/tools/ts-generator/CMakeLists.txt @@ -1,6 +1,5 @@ set(SRCS main.cpp - thermal_interface.cpp include/antares/ts-generator/thermal_interface.h ) diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index 36e55496cc..ab80376011 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -20,7 +20,7 @@ */ # pragma once -#include +#include #include @@ -58,6 +58,12 @@ struct thermalInterface }; template -std::vector convertToInterface(T list); +std::vector convertToInterface(T list) +{ + std::vector clusters; + clusters.resize(list.size()); + + return clusters; +} } // namespace Antares::TsGenerator diff --git a/src/tools/ts-generator/thermal_interface.cpp b/src/tools/ts-generator/thermal_interface.cpp deleted file mode 100644 index 8f72ce69ad..0000000000 --- a/src/tools/ts-generator/thermal_interface.cpp +++ /dev/null @@ -1,37 +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 - -namespace Antares::TsGenerator -{ - -template -std::vector convertToInterface(T list) -{ - std::vector clusters; - clusters.resize(list.size()); - - return clusters; -} - - -} // namespace Antares::TsGenerator From dddfe91ad6671b543ab7df2bb1e4ff4569bba61a Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 13:20:08 +0100 Subject: [PATCH 004/101] template constructor --- .../antares/ts-generator/thermal_interface.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index ab80376011..8f8ba1219a 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -37,8 +37,13 @@ class preproVector std::vector mVec; }; -struct thermalInterface +class ThermalInterface { +public: + + template + ThermalInterface(T source); + preproVector foDuration; preproVector poDuration; preproVector foRate; @@ -54,16 +59,10 @@ struct thermalInterface Data::ThermalLaw forcedLaw = Data::thermalLawUniform; Data::ThermalLaw plannedLaw = Data::thermalLawUniform; - }; template -std::vector convertToInterface(T list) -{ - std::vector clusters; - clusters.resize(list.size()); - - return clusters; -} +ThermalInterface::ThermalInterface(T source) +{} } // namespace Antares::TsGenerator From 6c99233104533d125ce48c9feb651b077a894c76 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 14:39:45 +0100 Subject: [PATCH 005/101] References init --- .../antares/ts-generator/thermal_interface.h | 22 ++++++++++++------- src/tools/ts-generator/main.cpp | 8 ++++++- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index 8f8ba1219a..5241dd5f8f 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -42,7 +42,7 @@ class ThermalInterface public: template - ThermalInterface(T source); + ThermalInterface(T& source); preproVector foDuration; preproVector poDuration; @@ -51,18 +51,24 @@ class ThermalInterface preproVector npoMin; preproVector npoMax; - unsigned unitCount; - float nominalCapacity; + const unsigned &unitCount; + const double &nominalCapacity; - double forcedVolatility; - double plannedVolatility; + const double& forcedVolatility; + const double& plannedVolatility; - Data::ThermalLaw forcedLaw = Data::thermalLawUniform; - Data::ThermalLaw plannedLaw = Data::thermalLawUniform; + Data::ThermalLaw& forcedLaw; + Data::ThermalLaw& plannedLaw; }; template -ThermalInterface::ThermalInterface(T source) +ThermalInterface::ThermalInterface(T& source) : + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw) {} } // namespace Antares::TsGenerator diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index cd2a3955e1..3559d19fd9 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -150,10 +150,16 @@ int main(int argc, char *argv[]) else clusters = getClustersToGen(study->areas, settings.thermalListToGen); + std::vector interface; for (auto& c : clusters) + { logs.debug() << c->id(); + interface.push_back(c); + logs.notice() << interface.back().unitCount; + logs.notice() << interface.back().nominalCapacity; + logs.notice() << interface.back().forcedVolatility; + } - /* auto clustersInterface = TsGenerator::convertToInterface(clusters); */ return TSGenerator::GenerateThermalTimeSeries(*study, clusters, 0, *resultWriter); } From a3019271a340b979fc0729f006b541c47d94b9b5 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 14:56:43 +0100 Subject: [PATCH 006/101] remove preproVector, use prepro pointer --- .../antares/ts-generator/thermal_interface.h | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index 5241dd5f8f..1d0228a11e 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -27,16 +27,6 @@ namespace Antares::TsGenerator { -class preproVector -{ -public: - preproVector() : mVec(8760) {} - double& operator[](std::size_t idx) { return mVec[idx];} - -private: - std::vector mVec; -}; - class ThermalInterface { public: @@ -44,13 +34,6 @@ class ThermalInterface template ThermalInterface(T& source); - preproVector foDuration; - preproVector poDuration; - preproVector foRate; - preproVector poRate; - preproVector npoMin; - preproVector npoMax; - const unsigned &unitCount; const double &nominalCapacity; @@ -59,6 +42,8 @@ class ThermalInterface Data::ThermalLaw& forcedLaw; Data::ThermalLaw& plannedLaw; + + Data::PreproThermal* prepro; }; template @@ -68,7 +53,8 @@ ThermalInterface::ThermalInterface(T& source) : forcedVolatility(source->forcedVolatility), plannedVolatility(source->plannedVolatility), forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw) + plannedLaw(source->plannedLaw), + prepro(source->prepro) {} } // namespace Antares::TsGenerator From 91aae900ab002dc300bb6262f7c947f69e3fba72 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 15:21:47 +0100 Subject: [PATCH 007/101] move ThermalInterface to generator.h --- .../antares/solver/ts-generator/generator.h | 30 +++++++++++++++++++ src/solver/ts-generator/thermal.cpp | 5 ++++ src/tools/ts-generator/CMakeLists.txt | 1 - .../antares/ts-generator/thermal_interface.h | 4 +-- src/tools/ts-generator/main.cpp | 14 +-------- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index d2192e93ef..84b7a43879 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -32,6 +32,36 @@ namespace Antares::TSGenerator { +class ThermalInterface +{ +public: + + template + ThermalInterface(T& source); + + const unsigned &unitCount; + const double &nominalCapacity; + + const double& forcedVolatility; + const double& plannedVolatility; + + Data::ThermalLaw& forcedLaw; + Data::ThermalLaw& plannedLaw; + + Data::PreproThermal* prepro; +}; + +template +ThermalInterface::ThermalInterface(T& source) : + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw), + prepro(source->prepro) +{} + void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); /*! diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index b5b33921dd..70409029aa 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -30,6 +30,8 @@ #include #include +#include + #include "antares/study/simulation.h" using namespace Yuni; @@ -626,7 +628,10 @@ bool GenerateThermalTimeSeries(Data::Study& study, // TODO VP: parallel for (auto* cluster : clusters) + { + /* ThermalInterface clusterInterface(cluster); */ (*generator)(*cluster->parentArea, *cluster); + } delete generator; diff --git a/src/tools/ts-generator/CMakeLists.txt b/src/tools/ts-generator/CMakeLists.txt index 2d54a8cc37..cea38ae0cd 100644 --- a/src/tools/ts-generator/CMakeLists.txt +++ b/src/tools/ts-generator/CMakeLists.txt @@ -1,6 +1,5 @@ set(SRCS main.cpp - include/antares/ts-generator/thermal_interface.h ) set(execname "antares-ts-generator") diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h index 1d0228a11e..9cbc5e56ff 100644 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h @@ -24,7 +24,7 @@ #include -namespace Antares::TsGenerator +namespace Antares::TSGenerator { class ThermalInterface @@ -57,4 +57,4 @@ ThermalInterface::ThermalInterface(T& source) : prepro(source->prepro) {} -} // namespace Antares::TsGenerator +} // namespace Antares::TSGenerator diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 3559d19fd9..ffde64a479 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -1,5 +1,4 @@ -/* -** 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, @@ -34,9 +33,6 @@ #include #include -#include - - using namespace Antares; struct TsGeneratorSettings @@ -150,16 +146,8 @@ int main(int argc, char *argv[]) else clusters = getClustersToGen(study->areas, settings.thermalListToGen); - std::vector interface; for (auto& c : clusters) - { logs.debug() << c->id(); - interface.push_back(c); - logs.notice() << interface.back().unitCount; - logs.notice() << interface.back().nominalCapacity; - logs.notice() << interface.back().forcedVolatility; - } return TSGenerator::GenerateThermalTimeSeries(*study, clusters, 0, *resultWriter); } - From 8b1a054e13e56b70796a49f4de5152619707b9ea Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 15:22:25 +0100 Subject: [PATCH 008/101] remove ts-generator/include --- .../antares/ts-generator/thermal_interface.h | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h diff --git a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h b/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h deleted file mode 100644 index 9cbc5e56ff..0000000000 --- a/src/tools/ts-generator/include/antares/ts-generator/thermal_interface.h +++ /dev/null @@ -1,60 +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 - -#include - -namespace Antares::TSGenerator -{ - -class ThermalInterface -{ -public: - - template - ThermalInterface(T& source); - - const unsigned &unitCount; - const double &nominalCapacity; - - const double& forcedVolatility; - const double& plannedVolatility; - - Data::ThermalLaw& forcedLaw; - Data::ThermalLaw& plannedLaw; - - Data::PreproThermal* prepro; -}; - -template -ThermalInterface::ThermalInterface(T& source) : - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro) -{} - -} // namespace Antares::TSGenerator From 053dfef9c68496368bdec545231fd914f4a64f4f Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 15:42:42 +0100 Subject: [PATCH 009/101] use interface --- .../antares/solver/ts-generator/generator.h | 14 +++++++++++++- src/solver/ts-generator/thermal.cpp | 18 +++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 84b7a43879..d85da54302 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "xcast/xcast.h" @@ -49,6 +50,13 @@ class ThermalInterface Data::ThermalLaw& plannedLaw; Data::PreproThermal* prepro; + + Data::TimeSeries& series; + + Matrix<>& modulation; + + const std::string& name; + const std::string& id; }; template @@ -59,7 +67,11 @@ ThermalInterface::ThermalInterface(T& source) : plannedVolatility(source->plannedVolatility), forcedLaw(source->forcedLaw), plannedLaw(source->plannedLaw), - prepro(source->prepro) + prepro(source->prepro), + series(source->series), + modulation(source->modulation), + name(source->name()), + id(source->id()) {} void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 70409029aa..d4f17c4fc2 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -53,7 +53,7 @@ class GeneratorTempData final void prepareOutputFoldersForAllAreas(uint year); - void operator()(Data::Area& area, Data::ThermalCluster& cluster); + void operator()(Data::Area& area, ThermalInterface& cluster); public: Data::Study& study; @@ -65,7 +65,7 @@ class GeneratorTempData final bool derated; private: - void writeResultsToDisk(const Data::Area& area, const Data::ThermalCluster& cluster); + void writeResultsToDisk(const Data::Area& area, const ThermalInterface& cluster); int durationGenerator(Data::ThermalLaw law, int expec, double volat, double a, double b); @@ -127,14 +127,14 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, } void GeneratorTempData::writeResultsToDisk(const Data::Area& area, - const Data::ThermalCluster& cluster) + const ThermalInterface& cluster) { if (not study.parameters.noOutput) { pTempFilename.reserve(study.folderOutput.size() + 256); pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << "mc-" << currentYear - << SEP << area.id << SEP << cluster.id() << ".txt"; + << SEP << area.id << SEP << cluster.id << ".txt"; enum { @@ -227,12 +227,12 @@ int GeneratorTempData::durationGenerator(Data::ThermalLaw law, return 0; } -void GeneratorTempData::operator()(Data::Area& area, Data::ThermalCluster& cluster) +void GeneratorTempData::operator()(Data::Area& area, ThermalInterface& cluster) { if (not cluster.prepro) { logs.error() - << "Cluster: " << area.name << '/' << cluster.name() + << "Cluster: " << area.name << '/' << cluster.name << ": The timeseries will not be regenerated. All data related to the ts-generator for " << "'thermal' have been released."; return; @@ -595,7 +595,6 @@ void GeneratorTempData::operator()(Data::Area& area, Data::ThermalCluster& clust if (archive) writeResultsToDisk(area, cluster); - cluster.calculationOfSpinning(); } } // namespace @@ -629,8 +628,9 @@ bool GenerateThermalTimeSeries(Data::Study& study, // TODO VP: parallel for (auto* cluster : clusters) { - /* ThermalInterface clusterInterface(cluster); */ - (*generator)(*cluster->parentArea, *cluster); + ThermalInterface clusterInterface(cluster); + (*generator)(*cluster->parentArea, clusterInterface); + cluster->calculationOfSpinning(); } delete generator; From 604cde052a4c6777376ce5157c4ef3e63b663c8d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 15:46:51 +0100 Subject: [PATCH 010/101] fix typo --- src/tools/ts-generator/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index ffde64a479..66f4cf90b2 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -1,4 +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, From b0c7c3515641a0fc38a40f4ec7ac556f41ce3fef Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 13 Mar 2024 16:17:29 +0100 Subject: [PATCH 011/101] use column for modulation --- .../include/antares/solver/ts-generator/generator.h | 4 ++-- src/solver/ts-generator/thermal.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index d85da54302..3d409f1f3a 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -53,7 +53,7 @@ class ThermalInterface Data::TimeSeries& series; - Matrix<>& modulation; + Matrix<>::ColumnType& modulationCapacity; const std::string& name; const std::string& id; @@ -69,7 +69,7 @@ ThermalInterface::ThermalInterface(T& source) : plannedLaw(source->plannedLaw), prepro(source->prepro), series(source->series), - modulation(source->modulation), + modulationCapacity(source->modulation[Data::thermalModulationCapacity]), name(source->name()), id(source->id()) {} diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index d4f17c4fc2..df726b7803 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -341,8 +341,6 @@ void GeneratorTempData::operator()(Data::Area& area, ThermalInterface& cluster) double cumul = 0; double last = 0; - auto& modulation = cluster.modulation[Data::thermalModulationCapacity]; - double* dstSeries = nullptr; const uint tsCount = nbThermalTimeseries_ + 2; @@ -582,7 +580,7 @@ void GeneratorTempData::operator()(Data::Area& area, ThermalInterface& cluster) double AVPDayInTheYear = AVP[dayInTheYear]; for (uint h = 0; h != 24; ++h) { - dstSeries[hour] = Math::Round(AVPDayInTheYear * modulation[hour]); + dstSeries[hour] = Math::Round(AVPDayInTheYear * cluster.modulationCapacity[hour]); ++hour; } } From ce3b8b3bcdace1b58d0d97c4137e01ef2001995d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 14 Mar 2024 11:19:27 +0100 Subject: [PATCH 012/101] Code smell --- .../include/antares/solver/ts-generator/generator.h | 2 +- src/solver/ts-generator/thermal.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 3d409f1f3a..7c22fc4282 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -38,7 +38,7 @@ class ThermalInterface public: template - ThermalInterface(T& source); + explicit ThermalInterface(T& source); const unsigned &unitCount; const double &nominalCapacity; diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index df726b7803..bab524b6f4 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -53,7 +53,7 @@ class GeneratorTempData final void prepareOutputFoldersForAllAreas(uint year); - void operator()(Data::Area& area, ThermalInterface& cluster); + void operator()(const Data::Area& area, ThermalInterface& cluster); public: Data::Study& study; @@ -227,7 +227,7 @@ int GeneratorTempData::durationGenerator(Data::ThermalLaw law, return 0; } -void GeneratorTempData::operator()(Data::Area& area, ThermalInterface& cluster) +void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& cluster) { if (not cluster.prepro) { From 31d73e301da73bac9e137af949a3cf0f0cd45b7c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 14 Mar 2024 12:05:31 +0100 Subject: [PATCH 013/101] Move save out of generator --- src/solver/ts-generator/thermal.cpp | 81 +++++++++++++---------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index bab524b6f4..aceeffc739 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -48,8 +48,7 @@ class GeneratorTempData final { public: GeneratorTempData(Data::Study& study, - Solver::Progression::Task& progr, - Solver::IResultWriter& writer); + Solver::Progression::Task& progr); void prepareOutputFoldersForAllAreas(uint year); @@ -58,15 +57,9 @@ class GeneratorTempData final public: Data::Study& study; - bool archive; - - uint currentYear; - bool derated; private: - void writeResultsToDisk(const Data::Area& area, const ThermalInterface& cluster); - int durationGenerator(Data::ThermalLaw law, int expec, double volat, double a, double b); template @@ -103,21 +96,16 @@ class GeneratorTempData final String pTempFilename; Solver::Progression::Task& pProgression; - Solver::IResultWriter& pWriter; }; GeneratorTempData::GeneratorTempData(Data::Study& study, - Solver::Progression::Task& progr, - Solver::IResultWriter& writer) : + Solver::Progression::Task& progr): study(study), rndgenerator(study.runtime->random[Data::seedTsGenThermal]), - pProgression(progr), - pWriter(writer) + pProgression(progr) { auto& parameters = study.parameters; - archive = (0 != (parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - nbThermalTimeseries_ = parameters.nbTimeSeriesThermal; derated = parameters.derated; @@ -126,30 +114,6 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, PPOW.resize(DAYS_PER_YEAR); } -void GeneratorTempData::writeResultsToDisk(const Data::Area& area, - const ThermalInterface& cluster) -{ - if (not study.parameters.noOutput) - { - pTempFilename.reserve(study.folderOutput.size() + 256); - - pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << "mc-" << currentYear - << SEP << area.id << SEP << cluster.id << ".txt"; - - enum - { - precision = 0 - }; - - std::string buffer; - cluster.series.timeSeries.saveToBuffer(buffer, precision); - - pWriter.addEntryFromBuffer(pTempFilename.c_str(), buffer); - } - - ++pProgression; -} - template void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, double volatility, @@ -242,8 +206,8 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu if (0 == cluster.unitCount or 0 == cluster.nominalCapacity) { - if (archive) - writeResultsToDisk(area, cluster); + if ((0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal))) + /* writeResultsToDisk(area, cluster); */ return; } @@ -590,12 +554,36 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu if (derated) cluster.series.timeSeries.averageTimeseries(); - if (archive) - writeResultsToDisk(area, cluster); } } // namespace +void writeResultsToDisk(const Data::Study& study, + Solver::IResultWriter& writer, + const Data::Area& area, + const Data::ThermalCluster& cluster) +{ + if (study.parameters.noOutput) + return; + + String pTempFilename; + + pTempFilename.reserve(study.folderOutput.size() + 256); + + pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << "mc-0" + << SEP << area.id << SEP << cluster.id() << ".txt"; + + enum + { + precision = 0 + }; + + std::string buffer; + cluster.series.timeSeries.saveToBuffer(buffer, precision); + + writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); +} + std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration) { @@ -619,9 +607,9 @@ bool GenerateThermalTimeSeries(Data::Study& study, logs.info() << "Generating the thermal time-series"; Solver::Progression::Task progression(study, year, Solver::Progression::sectTSGThermal); - auto* generator = new GeneratorTempData(study, progression, writer); + bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - generator->currentYear = year; + auto* generator = new GeneratorTempData(study, progression); // TODO VP: parallel for (auto* cluster : clusters) @@ -629,6 +617,9 @@ bool GenerateThermalTimeSeries(Data::Study& study, ThermalInterface clusterInterface(cluster); (*generator)(*cluster->parentArea, clusterInterface); cluster->calculationOfSpinning(); + + if (archive) + writeResultsToDisk(study, writer, *cluster->parentArea, *cluster); } delete generator; From ee84f58dfdfb5e33204166dcc2026df3546315c9 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 14 Mar 2024 12:35:51 +0100 Subject: [PATCH 014/101] FIx results, spinning after writing --- src/solver/ts-generator/thermal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index aceeffc739..0e52276551 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -616,10 +616,11 @@ bool GenerateThermalTimeSeries(Data::Study& study, { ThermalInterface clusterInterface(cluster); (*generator)(*cluster->parentArea, clusterInterface); - cluster->calculationOfSpinning(); if (archive) writeResultsToDisk(study, writer, *cluster->parentArea, *cluster); + + cluster->calculationOfSpinning(); } delete generator; From c6975ca529dc2a76e14200b5a1358e5249ea1d06 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 15 Mar 2024 15:53:53 +0100 Subject: [PATCH 015/101] code smells --- src/solver/ts-generator/thermal.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 0e52276551..605eaa8896 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -50,8 +50,6 @@ class GeneratorTempData final GeneratorTempData(Data::Study& study, Solver::Progression::Task& progr); - void prepareOutputFoldersForAllAreas(uint year); - void operator()(const Data::Area& area, ThermalInterface& cluster); public: @@ -205,11 +203,7 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu assert(cluster.prepro); if (0 == cluster.unitCount or 0 == cluster.nominalCapacity) - { - if ((0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal))) - /* writeResultsToDisk(area, cluster); */ return; - } const auto& preproData = *(cluster.prepro); @@ -609,7 +603,7 @@ bool GenerateThermalTimeSeries(Data::Study& study, bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - auto* generator = new GeneratorTempData(study, progression); + auto generator = std::make_unique(study, progression); // TODO VP: parallel for (auto* cluster : clusters) @@ -623,8 +617,6 @@ bool GenerateThermalTimeSeries(Data::Study& study, cluster->calculationOfSpinning(); } - delete generator; - return true; } From 4d9ec992ac4b75762339e9fa4d4cb3d84b37b584 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 15 Mar 2024 15:56:32 +0100 Subject: [PATCH 016/101] remove mc-year directory from ts-generator output --- src/solver/ts-generator/thermal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 605eaa8896..b07fe63e95 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -564,8 +564,8 @@ void writeResultsToDisk(const Data::Study& study, pTempFilename.reserve(study.folderOutput.size() + 256); - pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << "mc-0" - << SEP << area.id << SEP << cluster.id() << ".txt"; + pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << area.id + << SEP << cluster.id() << ".txt"; enum { From 04edcb2beca738fce44cc654d9c4b3bbbeae0dd0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 13:34:02 +0100 Subject: [PATCH 017/101] remove id from interface --- .../include/antares/solver/ts-generator/generator.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 7c22fc4282..39c8bcaf7f 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -56,7 +56,6 @@ class ThermalInterface Matrix<>::ColumnType& modulationCapacity; const std::string& name; - const std::string& id; }; template @@ -70,8 +69,7 @@ ThermalInterface::ThermalInterface(T& source) : prepro(source->prepro), series(source->series), modulationCapacity(source->modulation[Data::thermalModulationCapacity]), - name(source->name()), - id(source->id()) + name(source->name()) {} void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); From 3591573951cc2a4962c828a84400452c680c9a34 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 13:38:00 +0100 Subject: [PATCH 018/101] remove progression --- src/solver/ts-generator/thermal.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index b07fe63e95..2c6cce11a6 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -47,8 +47,7 @@ namespace class GeneratorTempData final { public: - GeneratorTempData(Data::Study& study, - Solver::Progression::Task& progr); + GeneratorTempData(Data::Study& study); void operator()(const Data::Area& area, ThermalInterface& cluster); @@ -93,14 +92,11 @@ class GeneratorTempData final std::vector> PPOW; String pTempFilename; - Solver::Progression::Task& pProgression; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, - Solver::Progression::Task& progr): +GeneratorTempData::GeneratorTempData(Data::Study& study) : study(study), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]), - pProgression(progr) + rndgenerator(study.runtime->random[Data::seedTsGenThermal]) { auto& parameters = study.parameters; @@ -599,11 +595,10 @@ bool GenerateThermalTimeSeries(Data::Study& study, { logs.info(); logs.info() << "Generating the thermal time-series"; - Solver::Progression::Task progression(study, year, Solver::Progression::sectTSGThermal); bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - auto generator = std::make_unique(study, progression); + auto generator = std::make_unique(study); // TODO VP: parallel for (auto* cluster : clusters) From d3a0c8b7183af64d4ccba393a86246cc9245c29b Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 14:28:12 +0100 Subject: [PATCH 019/101] Add data to link class, specify interface constructor for thermal --- .../study/include/antares/study/area/links.h | 16 ++++++++++++++++ .../antares/solver/ts-generator/generator.h | 7 ++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index d1259cd53c..a9486f6135 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -21,6 +21,7 @@ #ifndef __ANTARES_LIBS_STUDY_LINKS_H__ #define __ANTARES_LIBS_STUDY_LINKS_H__ +#include #include #include #include @@ -204,6 +205,21 @@ class AreaLink final : public Yuni::NonCopyable int linkWidth; friend struct CompareLinkName; + + unsigned unitCount; + double nominalCapacity; + + double forcedVolatility; + double plannedVolatility; + + Data::ThermalLaw forcedLaw; + Data::ThermalLaw plannedLaw; + + Data::PreproThermal* prepro; + + Matrix<> modulationCapacity; + + }; // class AreaLink struct CompareLinkName final diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 39c8bcaf7f..1e27c62789 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -36,9 +36,7 @@ namespace Antares::TSGenerator class ThermalInterface { public: - - template - explicit ThermalInterface(T& source); + explicit ThermalInterface(Data::ThermalCluster*); const unsigned &unitCount; const double &nominalCapacity; @@ -58,8 +56,7 @@ class ThermalInterface const std::string& name; }; -template -ThermalInterface::ThermalInterface(T& source) : +ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : unitCount(source->unitCount), nominalCapacity(source->nominalCapacity), forcedVolatility(source->forcedVolatility), From 8e9ef164026593c542706514311b6a076d8b4549 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 14:29:07 +0100 Subject: [PATCH 020/101] Remove unused arg year --- .../simulation/include/antares/solver/simulation/solver.hxx | 2 +- .../include/antares/solver/ts-generator/generator.h | 1 - src/solver/ts-generator/thermal.cpp | 1 - src/tools/ts-generator/main.cpp | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 25fbc1e085..2483e347a7 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -490,7 +490,7 @@ void ISimulation::regenerateTimeSeries(uint year) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); - GenerateThermalTimeSeries(study, clusters, year, pResultWriter); + GenerateThermalTimeSeries(study, clusters, pResultWriter); } timer.stop(); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 1e27c62789..95ce805612 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -79,7 +79,6 @@ bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer); bool GenerateThermalTimeSeries(Data::Study& study, std::vector clusters, - uint year, Solver::IResultWriter& writer); std::vector getAllClustersToGen(Data::AreaList& areas, diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 2c6cce11a6..406be14529 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -590,7 +590,6 @@ std::vector getAllClustersToGen(Data::AreaList& areas, bool GenerateThermalTimeSeries(Data::Study& study, std::vector clusters, - uint year, Solver::IResultWriter& writer) { logs.info(); diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 66f4cf90b2..adfe26e5d0 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -150,5 +150,5 @@ int main(int argc, char *argv[]) for (auto& c : clusters) logs.debug() << c->id(); - return TSGenerator::GenerateThermalTimeSeries(*study, clusters, 0, *resultWriter); + return TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter); } From 71c226554b35e9b480206fbecba1f30b65aeff70 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 14:38:23 +0100 Subject: [PATCH 021/101] Fix compile --- .../include/antares/solver/ts-generator/generator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 95ce805612..a3ffb8d2e6 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -36,7 +36,7 @@ namespace Antares::TSGenerator class ThermalInterface { public: - explicit ThermalInterface(Data::ThermalCluster*); + ThermalInterface(Data::ThermalCluster*); const unsigned &unitCount; const double &nominalCapacity; @@ -56,7 +56,7 @@ class ThermalInterface const std::string& name; }; -ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : +inline ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : unitCount(source->unitCount), nominalCapacity(source->nominalCapacity), forcedVolatility(source->forcedVolatility), From 5eb633f5a6656d9d7a8d0d4dac8efad15b5f3b80 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 14:41:08 +0100 Subject: [PATCH 022/101] Move constructor to cpp file --- .../antares/solver/ts-generator/generator.h | 13 ------------- src/solver/ts-generator/thermal.cpp | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index a3ffb8d2e6..da2ca17654 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -56,19 +56,6 @@ class ThermalInterface const std::string& name; }; -inline ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro), - series(source->series), - modulationCapacity(source->modulation[Data::thermalModulationCapacity]), - name(source->name()) -{} - void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); /*! diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 406be14529..ba31a5aa0e 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -42,8 +42,23 @@ using namespace Yuni; namespace Antares::TSGenerator { + +ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw), + prepro(source->prepro), + series(source->series), + modulationCapacity(source->modulation[Data::thermalModulationCapacity]), + name(source->name()) +{} + namespace { + class GeneratorTempData final { public: From 444a9672f79bd5030949a19392d988961682a977 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 14:52:19 +0100 Subject: [PATCH 023/101] Add constructor for links --- .../include/antares/solver/ts-generator/generator.h | 4 ++-- src/solver/ts-generator/thermal.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index da2ca17654..21e47a51b9 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -1,5 +1,4 @@ -/* -** 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, @@ -37,6 +36,7 @@ class ThermalInterface { public: ThermalInterface(Data::ThermalCluster*); + ThermalInterface(Data::AreaLink*, Data::TimeSeries&); const unsigned &unitCount; const double &nominalCapacity; diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index ba31a5aa0e..03a2589d2f 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -56,6 +56,19 @@ ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : name(source->name()) {} +ThermalInterface::ThermalInterface(Data::AreaLink *source, Data::TimeSeries& capacity) : + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw), + prepro(source->prepro), + series(capacity), + modulationCapacity(source->modulationCapacity[0]), + name(source->getName()) +{} + namespace { From 8068785b044abe6d35af7e0057b20cb12128f767 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 18 Mar 2024 15:19:18 +0100 Subject: [PATCH 024/101] Add struct tsgeneration in arealink --- .../study/include/antares/study/area/links.h | 19 +++++++++------- .../antares/solver/ts-generator/generator.h | 2 +- src/solver/ts-generator/thermal.cpp | 22 ++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index a9486f6135..c7011e6ecc 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -206,18 +206,21 @@ class AreaLink final : public Yuni::NonCopyable friend struct CompareLinkName; - unsigned unitCount; - double nominalCapacity; + struct TsGeneration + { + unsigned unitCount; + double nominalCapacity; - double forcedVolatility; - double plannedVolatility; + double forcedVolatility; + double plannedVolatility; - Data::ThermalLaw forcedLaw; - Data::ThermalLaw plannedLaw; + Data::ThermalLaw forcedLaw; + Data::ThermalLaw plannedLaw; - Data::PreproThermal* prepro; + Data::PreproThermal* prepro; - Matrix<> modulationCapacity; + Matrix<> modulationCapacity; + }; }; // class AreaLink diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 21e47a51b9..aaddded269 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -36,7 +36,7 @@ class ThermalInterface { public: ThermalInterface(Data::ThermalCluster*); - ThermalInterface(Data::AreaLink*, Data::TimeSeries&); + ThermalInterface(Data::AreaLink::TsGeneration&, Data::TimeSeries&, const std::string& name); const unsigned &unitCount; const double &nominalCapacity; diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 03a2589d2f..2f31ecd073 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -56,17 +56,19 @@ ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : name(source->name()) {} -ThermalInterface::ThermalInterface(Data::AreaLink *source, Data::TimeSeries& capacity) : - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro), +ThermalInterface::ThermalInterface(Data::AreaLink::TsGeneration& source, + Data::TimeSeries& capacity, + const std::string& linkName) : + unitCount(source.unitCount), + nominalCapacity(source.nominalCapacity), + forcedVolatility(source.forcedVolatility), + plannedVolatility(source.plannedVolatility), + forcedLaw(source.forcedLaw), + plannedLaw(source.plannedLaw), + prepro(source.prepro), series(capacity), - modulationCapacity(source->modulationCapacity[0]), - name(source->getName()) + modulationCapacity(source.modulationCapacity[0]), + name(linkName) {} namespace From 452fd39593c23f18cafe1d5d5d5ee48de85c9df5 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 19 Mar 2024 12:29:13 +0100 Subject: [PATCH 025/101] fix compile --- src/solver/ts-generator/thermal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 5aab1189f3..d6327ef2a5 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -580,7 +580,7 @@ void writeResultsToDisk(const Data::Study& study, if (study.parameters.noOutput) return; - String pTempFilename; + Yuni::String pTempFilename; pTempFilename.reserve(study.folderOutput.size() + 256); From 7158a87137d80a89caa661b99d83be70d057a211 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 19 Mar 2024 16:31:13 +0100 Subject: [PATCH 026/101] test link interface --- src/libs/antares/study/include/antares/study/area/links.h | 3 ++- .../include/antares/solver/ts-generator/generator.h | 4 ++-- src/solver/ts-generator/thermal.cpp | 7 +++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index c7011e6ecc..c69aca3d0a 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -206,7 +206,7 @@ class AreaLink final : public Yuni::NonCopyable friend struct CompareLinkName; - struct TsGeneration + struct LinkTsGeneration { unsigned unitCount; double nominalCapacity; @@ -222,6 +222,7 @@ class AreaLink final : public Yuni::NonCopyable Matrix<> modulationCapacity; }; + LinkTsGeneration tsGeneration; }; // class AreaLink diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index aaddded269..18913452b3 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -35,8 +35,8 @@ namespace Antares::TSGenerator class ThermalInterface { public: - ThermalInterface(Data::ThermalCluster*); - ThermalInterface(Data::AreaLink::TsGeneration&, Data::TimeSeries&, const std::string& name); + explicit ThermalInterface(Data::ThermalCluster*); + ThermalInterface(Data::AreaLink::LinkTsGeneration&, Data::TimeSeries&, const std::string& name); const unsigned &unitCount; const double &nominalCapacity; diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index d6327ef2a5..0f2c4dd5dd 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -51,7 +51,7 @@ ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : name(source->name()) {} -ThermalInterface::ThermalInterface(Data::AreaLink::TsGeneration& source, +ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, Data::TimeSeries& capacity, const std::string& linkName) : unitCount(source.unitCount), @@ -72,7 +72,7 @@ namespace class GeneratorTempData final { public: - GeneratorTempData(Data::Study& study); + explicit GeneratorTempData(Data::Study& study); void operator()(const Data::Area& area, ThermalInterface& cluster); @@ -635,6 +635,9 @@ bool GenerateThermalTimeSeries(Data::Study& study, cluster->calculationOfSpinning(); } + for (auto& [name, link] : study.areas.byIndex[0]->links) + ThermalInterface lnk(link->tsGeneration, link->directCapacities, link->getName()); + return true; } From ccf0ae5704fcac112acb7e9a5fb480f1834becce Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 20 Mar 2024 16:38:08 +0100 Subject: [PATCH 027/101] remove link test --- src/solver/ts-generator/thermal.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 0f2c4dd5dd..9e22eb0705 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -635,9 +635,6 @@ bool GenerateThermalTimeSeries(Data::Study& study, cluster->calculationOfSpinning(); } - for (auto& [name, link] : study.areas.byIndex[0]->links) - ThermalInterface lnk(link->tsGeneration, link->directCapacities, link->getName()); - return true; } From 0751ed3b888b0e10db0b3e5abd017f0bf15eb8eb Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 21 Mar 2024 11:42:28 +0100 Subject: [PATCH 028/101] Add the output path to save as arg --- .../include/antares/solver/simulation/solver.hxx | 4 +++- .../include/antares/solver/ts-generator/generator.h | 6 ++++-- src/solver/ts-generator/thermal.cpp | 12 ++++++------ src/tools/ts-generator/main.cpp | 6 +++++- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 2483e347a7..fca2a5d07f 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -39,6 +39,7 @@ #include #include "antares/concurrency/concurrency.h" +#define SEP Yuni::IO::Separator namespace Antares::Solver::Simulation { @@ -490,7 +491,8 @@ void ISimulation::regenerateTimeSeries(uint year) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); - GenerateThermalTimeSeries(study, clusters, pResultWriter); + const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-0"; + GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); } timer.stop(); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 18913452b3..565ef34b85 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -1,4 +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, @@ -66,7 +67,8 @@ bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer); bool GenerateThermalTimeSeries(Data::Study& study, std::vector clusters, - Solver::IResultWriter& writer); + Solver::IResultWriter& writer, + const std::string& savePath); std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration); diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 9e22eb0705..b1a201c18b 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -575,17 +575,16 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu void writeResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Data::Area& area, - const Data::ThermalCluster& cluster) + const Data::ThermalCluster& cluster, + const std::string& savePath) { if (study.parameters.noOutput) return; Yuni::String pTempFilename; - pTempFilename.reserve(study.folderOutput.size() + 256); - pTempFilename.clear() << "ts-generator" << SEP << "thermal" << SEP << area.id - << SEP << cluster.id() << ".txt"; + pTempFilename.clear() << savePath << SEP << area.id << SEP << cluster.id() << ".txt"; enum { @@ -614,7 +613,8 @@ std::vector getAllClustersToGen(Data::AreaList& areas, bool GenerateThermalTimeSeries(Data::Study& study, std::vector clusters, - Solver::IResultWriter& writer) + Solver::IResultWriter& writer, + const std::string& savePath) { logs.info(); logs.info() << "Generating the thermal time-series"; @@ -630,7 +630,7 @@ bool GenerateThermalTimeSeries(Data::Study& study, (*generator)(*cluster->parentArea, clusterInterface); if (archive) - writeResultsToDisk(study, writer, *cluster->parentArea, *cluster); + writeResultsToDisk(study, writer, *cluster->parentArea, *cluster, savePath); cluster->calculationOfSpinning(); } diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 9afa89fbbf..c3be5f287d 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -34,6 +34,8 @@ #include #include +#define SEP Yuni::IO::Separator + using namespace Antares; struct TsGeneratorSettings @@ -140,6 +142,8 @@ int main(int argc, char *argv[]) auto resultWriter = Solver::resultWriterFactory( Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); + const std::string savePath = std::string("ts-generator") + SEP + "thermal"; + std::vector clusters; if (settings.thermalListToGen.empty()) @@ -150,5 +154,5 @@ int main(int argc, char *argv[]) for (auto& c : clusters) logs.debug() << c->id(); - return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter); + return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter, savePath); } From 751ce5ccc6911007e85628b33493274b63d6ecc0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 21 Mar 2024 16:50:19 +0100 Subject: [PATCH 029/101] comments --- .../simulation/include/antares/solver/simulation/solver.hxx | 4 ++-- src/solver/ts-generator/thermal.cpp | 3 ++- src/tools/ts-generator/main.cpp | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index fca2a5d07f..282675745c 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -39,7 +39,6 @@ #include #include "antares/concurrency/concurrency.h" -#define SEP Yuni::IO::Separator namespace Antares::Solver::Simulation { @@ -490,8 +489,9 @@ void ISimulation::regenerateTimeSeries(uint year) if (refreshTSonCurrentYear) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); - +#define SEP Yuni::IO::Separator const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-0"; +#undef SEP GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); } diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index b1a201c18b..3e6cf1066d 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -320,6 +320,7 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu double cumul = 0; double last = 0; + auto& modulation = cluster.modulationCapacity; double* dstSeries = nullptr; const uint tsCount = nbThermalTimeseries_ + 2; @@ -559,7 +560,7 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu double AVPDayInTheYear = AVP[dayInTheYear]; for (uint h = 0; h != 24; ++h) { - dstSeries[hour] = std::round(AVPDayInTheYear * cluster.modulationCapacity[hour]); + dstSeries[hour] = std::round(AVPDayInTheYear * modulation[hour]); ++hour; } } diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index c3be5f287d..8e3e691405 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -34,8 +34,6 @@ #include #include -#define SEP Yuni::IO::Separator - using namespace Antares; struct TsGeneratorSettings @@ -142,7 +140,9 @@ int main(int argc, char *argv[]) auto resultWriter = Solver::resultWriterFactory( Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); +#define SEP Yuni::IO::Separator const std::string savePath = std::string("ts-generator") + SEP + "thermal"; +#undef SEP std::vector clusters; From a9a8e6c01afbd143a25640f22fcd8122a220e679 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 21 Mar 2024 17:01:01 +0100 Subject: [PATCH 030/101] use year --- .../simulation/include/antares/solver/simulation/solver.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 282675745c..8e218d4f22 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -490,7 +490,7 @@ void ISimulation::regenerateTimeSeries(uint year) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); #define SEP Yuni::IO::Separator - const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-0"; + const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-l" + year; #undef SEP GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); } From c3c5dceff9d0ed8aef45c0d6895f9109d8681ad1 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 21 Mar 2024 17:45:07 +0100 Subject: [PATCH 031/101] fix compilw --- .../simulation/include/antares/solver/simulation/solver.hxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 8e218d4f22..c35acbf2d4 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -490,7 +490,8 @@ void ISimulation::regenerateTimeSeries(uint year) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); #define SEP Yuni::IO::Separator - const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-l" + year; + const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + + "mc-l" + std::to_string(year); #undef SEP GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); } From d8749ab922ea21a1247b5b5bb40cde67662120d4 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 22 Mar 2024 16:50:35 +0100 Subject: [PATCH 032/101] add function to get links to generate --- src/tools/ts-generator/main.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 8e3e691405..642e759c9f 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -55,6 +55,10 @@ std::unique_ptr createTsGeneratorParser(TsGeneratorSetting parser->addFlag(settings.thermalListToGen, ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); + parser->addFlag(settings.allThermal, ' ', "all-links", "Generate TS capacities for all links"); + + parser->addFlag(settings.thermalListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.linkName;area2ID.linkName\""); + parser->remainingArguments(settings.studyFolder); @@ -91,6 +95,35 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } +std::vector getLinkssToGen(Data::AreaList& areas, + const std::string& clustersToGen) +{ + std::vector links; + const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); + + for (const auto& [areaID, linkID] : ids) + { + logs.info() << "Generating ts for area: " << areaID << " and cluster: " << linkID; + + auto* area = areas.find(areaID); + if (!area) + { + logs.warning() << "Area not found: " << areaID; + continue; + } + + auto it = std::ranges::find_if(area->links, [&linkID](auto& l) + { return l.second->getName() == linkID;}); + + if (it != area->links.end()) + links.push_back(it->second); + else + logs.warning() << "Link not found: " << linkID; + } + + return links; +} + int main(int argc, char *argv[]) { TsGeneratorSettings settings; From 3031b8156482c39a0fd3854064bf97e955790cd1 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 22 Mar 2024 17:08:45 +0100 Subject: [PATCH 033/101] better handling of args --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 642e759c9f..d2b3b28e8f 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -179,9 +179,9 @@ int main(int argc, char *argv[]) std::vector clusters; - if (settings.thermalListToGen.empty()) + if (settings.allThermal) clusters = TSGenerator::getAllClustersToGen(study->areas, true); - else + else if (!settings.thermalListToGen.empty()) clusters = getClustersToGen(study->areas, settings.thermalListToGen); for (auto& c : clusters) From 4fa72e83b9cc6c7e7c4f57e3a45a9dc543e489a9 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 22 Mar 2024 17:25:57 +0100 Subject: [PATCH 034/101] add handling of link args --- src/tools/ts-generator/main.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index d2b3b28e8f..8de3ccbab6 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -44,6 +44,11 @@ struct TsGeneratorSettings bool allThermal = false; /// generate TS for a list "area.cluster;area2.cluster2;" std::string thermalListToGen = ""; + + /// generate TS for all links if activated + bool allLinks = false; + /// generate TS for a list "area.link;area2.link2;" + std::string linksListToGen = ""; }; std::unique_ptr createTsGeneratorParser(TsGeneratorSettings& settings) @@ -55,9 +60,9 @@ std::unique_ptr createTsGeneratorParser(TsGeneratorSetting parser->addFlag(settings.thermalListToGen, ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); - parser->addFlag(settings.allThermal, ' ', "all-links", "Generate TS capacities for all links"); + parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); - parser->addFlag(settings.thermalListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.linkName;area2ID.linkName\""); + parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.linkName;area2ID.linkName\""); parser->remainingArguments(settings.studyFolder); @@ -95,7 +100,7 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -std::vector getLinkssToGen(Data::AreaList& areas, +std::vector getLinksToGen(Data::AreaList& areas, const std::string& clustersToGen) { std::vector links; @@ -184,6 +189,11 @@ int main(int argc, char *argv[]) else if (!settings.thermalListToGen.empty()) clusters = getClustersToGen(study->areas, settings.thermalListToGen); + std::vector links; + + if (!settings.linksListToGen.empty()) + links = getLinksToGen(study->areas, settings.linksListToGen); + for (auto& c : clusters) logs.debug() << c->id(); From b5f545bb12ef550f727e5660ccb558cf573453c9 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 11:49:28 +0100 Subject: [PATCH 035/101] use ID --- src/tools/ts-generator/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 8de3ccbab6..f4e035cccb 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -118,7 +118,7 @@ std::vector getLinksToGen(Data::AreaList& areas, } auto it = std::ranges::find_if(area->links, [&linkID](auto& l) - { return l.second->getName() == linkID;}); + { return l.second->with->id == linkID;}); if (it != area->links.end()) links.push_back(it->second); @@ -197,5 +197,8 @@ int main(int argc, char *argv[]) for (auto& c : clusters) logs.debug() << c->id(); + for (auto& l : links) + logs.debug() << l->getName(); + return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter, savePath); } From 6dc3ea699403e238a6d4cf3f9b611b8a28f421fc Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 12:35:20 +0100 Subject: [PATCH 036/101] add function generateLinkTS --- src/solver/ts-generator/thermal.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 3e6cf1066d..b795ea9575 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -53,7 +53,7 @@ ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, Data::TimeSeries& capacity, - const std::string& linkName) : + const std::string& areaDestName) : unitCount(source.unitCount), nominalCapacity(source.nominalCapacity), forcedVolatility(source.forcedVolatility), @@ -63,7 +63,7 @@ ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, prepro(source.prepro), series(capacity), modulationCapacity(source.modulationCapacity[0]), - name(linkName) + name(areaDestName) {} namespace @@ -639,4 +639,22 @@ bool GenerateThermalTimeSeries(Data::Study& study, return true; } +bool generateLinkTimeSeries(Data::Study& study, + std::vector links, + Solver::IResultWriter& writer, + const std::string& savePath) +{ + logs.info(); + logs.info() << "Generating the links time-series"; + + auto generator = std::make_unique(study); + + for (auto* link: links) + { + ThermalInterface clusterInterface(link->tsGeneration, link->directCapacities, link->with->name); + (*generator)(*link->from, clusterInterface); + } + + return true; +} } // namespace Antares::TSGenerator From 2c9a8f6b0cec698049267a9097241d5c7f635343 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 12:45:10 +0100 Subject: [PATCH 037/101] call function --- .../antares/solver/ts-generator/generator.h | 5 +++++ src/tools/ts-generator/main.cpp | 16 +++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 565ef34b85..aec734dc04 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -70,6 +70,11 @@ bool GenerateThermalTimeSeries(Data::Study& study, Solver::IResultWriter& writer, const std::string& savePath); +bool generateLinkTimeSeries(Data::Study& study, + std::vector links, + Solver::IResultWriter& writer, + const std::string& savePath); + std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration); /*! diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index f4e035cccb..4e292fd798 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -179,26 +179,28 @@ int main(int argc, char *argv[]) Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); #define SEP Yuni::IO::Separator - const std::string savePath = std::string("ts-generator") + SEP + "thermal"; + const std::string thermalSavePath = std::string("ts-generator") + SEP + "thermal"; + const std::string linksSavePath = std::string("ts-generator") + SEP + "links"; #undef SEP + // THERMAL std::vector clusters; - if (settings.allThermal) clusters = TSGenerator::getAllClustersToGen(study->areas, true); else if (!settings.thermalListToGen.empty()) clusters = getClustersToGen(study->areas, settings.thermalListToGen); - std::vector links; + for (auto& c : clusters) + logs.debug() << c->id(); + // LINKS + std::vector links; if (!settings.linksListToGen.empty()) links = getLinksToGen(study->areas, settings.linksListToGen); - for (auto& c : clusters) - logs.debug() << c->id(); - for (auto& l : links) logs.debug() << l->getName(); - return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter, savePath); + return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath) + && !TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath); } From 5f9afcbbde20572a4950bc62e8b03b1c62ad928c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 14:09:16 +0100 Subject: [PATCH 038/101] fix arg description --- src/tools/ts-generator/main.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 4e292fd798..9a02b42f35 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -57,16 +57,13 @@ std::unique_ptr createTsGeneratorParser(TsGeneratorSetting parser->addParagraph("Antares Time Series generator\n"); parser->addFlag(settings.allThermal, ' ', "all-thermal", "Generate TS for all thermal clusters"); - parser->addFlag(settings.thermalListToGen, ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); - - parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.linkName;area2ID.linkName\""); + parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); parser->remainingArguments(settings.studyFolder); - return parser; } From 4f943e53dcbf489578ae7f141dfe200f8a503ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= <26088210+flomnes@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:23:13 +0100 Subject: [PATCH 039/101] Invert dependency on TS-Generator data (#2006) ### Before `AreaLink` depends on `ThermalCluster` ### After `AreaLink` and `ThermalCluster` depend on `ThermalPrepro` and `ThermalLaw`, both of which are defined in ts-generator. --- src/libs/antares/study/CMakeLists.txt | 3 - .../study/include/antares/study/area/links.h | 4 +- .../antares/study/include/antares/study/fwd.h | 4 -- .../study/include/antares/study/parts/parts.h | 1 - .../antares/study/parts/thermal/cluster.h | 19 +++--- .../antares/study/parts/thermal/cluster.cpp | 22 +++---- src/solver/ts-generator/CMakeLists.txt | 8 ++- .../antares/solver/ts-generator/generator.h | 6 +- .../include/antares/solver/ts-generator/law.h | 10 +++ .../antares/solver/ts-generator}/prepro.h | 7 +-- .../antares/solver/ts-generator}/prepro.hxx | 0 .../ts-generator}/prepro.cpp | 4 +- src/solver/ts-generator/thermal.cpp | 61 +++++++++---------- .../renderer/area/thermalmodulation.h | 2 +- .../datagrid/renderer/area/thermalprepro.h | 2 +- .../windows/inspector/property.update.cpp | 3 +- 16 files changed, 77 insertions(+), 79 deletions(-) create mode 100644 src/solver/ts-generator/include/antares/solver/ts-generator/law.h rename src/{libs/antares/study/include/antares/study/parts/thermal => solver/ts-generator/include/antares/solver/ts-generator}/prepro.h (97%) rename src/{libs/antares/study/include/antares/study/parts/thermal => solver/ts-generator/include/antares/solver/ts-generator}/prepro.hxx (100%) rename src/{libs/antares/study/parts/thermal => solver/ts-generator}/prepro.cpp (98%) diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 5e559be2c8..6c9340c11b 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -70,9 +70,6 @@ source_group("study\\part\\common" FILES ${SRC_STUDY_PART_COMMON}) set(SRC_STUDY_PART_THERMAL include/antares/study/parts/thermal/container.h parts/thermal/container.cpp - include/antares/study/parts/thermal/prepro.h - include/antares/study/parts/thermal/prepro.hxx - parts/thermal/prepro.cpp include/antares/study/parts/thermal/ecoInput.h parts/thermal/ecoInput.cpp include/antares/study/parts/thermal/cluster.h diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index c69aca3d0a..8d798863f4 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -21,7 +21,9 @@ #ifndef __ANTARES_LIBS_STUDY_LINKS_H__ #define __ANTARES_LIBS_STUDY_LINKS_H__ -#include +//#include +#include +#include #include #include #include diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index c5e5933691..1cf7bf843d 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -223,8 +223,6 @@ enum TimeSeriesType : unsigned int // *********************************************************************** }; // enum TimeSeries - - template struct TimeSeriesBitPatternIntoIndex; @@ -551,8 +549,6 @@ class Sets; } // namespace Antares::Data::ScenarioBuilder - - namespace Benchmarking { class IDurationCollector; diff --git a/src/libs/antares/study/include/antares/study/parts/parts.h b/src/libs/antares/study/include/antares/study/parts/parts.h index 7f02083486..db927118f9 100644 --- a/src/libs/antares/study/include/antares/study/parts/parts.h +++ b/src/libs/antares/study/include/antares/study/parts/parts.h @@ -40,7 +40,6 @@ // Thermal #include "thermal/defines.h" -#include "thermal/prepro.h" #include "thermal/cluster.h" #include "thermal/container.h" diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h index 3b32763d51..dbdcae4123 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h @@ -24,8 +24,8 @@ #include #include #include +#include #include "defines.h" -#include "prepro.h" #include "ecoInput.h" #include "../common/cluster.h" #include "../../fwd.h" @@ -39,12 +39,6 @@ namespace Antares { namespace Data { -enum ThermalLaw -{ - thermalLawUniform, - thermalLawGeometric -}; - enum ThermalModulation { thermalModulationCost = 0, @@ -239,7 +233,10 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this //! Mustrun bool mustrun = false; - bool isMustRun() const { return mustrun; } + bool isMustRun() const + { + return mustrun; + } //! Mustrun (as it were at the loading of the data) // @@ -378,12 +375,12 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this // // Calculation of market bid and marginals costs per hour // - // These time series can be set + // These time series can be set // Market bid and marginal costs are set manually. // Or if time series are used the formula is: // Marginal_Cost[€/MWh] = Market_Bid_Cost[€/MWh] = (Fuel_Cost[€/GJ] * 3.6 * 100 / Efficiency[%]) // CO2_emission_factor[tons/MWh] * C02_cost[€/tons] + Variable_O&M_cost[€/MWh] - + void fillMarketBidCostTS(); void fillMarginalCostTS(); void resizeCostTS(); @@ -391,8 +388,6 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this void MarginalCostEqualsMarketBid(); void ComputeProductionCostTS(); - - }; // class ThermalCluster } // namespace Data } // namespace Antares diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index b8a313b99a..60f2e2cecb 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -28,6 +28,7 @@ #include #include "antares/study/study.h" #include "antares/study/parts/thermal/cluster.h" +#include #include #include #include @@ -105,16 +106,12 @@ bool Into::Perform(AnyString string, T } // namespace Yuni::Extension::CString - - namespace Antares { namespace Data { Data::ThermalCluster::ThermalCluster(Area* parent) : - Cluster(parent), - PthetaInf(HOURS_PER_YEAR, 0), - costsTimeSeries(1, CostsTimeSeries()) + Cluster(parent), PthetaInf(HOURS_PER_YEAR, 0), costsTimeSeries(1, CostsTimeSeries()) { // assert assert(parent && "A parent for a thermal dispatchable cluster can not be null"); @@ -225,7 +222,7 @@ static Data::ThermalCluster::ThermalDispatchableGroup stringToGroup(Data::Cluste {"other 4", ThermalCluster::thermalDispatchGrpOther4}}; boost::to_lower(newgrp); - if (auto res = mapping.find(newgrp);res != mapping.end()) + if (auto res = mapping.find(newgrp); res != mapping.end()) { return res->second; } @@ -380,10 +377,9 @@ void ThermalCluster::ComputeProductionCostTS() } } - double Data::ThermalCluster::computeMarketBidCost(double fuelCost, - double co2EmissionFactor, - double co2cost) + double co2EmissionFactor, + double co2cost) { return fuelCost * 360.0 / fuelEfficiency + co2EmissionFactor * co2cost + variableomcost; } @@ -768,9 +764,8 @@ void ThermalCluster::checkAndCorrectAvailability() { for (uint x = 0; x != series.timeSeries.width; ++x) { - auto rightpart - = PminDUnGroupeDuPalierThermique - * ceil(series.timeSeries.entry[x][y] / PmaxDUnGroupeDuPalierThermique); + auto rightpart = PminDUnGroupeDuPalierThermique + * ceil(series.timeSeries.entry[x][y] / PmaxDUnGroupeDuPalierThermique); condition = rightpart > series.timeSeries.entry[x][y]; if (condition) { @@ -785,7 +780,8 @@ void ThermalCluster::checkAndCorrectAvailability() << " available power lifted to match Pmin and Pnom requirements"; } -bool ThermalCluster::isActive() const { +bool ThermalCluster::isActive() const +{ return enabled && !mustrun; } diff --git a/src/solver/ts-generator/CMakeLists.txt b/src/solver/ts-generator/CMakeLists.txt index 3590cbf13f..97960c7c48 100644 --- a/src/solver/ts-generator/CMakeLists.txt +++ b/src/solver/ts-generator/CMakeLists.txt @@ -20,6 +20,12 @@ set(SRC_XCAST include/antares/solver/ts-generator/xcast/constants.h include/antares/solver/ts-generator/xcast/studydata.h include/antares/solver/ts-generator/xcast/studydata.hxx + include/antares/solver/ts-generator/law.h + + prepro.cpp + + include/antares/solver/ts-generator/prepro.h + include/antares/solver/ts-generator/prepro.hxx xcast/studydata.cpp xcast/gamma-euler.cpp xcast/gamma-inc.cpp @@ -58,4 +64,4 @@ target_include_directories(antares-solver-ts-generator install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index aec734dc04..463a568e9a 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -26,21 +26,21 @@ #include #include #include +#include #include #include #include "xcast/xcast.h" namespace Antares::TSGenerator { - class ThermalInterface { public: explicit ThermalInterface(Data::ThermalCluster*); ThermalInterface(Data::AreaLink::LinkTsGeneration&, Data::TimeSeries&, const std::string& name); - const unsigned &unitCount; - const double &nominalCapacity; + const unsigned& unitCount; + const double& nominalCapacity; const double& forcedVolatility; const double& plannedVolatility; diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/law.h b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h new file mode 100644 index 0000000000..35214c540d --- /dev/null +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h @@ -0,0 +1,10 @@ +#pragma once + +namespace Antares::Data +{ +enum ThermalLaw +{ + thermalLawUniform, + thermalLawGeometric +}; +} diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h similarity index 97% rename from src/libs/antares/study/include/antares/study/parts/thermal/prepro.h rename to src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index b921a02a50..6b373199bf 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -21,10 +21,9 @@ #ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_H__ #define __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_H__ -#include "cluster.h" #include -#include "defines.h" -#include "../../fwd.h" +#include +#include #include namespace Antares @@ -68,8 +67,6 @@ class PreproThermal void markAsModified() const; - - /*! ** \brief Reset all values to their default ones */ diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/prepro.hxx b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx similarity index 100% rename from src/libs/antares/study/include/antares/study/parts/thermal/prepro.hxx rename to src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx diff --git a/src/libs/antares/study/parts/thermal/prepro.cpp b/src/solver/ts-generator/prepro.cpp similarity index 98% rename from src/libs/antares/study/parts/thermal/prepro.cpp rename to src/solver/ts-generator/prepro.cpp index 2048d44496..36659e1439 100644 --- a/src/libs/antares/study/parts/thermal/prepro.cpp +++ b/src/solver/ts-generator/prepro.cpp @@ -24,7 +24,7 @@ #include #include #include "antares/study/study.h" -#include "antares/study/parts/thermal/prepro.h" +#include #include using namespace Yuni; @@ -157,7 +157,7 @@ bool PreproThermal::loadFromFolder(Study& study, const AnyString& folder) bool PreproThermal::forceReload(bool reload) const { - return data.forceReload(reload); + return data.forceReload(reload); } void PreproThermal::markAsModified() const diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index b795ea9575..6cd860d2c7 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -28,7 +28,7 @@ #include #include - +#include #include "antares/study/simulation.h" #define SEP Yuni::IO::Separator @@ -37,38 +37,38 @@ namespace Antares::TSGenerator { - -ThermalInterface::ThermalInterface(Data::ThermalCluster *source) : - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro), - series(source->series), - modulationCapacity(source->modulation[Data::thermalModulationCapacity]), - name(source->name()) -{} +ThermalInterface::ThermalInterface(Data::ThermalCluster* source) : + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw), + prepro(source->prepro), + series(source->series), + modulationCapacity(source->modulation[Data::thermalModulationCapacity]), + name(source->name()) +{ +} ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, Data::TimeSeries& capacity, const std::string& areaDestName) : - unitCount(source.unitCount), - nominalCapacity(source.nominalCapacity), - forcedVolatility(source.forcedVolatility), - plannedVolatility(source.plannedVolatility), - forcedLaw(source.forcedLaw), - plannedLaw(source.plannedLaw), - prepro(source.prepro), - series(capacity), - modulationCapacity(source.modulationCapacity[0]), - name(areaDestName) -{} + unitCount(source.unitCount), + nominalCapacity(source.nominalCapacity), + forcedVolatility(source.forcedVolatility), + plannedVolatility(source.plannedVolatility), + forcedLaw(source.forcedLaw), + plannedLaw(source.plannedLaw), + prepro(source.prepro), + series(capacity), + modulationCapacity(source.modulationCapacity[0]), + name(areaDestName) +{ +} namespace { - class GeneratorTempData final { public: @@ -120,8 +120,7 @@ class GeneratorTempData final }; GeneratorTempData::GeneratorTempData(Data::Study& study) : - study(study), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]) + study(study), rndgenerator(study.runtime->random[Data::seedTsGenThermal]) { auto& parameters = study.parameters; @@ -569,7 +568,6 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu if (derated) cluster.series.timeSeries.averageTimeseries(); - } } // namespace @@ -649,9 +647,10 @@ bool generateLinkTimeSeries(Data::Study& study, auto generator = std::make_unique(study); - for (auto* link: links) + for (auto* link : links) { - ThermalInterface clusterInterface(link->tsGeneration, link->directCapacities, link->with->name); + ThermalInterface clusterInterface( + link->tsGeneration, link->directCapacities, link->with->name); (*generator)(*link->from, clusterInterface); } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalmodulation.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalmodulation.h index 7d0ccecba8..8d61013f29 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalmodulation.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalmodulation.h @@ -23,7 +23,7 @@ #include "../../../../input/thermal-cluster.h" #include "../matrix.h" -#include +#include namespace Antares { diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h index 7a80563695..90f372eea7 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h @@ -23,7 +23,7 @@ #include "../../../../input/thermal-cluster.h" #include "../matrix.h" -#include +#include namespace Antares { diff --git a/src/ui/simulator/windows/inspector/property.update.cpp b/src/ui/simulator/windows/inspector/property.update.cpp index 82ad2acf00..06e7c619bb 100644 --- a/src/ui/simulator/windows/inspector/property.update.cpp +++ b/src/ui/simulator/windows/inspector/property.update.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include "../message.h" #include "../../application/main/internal-ids.h" #include "property.cluster.update.h" @@ -797,7 +798,7 @@ bool InspectorGrid::onPropertyChanging_ThermalCluster(wxPGProperty*, (*i)->marginalCost = d; (*i)->ComputeCostTimeSeries(); // update } - + pFrame.delayApply(); // Notify OnStudyThermalClusterCommonSettingsChanged(); From 3dbd0915706ed9b729b3ac21bd6880701abd8718 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 15:57:59 +0100 Subject: [PATCH 040/101] add save for links --- src/solver/ts-generator/thermal.cpp | 43 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 6cd860d2c7..5657e170b1 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -585,10 +585,7 @@ void writeResultsToDisk(const Data::Study& study, pTempFilename.clear() << savePath << SEP << area.id << SEP << cluster.id() << ".txt"; - enum - { - precision = 0 - }; + enum { precision = 0 }; std::string buffer; cluster.series.timeSeries.saveToBuffer(buffer, precision); @@ -596,6 +593,34 @@ void writeResultsToDisk(const Data::Study& study, writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); } +void writeLinksResultsToDisk(const Data::Study& study, + Solver::IResultWriter& writer, + const Data::AreaLink& link, + const std::string& savePath, + bool directCapacity) +{ + if (study.parameters.noOutput) + return; + + std::string direction = directCapacity ? "direct" : "indirect"; + + Yuni::String pTempFilename; + pTempFilename.reserve(study.folderOutput.size() + 256); + + pTempFilename.clear() << savePath << SEP << link.from->id << SEP << + link.with->id << "_" << direction << ".txt"; + + enum { precision = 0 }; + + std::string buffer; + if (directCapacity) + link.directCapacities.timeSeries.saveToBuffer(buffer, precision); + else + link.indirectCapacities.timeSeries.saveToBuffer(buffer, precision); + + writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); +} + std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration) { @@ -649,9 +674,13 @@ bool generateLinkTimeSeries(Data::Study& study, for (auto* link : links) { - ThermalInterface clusterInterface( - link->tsGeneration, link->directCapacities, link->with->name); - (*generator)(*link->from, clusterInterface); + ThermalInterface clusterInterfaceDirect( + link->tsGeneration, link->directCapacities, link->with->name); + ThermalInterface clusterInterfaceIndirect( + link->tsGeneration, link->indirectCapacities, link->with->name); + + (*generator)(*link->from, clusterInterfaceDirect); + (*generator)(*link->from, clusterInterfaceIndirect); } return true; From 6251f6be61a5567b0fe16157a40d608649fcf9cd Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 16:27:06 +0100 Subject: [PATCH 041/101] save both capacities --- src/solver/ts-generator/thermal.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 5657e170b1..57bb07c5ce 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -596,28 +596,28 @@ void writeResultsToDisk(const Data::Study& study, void writeLinksResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Data::AreaLink& link, - const std::string& savePath, - bool directCapacity) + const std::string& savePath) { if (study.parameters.noOutput) return; - std::string direction = directCapacity ? "direct" : "indirect"; + enum { precision = 0 }; + std::string buffer; Yuni::String pTempFilename; pTempFilename.reserve(study.folderOutput.size() + 256); pTempFilename.clear() << savePath << SEP << link.from->id << SEP << - link.with->id << "_" << direction << ".txt"; + link.with->id << "_direct.txt"; - enum { precision = 0 }; + link.directCapacities.timeSeries.saveToBuffer(buffer, precision); + writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); - std::string buffer; - if (directCapacity) - link.directCapacities.timeSeries.saveToBuffer(buffer, precision); - else - link.indirectCapacities.timeSeries.saveToBuffer(buffer, precision); + pTempFilename.clear() << savePath << SEP << link.from->id << SEP << + link.with->id << "_indirect.txt"; + + link.indirectCapacities.timeSeries.saveToBuffer(buffer, precision); writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); } From b4f129a684ec2ce98aceaae7ae6b02912b3bc8a9 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 16:27:39 +0100 Subject: [PATCH 042/101] fix type --- .../simulation/include/antares/solver/simulation/solver.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index c35acbf2d4..10228c5647 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -491,7 +491,7 @@ void ISimulation::regenerateTimeSeries(uint year) auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); #define SEP Yuni::IO::Separator const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + - "mc-l" + std::to_string(year); + "mc-" + std::to_string(year); #undef SEP GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); } From 5b0a621093cd9b386b7274d9c74a1ef3d82a2f42 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 25 Mar 2024 16:33:24 +0100 Subject: [PATCH 043/101] add write call --- src/solver/ts-generator/thermal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 57bb07c5ce..158baed991 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -681,6 +681,8 @@ bool generateLinkTimeSeries(Data::Study& study, (*generator)(*link->from, clusterInterfaceDirect); (*generator)(*link->from, clusterInterfaceIndirect); + + writeLinksResultsToDisk(study, writer, *link, savePath); } return true; From 5cf0319e142e8e53a6ca3b20cc861ab0fadabb52 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 26 Mar 2024 10:31:33 +0100 Subject: [PATCH 044/101] add seed and param nb of link series --- src/libs/antares/study/fwd.cpp | 4 ++++ src/libs/antares/study/include/antares/study/fwd.h | 2 ++ src/libs/antares/study/include/antares/study/parameters.h | 2 ++ src/libs/antares/study/parameters.cpp | 2 ++ 4 files changed, 10 insertions(+) diff --git a/src/libs/antares/study/fwd.cpp b/src/libs/antares/study/fwd.cpp index 6abae87d3d..8d6e8e24dd 100644 --- a/src/libs/antares/study/fwd.cpp +++ b/src/libs/antares/study/fwd.cpp @@ -40,6 +40,8 @@ const char* SeedToCString(SeedIndex seed) return "Thermal time-series generation"; case seedTsGenSolar: return "Solar time-series generation"; + case seedTsGenLinks: + return "Links time-series generation"; case seedTimeseriesNumbers: return "Time-series draws (MC scenario builder)"; case seedUnsuppliedEnergyCosts: @@ -72,6 +74,8 @@ const char* SeedToID(SeedIndex seed) return "seed-tsgen-thermal"; case seedTsGenSolar: return "seed-tsgen-solar"; + case seedTsGenLinks: + return "seed-tsgen-links"; case seedTimeseriesNumbers: return "seed-tsnumbers"; case seedUnsuppliedEnergyCosts: diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index 1cf7bf843d..836a23532e 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -338,6 +338,8 @@ enum SeedIndex seedTsGenThermal, //! The seed for solar seedTsGenSolar, + //! The seed for links + seedTsGenLinks, //! The seed used for time-series numbers seedTimeseriesNumbers, //! Seed - unsupplied energy costs diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index ca7a774245..a8335881f6 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -268,6 +268,8 @@ class Parameters final uint nbTimeSeriesThermal; //! Nb of timeSeries : Solar uint nbTimeSeriesSolar; + //! Nb of timeSeries : Solar + uint nbTimeSeriesLinks; //@} //! \name Time-series refresh diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index b070f0f188..12088231b0 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -900,6 +900,8 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, return value.to(d.seed[seedTsGenThermal]); if (key == "seed_solar") return value.to(d.seed[seedTsGenSolar]); + if (key == "seed_links") + return value.to(d.seed[seedTsGenLinks]); if (key == "seed_timeseriesnumbers") return value.to(d.seed[seedTimeseriesNumbers]); } From 01659803bb165bf9e682adf54e21c3c06631c43f Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 26 Mar 2024 10:43:02 +0100 Subject: [PATCH 045/101] use correct number of ts to gen --- src/solver/ts-generator/thermal.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 158baed991..c788a8e330 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -72,7 +72,7 @@ namespace class GeneratorTempData final { public: - explicit GeneratorTempData(Data::Study& study); + explicit GeneratorTempData(Data::Study&, unsigned); void operator()(const Data::Area& area, ThermalInterface& cluster); @@ -119,12 +119,12 @@ class GeneratorTempData final Yuni::String pTempFilename; }; -GeneratorTempData::GeneratorTempData(Data::Study& study) : +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : study(study), rndgenerator(study.runtime->random[Data::seedTsGenThermal]) { auto& parameters = study.parameters; - nbThermalTimeseries_ = parameters.nbTimeSeriesThermal; + nbThermalTimeseries_ = nbOfSeriesToGen; derated = parameters.derated; @@ -645,7 +645,7 @@ bool GenerateThermalTimeSeries(Data::Study& study, bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - auto generator = std::make_unique(study); + auto generator = std::make_unique(study, study.parameters.nbTimeSeriesThermal); // TODO VP: parallel for (auto* cluster : clusters) @@ -670,7 +670,7 @@ bool generateLinkTimeSeries(Data::Study& study, logs.info(); logs.info() << "Generating the links time-series"; - auto generator = std::make_unique(study); + auto generator = std::make_unique(study, study.parameters.nbTimeSeriesLinks); for (auto* link : links) { From 19ed14c0fbec3b0dfbf6d628cfb2ef951f3bc43b Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 26 Mar 2024 11:21:53 +0100 Subject: [PATCH 046/101] use intermediate matrix --- src/solver/ts-generator/thermal.cpp | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index c788a8e330..e976030d9b 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -596,7 +596,9 @@ void writeResultsToDisk(const Data::Study& study, void writeLinksResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Data::AreaLink& link, - const std::string& savePath) + Matrix<>& series, + const std::string& savePath, + bool direct) { if (study.parameters.noOutput) return; @@ -604,20 +606,16 @@ void writeLinksResultsToDisk(const Data::Study& study, enum { precision = 0 }; std::string buffer; + std::string capacityType = direct ? "_direct" : "_indirect"; + Yuni::String pTempFilename; pTempFilename.reserve(study.folderOutput.size() + 256); pTempFilename.clear() << savePath << SEP << link.from->id << SEP << - link.with->id << "_direct.txt"; - - link.directCapacities.timeSeries.saveToBuffer(buffer, precision); - writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); + link.with->id << capacityType << ".txt"; + series.saveToBuffer(buffer, precision); - pTempFilename.clear() << savePath << SEP << link.from->id << SEP << - link.with->id << "_indirect.txt"; - - link.indirectCapacities.timeSeries.saveToBuffer(buffer, precision); writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); } @@ -674,15 +672,17 @@ bool generateLinkTimeSeries(Data::Study& study, for (auto* link : links) { - ThermalInterface clusterInterfaceDirect( - link->tsGeneration, link->directCapacities, link->with->name); - ThermalInterface clusterInterfaceIndirect( - link->tsGeneration, link->indirectCapacities, link->with->name); + Data::TimeSeries ts(link->timeseriesNumbers); + ts.resize(study.parameters.nbTimeSeriesLinks, HOURS_PER_YEAR); - (*generator)(*link->from, clusterInterfaceDirect); - (*generator)(*link->from, clusterInterfaceIndirect); + // direct capacity + ThermalInterface clusterInterface(link->tsGeneration, ts, link->with->name); + (*generator)(*link->from, clusterInterface); + writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, true); - writeLinksResultsToDisk(study, writer, *link, savePath); + // indirect capacity + (*generator)(*link->from, clusterInterface); + writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, false); } return true; From f930267e5ab9bb24f8bd70666462bd930a5ca7a5 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 26 Mar 2024 12:27:31 +0100 Subject: [PATCH 047/101] property struct for ts direct and indirect --- src/libs/antares/study/include/antares/study/area/links.h | 3 ++- src/solver/ts-generator/thermal.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index 8d798863f4..88c2639bc3 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -224,7 +224,8 @@ class AreaLink final : public Yuni::NonCopyable Matrix<> modulationCapacity; }; - LinkTsGeneration tsGeneration; + LinkTsGeneration tsGenerationDirect; + LinkTsGeneration tsGenerationIndirect; }; // class AreaLink diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index e976030d9b..6f2455bf6d 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -676,12 +676,13 @@ bool generateLinkTimeSeries(Data::Study& study, ts.resize(study.parameters.nbTimeSeriesLinks, HOURS_PER_YEAR); // direct capacity - ThermalInterface clusterInterface(link->tsGeneration, ts, link->with->name); - (*generator)(*link->from, clusterInterface); + ThermalInterface clusterInterfaceDirect(link->tsGenerationDirect, ts, link->with->name); + (*generator)(*link->from, clusterInterfaceDirect); writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, true); // indirect capacity - (*generator)(*link->from, clusterInterface); + ThermalInterface clusterInterfaceIndirect(link->tsGenerationIndirect, ts, link->with->name); + (*generator)(*link->from, clusterInterfaceIndirect); writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, false); } From 0a55a49014b8a05607d8e8bd8ac1438370229d3c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 26 Mar 2024 18:04:46 +0100 Subject: [PATCH 048/101] try fixing res diff --- src/libs/antares/study/fwd.cpp | 8 ++++---- src/libs/antares/study/include/antares/study/fwd.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/antares/study/fwd.cpp b/src/libs/antares/study/fwd.cpp index 8d6e8e24dd..88580e32fd 100644 --- a/src/libs/antares/study/fwd.cpp +++ b/src/libs/antares/study/fwd.cpp @@ -40,8 +40,6 @@ const char* SeedToCString(SeedIndex seed) return "Thermal time-series generation"; case seedTsGenSolar: return "Solar time-series generation"; - case seedTsGenLinks: - return "Links time-series generation"; case seedTimeseriesNumbers: return "Time-series draws (MC scenario builder)"; case seedUnsuppliedEnergyCosts: @@ -54,6 +52,8 @@ const char* SeedToCString(SeedIndex seed) return "Noise on virtual Hydro costs"; case seedHydroManagement: return "Initial reservoir levels"; + case seedTsGenLinks: + return "Links time-series generation"; case seedMax: return ""; } @@ -74,8 +74,6 @@ const char* SeedToID(SeedIndex seed) return "seed-tsgen-thermal"; case seedTsGenSolar: return "seed-tsgen-solar"; - case seedTsGenLinks: - return "seed-tsgen-links"; case seedTimeseriesNumbers: return "seed-tsnumbers"; case seedUnsuppliedEnergyCosts: @@ -88,6 +86,8 @@ const char* SeedToID(SeedIndex seed) return "seed-hydro-costs"; case seedHydroManagement: return "seed-initial-reservoir-levels"; + case seedTsGenLinks: + return "seed-tsgen-links"; case seedMax: return ""; } diff --git a/src/libs/antares/study/include/antares/study/fwd.h b/src/libs/antares/study/include/antares/study/fwd.h index 836a23532e..0edcedc4da 100644 --- a/src/libs/antares/study/include/antares/study/fwd.h +++ b/src/libs/antares/study/include/antares/study/fwd.h @@ -338,8 +338,6 @@ enum SeedIndex seedTsGenThermal, //! The seed for solar seedTsGenSolar, - //! The seed for links - seedTsGenLinks, //! The seed used for time-series numbers seedTimeseriesNumbers, //! Seed - unsupplied energy costs @@ -352,6 +350,8 @@ enum SeedIndex seedHydroCosts, //! Seed - Hydro management seedHydroManagement, + //! The seed for links + seedTsGenLinks, //! The number of seeds seedMax, }; From ddc28df4c260e37b52343bbffb3c9fa1d73d407c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 11:35:04 +0100 Subject: [PATCH 049/101] Add ts generator test to ubuntu CI --- .github/workflows/ubuntu.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index dc9a194768..538240ff35 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -191,6 +191,15 @@ jobs: batch-name: valid-v910 os: ${{ env.os }} + - name: Run tests for time series generator tool + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: ts-generator + os: ${{ env.os }} + variant: "tsgenerator" + - name: Run short-tests if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} uses: ./.github/workflows/run-tests From 0cb0919b4c9b5d0df736c8ee0216b1419d091cb8 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 12:11:54 +0100 Subject: [PATCH 050/101] Add ts generator test to windows CI --- .github/workflows/windows-vcpkg.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index c721bf6f91..d9d1bed21b 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -261,6 +261,15 @@ jobs: batch-name: valid-mps os: ${{ env.test-platform }} + - name: Run tests for time series generator tool + if: ${{ env.RUN_SIMPLE_TESTS == 'true' }} + uses: ./.github/workflows/run-tests + with: + simtest-tag: ${{steps.simtest-version.outputs.prop}} + batch-name: ts-generator + os: ${{ env.os }} + variant: "tsgenerator" + - name: Run parallel tests if: ${{ env.RUN_EXTENDED_TESTS == 'true' }} uses: ./.github/workflows/run-tests From aab9d29f8d279775eff48cbc2cb44ac16463e986 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 14:20:59 +0100 Subject: [PATCH 051/101] fix os windows ci --- .github/workflows/windows-vcpkg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index d9d1bed21b..efa622489a 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -267,7 +267,7 @@ jobs: with: simtest-tag: ${{steps.simtest-version.outputs.prop}} batch-name: ts-generator - os: ${{ env.os }} + os: ${{ env.test-platform }} variant: "tsgenerator" - name: Run parallel tests From 6daae6bd1d1c44aa64f36630627a8317cb582b5d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 15:14:44 +0100 Subject: [PATCH 052/101] coding style --- .../antares/solver/simulation/solver.hxx | 2 +- .../antares/solver/ts-generator/generator.h | 2 +- src/solver/ts-generator/thermal.cpp | 40 ++++++++++--------- src/tools/ts-generator/main.cpp | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 10228c5647..64c14f6a0d 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -493,7 +493,7 @@ void ISimulation::regenerateTimeSeries(uint year) const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-" + std::to_string(year); #undef SEP - GenerateThermalTimeSeries(study, clusters, pResultWriter, savePath); + generateThermalTimeSeries(study, clusters, pResultWriter, savePath); } timer.stop(); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 463a568e9a..875caabfee 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -65,7 +65,7 @@ void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); template bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer); -bool GenerateThermalTimeSeries(Data::Study& study, +bool generateThermalTimeSeries(Data::Study& study, std::vector clusters, Solver::IResultWriter& writer, const std::string& savePath); diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 6f2455bf6d..9e7b9d39c4 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -571,7 +571,21 @@ void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& clu } } // namespace -void writeResultsToDisk(const Data::Study& study, +std::vector getAllClustersToGen(Data::AreaList& areas, + bool globalThermalTSgeneration) +{ + std::vector clusters; + + areas.each([&clusters, &globalThermalTSgeneration](Data::Area& area) { + for (auto cluster : area.thermal.list.all()) + if (cluster->doWeGenerateTS(globalThermalTSgeneration)) + clusters.push_back(cluster.get()); + }); + + return clusters; +} + +void writeThermalResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Data::Area& area, const Data::ThermalCluster& cluster, @@ -619,21 +633,7 @@ void writeLinksResultsToDisk(const Data::Study& study, writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); } -std::vector getAllClustersToGen(Data::AreaList& areas, - bool globalThermalTSgeneration) -{ - std::vector clusters; - - areas.each([&clusters, &globalThermalTSgeneration](Data::Area& area) { - for (auto cluster : area.thermal.list.all()) - if (cluster->doWeGenerateTS(globalThermalTSgeneration)) - clusters.push_back(cluster.get()); - }); - - return clusters; -} - -bool GenerateThermalTimeSeries(Data::Study& study, +bool generateThermalTimeSeries(Data::Study& study, std::vector clusters, Solver::IResultWriter& writer, const std::string& savePath) @@ -643,7 +643,8 @@ bool GenerateThermalTimeSeries(Data::Study& study, bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - auto generator = std::make_unique(study, study.parameters.nbTimeSeriesThermal); + auto generator = std::make_unique + (study, study.parameters.nbTimeSeriesThermal); // TODO VP: parallel for (auto* cluster : clusters) @@ -652,7 +653,7 @@ bool GenerateThermalTimeSeries(Data::Study& study, (*generator)(*cluster->parentArea, clusterInterface); if (archive) - writeResultsToDisk(study, writer, *cluster->parentArea, *cluster, savePath); + writeThermalResultsToDisk(study, writer, *cluster->parentArea, *cluster, savePath); cluster->calculationOfSpinning(); } @@ -668,7 +669,8 @@ bool generateLinkTimeSeries(Data::Study& study, logs.info(); logs.info() << "Generating the links time-series"; - auto generator = std::make_unique(study, study.parameters.nbTimeSeriesLinks); + auto generator = std::make_unique + (study, study.parameters.nbTimeSeriesLinks); for (auto* link : links) { diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 9a02b42f35..048f81e6b2 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -198,6 +198,6 @@ int main(int argc, char *argv[]) for (auto& l : links) logs.debug() << l->getName(); - return !TSGenerator::GenerateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath) + return !TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath) && !TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath); } From 1a0fb4617beb724ba26ec37c863affc129842570 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 15:45:30 +0100 Subject: [PATCH 053/101] add function to generate all links --- src/solver/ts-generator/thermal.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 9e7b9d39c4..0a44621d7f 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -585,6 +585,19 @@ std::vector getAllClustersToGen(Data::AreaList& areas, return clusters; } +std::vector getAllLinksToGen(Data::AreaList& areas) +{ + std::vector links; + + areas.each([&links](Data::Area& area) { + std::ranges::for_each(area.links, [&links](auto& l) { + links.push_back(l.second); + }); + }); + + return links; +} + void writeThermalResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, const Data::Area& area, From ae6d129f4373dd5f62728efef7f553b7c2c0b72e Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 27 Mar 2024 17:48:10 +0100 Subject: [PATCH 054/101] working option all links --- .../include/antares/solver/ts-generator/generator.h | 3 +++ src/tools/ts-generator/main.cpp | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 875caabfee..e7dcf946b3 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -77,6 +77,9 @@ bool generateLinkTimeSeries(Data::Study& study, std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration); + +std::vector getAllLinksToGen(Data::AreaList& areas); + /*! ** \brief Destroy all TS Generators */ diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 048f81e6b2..949004d650 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -192,7 +192,9 @@ int main(int argc, char *argv[]) // LINKS std::vector links; - if (!settings.linksListToGen.empty()) + if (settings.allLinks) + links = TSGenerator::getAllLinksToGen(study->areas); + else if (!settings.linksListToGen.empty()) links = getLinksToGen(study->areas, settings.linksListToGen); for (auto& l : links) From e1682e637823b288517ed769613b4af9ad46b077 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 2 Apr 2024 12:13:50 +0200 Subject: [PATCH 055/101] Use findlink, add enum linkDirection --- .../antares/solver/ts-generator/generator.h | 9 +++++++++ src/tools/ts-generator/main.cpp | 20 +++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index e7dcf946b3..d0db5ed9e2 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -57,6 +57,15 @@ class ThermalInterface const std::string& name; }; +enum class linkDirection +{ + direct, + indirect +}; + +typedef std::vector> listOfLinks; + + void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); /*! diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 949004d650..68d2988451 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -103,24 +103,18 @@ std::vector getLinksToGen(Data::AreaList& areas, std::vector links; const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); - for (const auto& [areaID, linkID] : ids) + for (const auto& [areaFromID, areaWithID] : ids) { - logs.info() << "Generating ts for area: " << areaID << " and cluster: " << linkID; + logs.info() << "Generating ts for area: " << areaFromID << " and cluster: " << areaWithID; - auto* area = areas.find(areaID); - if (!area) + auto* link = areas.findLink(areaFromID, areaWithID); + if (!link) { - logs.warning() << "Area not found: " << areaID; + logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; continue; } - - auto it = std::ranges::find_if(area->links, [&linkID](auto& l) - { return l.second->with->id == linkID;}); - - if (it != area->links.end()) - links.push_back(it->second); - else - logs.warning() << "Link not found: " << linkID; +// if (link.from->id == areaFromID) + links.push_back(link); } return links; From d3a61a8364a57cf6bda0f60ac7c62a9097f8dcd7 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 2 Apr 2024 14:01:04 +0200 Subject: [PATCH 056/101] Use direction in generator --- .../antares/solver/ts-generator/generator.h | 4 +-- src/solver/ts-generator/thermal.cpp | 26 +++++++++---------- src/tools/ts-generator/main.cpp | 14 +++++----- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index d0db5ed9e2..666facd3a8 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -80,14 +80,14 @@ bool generateThermalTimeSeries(Data::Study& study, const std::string& savePath); bool generateLinkTimeSeries(Data::Study& study, - std::vector links, + listOfLinks links, Solver::IResultWriter& writer, const std::string& savePath); std::vector getAllClustersToGen(Data::AreaList& areas, bool globalThermalTSgeneration); -std::vector getAllLinksToGen(Data::AreaList& areas); +listOfLinks getAllLinksToGen(Data::AreaList& areas); /*! ** \brief Destroy all TS Generators diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 0a44621d7f..2bc7b393c0 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -585,13 +585,14 @@ std::vector getAllClustersToGen(Data::AreaList& areas, return clusters; } -std::vector getAllLinksToGen(Data::AreaList& areas) +listOfLinks getAllLinksToGen(Data::AreaList& areas) { - std::vector links; + listOfLinks links; areas.each([&links](Data::Area& area) { std::ranges::for_each(area.links, [&links](auto& l) { - links.push_back(l.second); + links.emplace_back(l.second, linkDirection::direct); + links.emplace_back(l.second, linkDirection::indirect); }); }); @@ -675,7 +676,7 @@ bool generateThermalTimeSeries(Data::Study& study, } bool generateLinkTimeSeries(Data::Study& study, - std::vector links, + listOfLinks links, Solver::IResultWriter& writer, const std::string& savePath) { @@ -685,20 +686,19 @@ bool generateLinkTimeSeries(Data::Study& study, auto generator = std::make_unique (study, study.parameters.nbTimeSeriesLinks); - for (auto* link : links) + for (auto& [link, direction] : links) { Data::TimeSeries ts(link->timeseriesNumbers); ts.resize(study.parameters.nbTimeSeriesLinks, HOURS_PER_YEAR); - // direct capacity - ThermalInterface clusterInterfaceDirect(link->tsGenerationDirect, ts, link->with->name); - (*generator)(*link->from, clusterInterfaceDirect); - writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, true); + auto& tsGenStruct = direction == linkDirection::direct ? link->tsGenerationDirect : link->tsGenerationIndirect; + + ThermalInterface linkInterface(tsGenStruct, ts, link->with->name); + + (*generator)(*link->from, linkInterface); + + writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, direction == linkDirection::direct); - // indirect capacity - ThermalInterface clusterInterfaceIndirect(link->tsGenerationIndirect, ts, link->with->name); - (*generator)(*link->from, clusterInterfaceIndirect); - writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, false); } return true; diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 68d2988451..43c6c3cded 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -97,10 +97,10 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -std::vector getLinksToGen(Data::AreaList& areas, +TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& clustersToGen) { - std::vector links; + TSGenerator::listOfLinks links; const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); for (const auto& [areaFromID, areaWithID] : ids) @@ -113,8 +113,10 @@ std::vector getLinksToGen(Data::AreaList& areas, logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; continue; } -// if (link.from->id == areaFromID) - links.push_back(link); + auto direction = (link->from->id == areaFromID) ? TSGenerator::linkDirection::direct : + TSGenerator::linkDirection::indirect; + + links.emplace_back(link, direction); } return links; @@ -185,14 +187,14 @@ int main(int argc, char *argv[]) logs.debug() << c->id(); // LINKS - std::vector links; + TSGenerator::listOfLinks links; if (settings.allLinks) links = TSGenerator::getAllLinksToGen(study->areas); else if (!settings.linksListToGen.empty()) links = getLinksToGen(study->areas, settings.linksListToGen); for (auto& l : links) - logs.debug() << l->getName(); + logs.debug() << l.first->getName(); return !TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath) && !TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath); From 2df3e2859109426dfd5269739c0d2bc844f9f3d1 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 2 Apr 2024 15:10:02 +0200 Subject: [PATCH 057/101] Fixes --- src/tools/ts-generator/main.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 43c6c3cded..a52335b70d 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -75,7 +75,7 @@ std::vector getClustersToGen(Data::AreaList& areas, for (const auto& [areaID, clusterID] : ids) { - logs.info() << "Generating ts for area: " << areaID << " and cluster: " << clusterID; + logs.info() << "Searching for area: " << areaID << " and cluster: " << clusterID; auto* area = areas.find(areaID); if (!area) @@ -105,7 +105,7 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, for (const auto& [areaFromID, areaWithID] : ids) { - logs.info() << "Generating ts for area: " << areaFromID << " and cluster: " << areaWithID; + logs.info() << "Searching for link: " << areaFromID << "/" << areaWithID; auto* link = areas.findLink(areaFromID, areaWithID); if (!link) @@ -196,6 +196,8 @@ int main(int argc, char *argv[]) for (auto& l : links) logs.debug() << l.first->getName(); - return !TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath) - && !TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath); + bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath); + ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath) && ret; + + return !ret; // return 0 for success } From 9f6eb17985bfd4eefaca59ca0274ad51588c791a Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 2 Apr 2024 16:00:42 +0200 Subject: [PATCH 058/101] Default nbtslink --- src/libs/antares/study/include/antares/study/parameters.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index a8335881f6..c27af305eb 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -268,8 +268,8 @@ class Parameters final uint nbTimeSeriesThermal; //! Nb of timeSeries : Solar uint nbTimeSeriesSolar; - //! Nb of timeSeries : Solar - uint nbTimeSeriesLinks; + //! Nb of timeSeries : Links + uint nbTimeSeriesLinks = 1; //@} //! \name Time-series refresh From afb2b8dd527c9f313ccff1173a393acd4df9bf15 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 10:47:47 +0200 Subject: [PATCH 059/101] comments 1 --- src/libs/antares/study/include/antares/study/area/links.h | 1 - src/libs/antares/study/include/antares/study/parameters.h | 2 +- src/solver/ts-generator/thermal.cpp | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index 88c2639bc3..a2a1c12bdb 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -21,7 +21,6 @@ #ifndef __ANTARES_LIBS_STUDY_LINKS_H__ #define __ANTARES_LIBS_STUDY_LINKS_H__ -//#include #include #include #include diff --git a/src/libs/antares/study/include/antares/study/parameters.h b/src/libs/antares/study/include/antares/study/parameters.h index c27af305eb..3a994fc8a6 100644 --- a/src/libs/antares/study/include/antares/study/parameters.h +++ b/src/libs/antares/study/include/antares/study/parameters.h @@ -269,7 +269,7 @@ class Parameters final //! Nb of timeSeries : Solar uint nbTimeSeriesSolar; //! Nb of timeSeries : Links - uint nbTimeSeriesLinks = 1; + uint nbLinkTStoGenerate = 1; //@} //! \name Time-series refresh diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index ab103eba08..0ff241bafb 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -684,12 +684,12 @@ bool generateLinkTimeSeries(Data::Study& study, logs.info() << "Generating the links time-series"; auto generator = std::make_unique - (study, study.parameters.nbTimeSeriesLinks); + (study, study.parameters.nbLinkTStoGenerate); for (auto& [link, direction] : links) { Data::TimeSeries ts(link->timeseriesNumbers); - ts.resize(study.parameters.nbTimeSeriesLinks, HOURS_PER_YEAR); + ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); auto& tsGenStruct = direction == linkDirection::direct ? link->tsGenerationDirect : link->tsGenerationIndirect; From 683d2b9d8b472513f952967dfc6daca27758c28c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 11:11:59 +0200 Subject: [PATCH 060/101] use filesystem for separator --- src/tools/ts-generator/main.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index a52335b70d..c0665734a5 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -18,6 +18,7 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ +#include #include #include @@ -36,7 +37,7 @@ using namespace Antares; -struct TsGeneratorSettings +struct Settings { std::string studyFolder; @@ -51,7 +52,7 @@ struct TsGeneratorSettings std::string linksListToGen = ""; }; -std::unique_ptr createTsGeneratorParser(TsGeneratorSettings& settings) +std::unique_ptr createTsGeneratorParser(Settings& settings) { auto parser = std::make_unique(); parser->addParagraph("Antares Time Series generator\n"); @@ -124,7 +125,7 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, int main(int argc, char *argv[]) { - TsGeneratorSettings settings; + Settings settings; auto parser = createTsGeneratorParser(settings); switch (auto ret = parser->operator()(argc, argv); ret) @@ -171,10 +172,8 @@ int main(int argc, char *argv[]) auto resultWriter = Solver::resultWriterFactory( Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); -#define SEP Yuni::IO::Separator - const std::string thermalSavePath = std::string("ts-generator") + SEP + "thermal"; - const std::string linksSavePath = std::string("ts-generator") + SEP + "links"; -#undef SEP + const std::string thermalSavePath = std::string("ts-generator") + std::filesystem::path::preferred_separator + "thermal"; + const std::string linksSavePath = std::string("ts-generator") + std::filesystem::path::preferred_separator + "links"; // THERMAL std::vector clusters; From 0d597e4f2470421bdaf74c9e7f06aedb7bf37297 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 11:20:23 +0200 Subject: [PATCH 061/101] remove dynamic alloc of generatorTempData --- src/solver/ts-generator/thermal.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 0ff241bafb..88b6fc782d 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -657,8 +657,7 @@ bool generateThermalTimeSeries(Data::Study& study, bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); - auto generator = std::make_unique - (study, study.parameters.nbTimeSeriesThermal); + auto generator = GeneratorTempData(study, study.parameters.nbTimeSeriesThermal); // TODO VP: parallel for (auto* cluster : clusters) @@ -683,8 +682,7 @@ bool generateLinkTimeSeries(Data::Study& study, logs.info(); logs.info() << "Generating the links time-series"; - auto generator = std::make_unique - (study, study.parameters.nbLinkTStoGenerate); + auto generator = GeneratorTempData(study, study.parameters.nbLinkTStoGenerate); for (auto& [link, direction] : links) { @@ -695,10 +693,9 @@ bool generateLinkTimeSeries(Data::Study& study, ThermalInterface linkInterface(tsGenStruct, ts, link->with->name); - (*generator)(*link->from, linkInterface); + generator(*link->from, linkInterface); writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, direction == linkDirection::direct); - } return true; From c7ffac3cda3fe7aead3da6b363a2322465a2271a Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 11:25:04 +0200 Subject: [PATCH 062/101] use a function instead of operator() to generate TS --- src/solver/ts-generator/thermal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 88b6fc782d..4576b5e9c6 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -74,7 +74,7 @@ class GeneratorTempData final public: explicit GeneratorTempData(Data::Study&, unsigned); - void operator()(const Data::Area& area, ThermalInterface& cluster); + void generateTS(const Data::Area& area, ThermalInterface& cluster); public: Data::Study& study; @@ -209,7 +209,7 @@ int GeneratorTempData::durationGenerator(Data::ThermalLaw law, return 0; } -void GeneratorTempData::operator()(const Data::Area& area, ThermalInterface& cluster) +void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& cluster) { if (not cluster.prepro) { @@ -663,7 +663,7 @@ bool generateThermalTimeSeries(Data::Study& study, for (auto* cluster : clusters) { ThermalInterface clusterInterface(cluster); - (*generator)(*cluster->parentArea, clusterInterface); + generator.generateTS(*cluster->parentArea, clusterInterface); if (archive) writeThermalResultsToDisk(study, writer, *cluster->parentArea, *cluster, savePath); @@ -693,7 +693,7 @@ bool generateLinkTimeSeries(Data::Study& study, ThermalInterface linkInterface(tsGenStruct, ts, link->with->name); - generator(*link->from, linkInterface); + generator.generateTS(*link->from, linkInterface); writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, direction == linkDirection::direct); } From 3e54378ed58789fe3baf12c5f98098590f166aa8 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 11:31:51 +0200 Subject: [PATCH 063/101] remove yuni string for saving --- src/solver/ts-generator/thermal.cpp | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 4576b5e9c6..660d0b8899 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -115,8 +115,6 @@ class GeneratorTempData final std::vector> FPOW; std::vector> PPOW; - - Yuni::String pTempFilename; }; GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : @@ -608,17 +606,12 @@ void writeThermalResultsToDisk(const Data::Study& study, if (study.parameters.noOutput) return; - Yuni::String pTempFilename; - pTempFilename.reserve(study.folderOutput.size() + 256); - - pTempFilename.clear() << savePath << SEP << area.id << SEP << cluster.id() << ".txt"; + std::string filePath = savePath + SEP + area.id + SEP + cluster.id() + ".txt"; enum { precision = 0 }; - std::string buffer; cluster.series.timeSeries.saveToBuffer(buffer, precision); - - writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); + writer.addEntryFromBuffer(filePath, buffer); } void writeLinksResultsToDisk(const Data::Study& study, @@ -631,20 +624,15 @@ void writeLinksResultsToDisk(const Data::Study& study, if (study.parameters.noOutput) return; - enum { precision = 0 }; - std::string buffer; - std::string capacityType = direct ? "_direct" : "_indirect"; - Yuni::String pTempFilename; - pTempFilename.reserve(study.folderOutput.size() + 256); - - pTempFilename.clear() << savePath << SEP << link.from->id << SEP << - link.with->id << capacityType << ".txt"; + std::string filePath = savePath + SEP + link.from->id + SEP + link.with->id.c_str() + + capacityType + ".txt"; + enum { precision = 0 }; + std::string buffer; series.saveToBuffer(buffer, precision); - - writer.addEntryFromBuffer(pTempFilename.c_str(), buffer); + writer.addEntryFromBuffer(filePath, buffer); } bool generateThermalTimeSeries(Data::Study& study, From fbe3554a63571691d60b65827cceafada4617ba6 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 11:40:20 +0200 Subject: [PATCH 064/101] Move some members to generation function --- src/solver/ts-generator/thermal.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 660d0b8899..154ecf908f 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -96,13 +96,10 @@ class GeneratorTempData final MersenneTwister& rndgenerator; - double AVP[366]; enum { Log_size = 4000 }; - int LOG[Log_size]; - int LOGP[Log_size]; double lf[366]; double lp[366]; @@ -113,8 +110,6 @@ class GeneratorTempData final double bf[366]; double bp[366]; - std::vector> FPOW; - std::vector> PPOW; }; GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : @@ -125,9 +120,6 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGe nbThermalTimeseries_ = nbOfSeriesToGen; derated = parameters.derated; - - FPOW.resize(DAYS_PER_YEAR); - PPOW.resize(DAYS_PER_YEAR); } template @@ -247,6 +239,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu auto p_law = cluster.plannedLaw; + std::vector> FPOW(DAYS_PER_YEAR); + std::vector> PPOW(DAYS_PER_YEAR); + int FODOfTheDay; int PODOfTheDay; @@ -295,9 +290,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu prepareIndispoFromLaw(f_law, f_volatility, af, bf, FOD); prepareIndispoFromLaw(p_law, p_volatility, ap, bp, POD); - (void)::memset(AVP, 0, sizeof(AVP)); - (void)::memset(LOG, 0, sizeof(LOG)); - (void)::memset(LOGP, 0, sizeof(LOGP)); + std::array AVP {}; + std::array LOG {}; + std::array LOGP {}; int MXO = 0; From cc4a8ba7f6ea0316d4b7fc3b508063dc054120ec Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 14:11:17 +0200 Subject: [PATCH 065/101] Move some members to generation function 2 --- src/solver/ts-generator/thermal.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 154ecf908f..5fe79dd208 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -87,8 +87,8 @@ class GeneratorTempData final template void prepareIndispoFromLaw(Data::ThermalLaw law, double volatility, - double A[], - double B[], + std::array A, + std::array B, const T& duration); private: @@ -101,14 +101,6 @@ class GeneratorTempData final Log_size = 4000 }; - double lf[366]; - double lp[366]; - double ff[366]; - double pp[366]; - double af[366]; - double ap[366]; - double bf[366]; - double bp[366]; }; @@ -125,8 +117,8 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGe template void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, double volatility, - double A[], - double B[], + std::array A, + std::array B, const T& duration) { switch (law) @@ -242,6 +234,15 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu std::vector> FPOW(DAYS_PER_YEAR); std::vector> PPOW(DAYS_PER_YEAR); + std::array lf {}; + std::array lp {}; + std::array ff {}; + std::array pp {}; + std::array af {}; + std::array ap {}; + std::array bf {}; + std::array bp {}; + int FODOfTheDay; int PODOfTheDay; From 9d986234cb0db1e84999113056fde7c7e0d7f18c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 14:27:36 +0200 Subject: [PATCH 066/101] Use path instead of string --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index c0665734a5..eb9205516f 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -172,8 +172,8 @@ int main(int argc, char *argv[]) auto resultWriter = Solver::resultWriterFactory( Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); - const std::string thermalSavePath = std::string("ts-generator") + std::filesystem::path::preferred_separator + "thermal"; - const std::string linksSavePath = std::string("ts-generator") + std::filesystem::path::preferred_separator + "links"; + const auto thermalSavePath = std::filesystem::path("ts-generator") / "thermal"; + const auto linksSavePath = std::filesystem::path("ts-generator") / "links"; // THERMAL std::vector clusters; From 8a2d4a022bf47ced005f2b42b475793ce8d7f9b7 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 14:55:07 +0200 Subject: [PATCH 067/101] One write function --- src/solver/ts-generator/thermal.cpp | 46 +++++++++-------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 5fe79dd208..d4d5d21fb9 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -593,42 +593,17 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) return links; } -void writeThermalResultsToDisk(const Data::Study& study, +void writeResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, - const Data::Area& area, - const Data::ThermalCluster& cluster, + Matrix<>& series, const std::string& savePath) { if (study.parameters.noOutput) return; - std::string filePath = savePath + SEP + area.id + SEP + cluster.id() + ".txt"; - - enum { precision = 0 }; std::string buffer; - cluster.series.timeSeries.saveToBuffer(buffer, precision); - writer.addEntryFromBuffer(filePath, buffer); -} - -void writeLinksResultsToDisk(const Data::Study& study, - Solver::IResultWriter& writer, - const Data::AreaLink& link, - Matrix<>& series, - const std::string& savePath, - bool direct) -{ - if (study.parameters.noOutput) - return; - - std::string capacityType = direct ? "_direct" : "_indirect"; - - std::string filePath = savePath + SEP + link.from->id + SEP + link.with->id.c_str() - + capacityType + ".txt"; - - enum { precision = 0 }; - std::string buffer; - series.saveToBuffer(buffer, precision); - writer.addEntryFromBuffer(filePath, buffer); + series.saveToBuffer(buffer, 0); + writer.addEntryFromBuffer(savePath, buffer); } bool generateThermalTimeSeries(Data::Study& study, @@ -649,8 +624,11 @@ bool generateThermalTimeSeries(Data::Study& study, ThermalInterface clusterInterface(cluster); generator.generateTS(*cluster->parentArea, clusterInterface); - if (archive) - writeThermalResultsToDisk(study, writer, *cluster->parentArea, *cluster, savePath); + if (archive) // compatibilty with in memory + { + std::string filePath = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; + writeResultsToDisk(study, writer, cluster->series.timeSeries, filePath); + } cluster->calculationOfSpinning(); } @@ -679,7 +657,11 @@ bool generateLinkTimeSeries(Data::Study& study, generator.generateTS(*link->from, linkInterface); - writeLinksResultsToDisk(study, writer, *link, ts.timeSeries, savePath, direction == linkDirection::direct); + std::string capacityType = direction == linkDirection::direct ? "_direct" : "_indirect"; + std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + capacityType + ".txt"; + + writeResultsToDisk(study, writer, ts.timeSeries, filePath); } return true; From fdb7d60a79d9ddd435b2f147b2fa7e0626de67cd Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 15:23:41 +0200 Subject: [PATCH 068/101] archive condition --- src/solver/ts-generator/thermal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index d4d5d21fb9..bb4df1e310 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -614,7 +614,7 @@ bool generateThermalTimeSeries(Data::Study& study, logs.info(); logs.info() << "Generating the thermal time-series"; - bool archive = (0 != (study.parameters.timeSeriesToArchive & Data::timeSeriesThermal)); + bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; auto generator = GeneratorTempData(study, study.parameters.nbTimeSeriesThermal); From 98b1a0837eee5d5702cede73f63fab6e221cdbe6 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 15:26:31 +0200 Subject: [PATCH 069/101] Revert "Move some members to generation function 2" This reverts commit cc4a8ba7f6ea0316d4b7fc3b508063dc054120ec. --- src/solver/ts-generator/thermal.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index bb4df1e310..e421bdf5be 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -87,8 +87,8 @@ class GeneratorTempData final template void prepareIndispoFromLaw(Data::ThermalLaw law, double volatility, - std::array A, - std::array B, + double A[], + double B[], const T& duration); private: @@ -101,6 +101,14 @@ class GeneratorTempData final Log_size = 4000 }; + double lf[366]; + double lp[366]; + double ff[366]; + double pp[366]; + double af[366]; + double ap[366]; + double bf[366]; + double bp[366]; }; @@ -117,8 +125,8 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGe template void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, double volatility, - std::array A, - std::array B, + double A[], + double B[], const T& duration) { switch (law) @@ -234,15 +242,6 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu std::vector> FPOW(DAYS_PER_YEAR); std::vector> PPOW(DAYS_PER_YEAR); - std::array lf {}; - std::array lp {}; - std::array ff {}; - std::array pp {}; - std::array af {}; - std::array ap {}; - std::array bf {}; - std::array bp {}; - int FODOfTheDay; int PODOfTheDay; From 9d9261ccc604080b7bf9c740c5b0e002304537fa Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 15:53:57 +0200 Subject: [PATCH 070/101] use string method to ceonvert path --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index eb9205516f..2311d79909 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -195,8 +195,8 @@ int main(int argc, char *argv[]) for (auto& l : links) logs.debug() << l.first->getName(); - bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath); - ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath) && ret; + bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath.string()); + ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath.string()) && ret; return !ret; // return 0 for success } From 3bc979cf435490a3bc29848784ceebf9445e4983 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 3 Apr 2024 17:18:45 +0200 Subject: [PATCH 071/101] code semlls --- .../antares/solver/ts-generator/generator.h | 2 +- src/solver/ts-generator/thermal.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 666facd3a8..9fca4986e5 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -80,7 +80,7 @@ bool generateThermalTimeSeries(Data::Study& study, const std::string& savePath); bool generateLinkTimeSeries(Data::Study& study, - listOfLinks links, + listOfLinks& links, Solver::IResultWriter& writer, const std::string& savePath); diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index e421bdf5be..309d707ff8 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -92,7 +92,7 @@ class GeneratorTempData final const T& duration); private: - uint nbThermalTimeseries_; + uint nbOfSeriesToGen_; MersenneTwister& rndgenerator; @@ -113,12 +113,12 @@ class GeneratorTempData final }; GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : - study(study), rndgenerator(study.runtime->random[Data::seedTsGenThermal]) + study(study), + nbOfSeriesToGen_(nbOfSeriesToGen), + rndgenerator(study.runtime->random[Data::seedTsGenThermal]) { auto& parameters = study.parameters; - nbThermalTimeseries_ = nbOfSeriesToGen; - derated = parameters.derated; } @@ -315,7 +315,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu auto& modulation = cluster.modulationCapacity; double* dstSeries = nullptr; - const uint tsCount = nbThermalTimeseries_ + 2; + const uint tsCount = nbOfSeriesToGen_ + 2; for (uint tsIndex = 0; tsIndex != tsCount; ++tsIndex) { uint hour = 0; @@ -570,7 +570,7 @@ std::vector getAllClustersToGen(Data::AreaList& areas, std::vector clusters; areas.each([&clusters, &globalThermalTSgeneration](Data::Area& area) { - for (auto& cluster : area.thermal.list.all()) + for (const auto& cluster : area.thermal.list.all()) if (cluster->doWeGenerateTS(globalThermalTSgeneration)) clusters.push_back(cluster.get()); }); @@ -594,7 +594,7 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) void writeResultsToDisk(const Data::Study& study, Solver::IResultWriter& writer, - Matrix<>& series, + const Matrix<>& series, const std::string& savePath) { if (study.parameters.noOutput) @@ -636,7 +636,7 @@ bool generateThermalTimeSeries(Data::Study& study, } bool generateLinkTimeSeries(Data::Study& study, - listOfLinks links, + listOfLinks& links, Solver::IResultWriter& writer, const std::string& savePath) { @@ -645,7 +645,7 @@ bool generateLinkTimeSeries(Data::Study& study, auto generator = GeneratorTempData(study, study.parameters.nbLinkTStoGenerate); - for (auto& [link, direction] : links) + for (const auto& [link, direction] : links) { Data::TimeSeries ts(link->timeseriesNumbers); ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); From 61ddedbe741667ba932cbb6ff4c85b57588399a6 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 4 Apr 2024 10:21:36 +0200 Subject: [PATCH 072/101] code smells 2 --- .../antares/solver/ts-generator/generator.h | 4 +-- .../antares/solver/ts-generator/prepro.h | 10 +++---- src/solver/ts-generator/prepro.cpp | 26 +++++++------------ src/solver/ts-generator/thermal.cpp | 2 +- 4 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 9fca4986e5..11dce8b3a3 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -63,7 +63,7 @@ enum class linkDirection indirect }; -typedef std::vector> listOfLinks; +using listOfLinks = std::vector>; void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); @@ -80,7 +80,7 @@ bool generateThermalTimeSeries(Data::Study& study, const std::string& savePath); bool generateLinkTimeSeries(Data::Study& study, - listOfLinks& links, + const listOfLinks& links, Solver::IResultWriter& writer, const std::string& savePath); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index 6b373199bf..d7d91c4f67 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -26,9 +26,7 @@ #include #include -namespace Antares -{ -namespace Data +namespace Antares::Data { /*! ** \brief Thermal @@ -54,7 +52,6 @@ class PreproThermal thermalPreproMax, }; -public: //! \name Constructor //@{ /*! @@ -89,7 +86,7 @@ class PreproThermal ** \param folder The targer folder ** \return A non-zero value if the operation succeeded, 0 otherwise */ - bool saveToFolder(const AnyString& folder); + bool saveToFolder(const AnyString& folder) const; /*! ** \brief Get the amount of memory used by the class @@ -110,8 +107,7 @@ class PreproThermal std::weak_ptr itsThermalCluster; }; // class PreproThermal -} // namespace Data -} // namespace Antares +} // namespace Antares::Data #include "prepro.hxx" diff --git a/src/solver/ts-generator/prepro.cpp b/src/solver/ts-generator/prepro.cpp index 36659e1439..ba9a63f18f 100644 --- a/src/solver/ts-generator/prepro.cpp +++ b/src/solver/ts-generator/prepro.cpp @@ -31,9 +31,7 @@ using namespace Yuni; #define SEP IO::Separator -namespace Antares -{ -namespace Data +namespace Antares::Data { PreproThermal::PreproThermal(std::weak_ptr cluster) : itsThermalCluster(cluster) @@ -47,7 +45,7 @@ void PreproThermal::copyFrom(const PreproThermal& rhs) rhs.data.unloadFromMemory(); } -bool PreproThermal::saveToFolder(const AnyString& folder) +bool PreproThermal::saveToFolder(const AnyString& folder) const { if (IO::Directory::Create(folder)) { @@ -74,7 +72,7 @@ bool PreproThermal::loadFromFolder(Study& study, const AnyString& folder) // standard loading ret = data.loadFromCSVFile( buffer, thermalPreproMax, DAYS_PER_YEAR, Matrix<>::optFixedSize, &study.dataBuffer) - and ret; + && ret; bool thermalTSglobalGeneration = study.parameters.isTSGeneratedByPrepro(timeSeriesThermal); if (study.usedByTheSolver && cluster->doWeGenerateTS(thermalTSglobalGeneration)) @@ -116,27 +114,27 @@ bool PreproThermal::loadFromFolder(Study& study, const AnyString& folder) ++errors; } - if (foRate < 0. or foRate > 1.) + if (foRate < 0. || foRate > 1.) { logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() << ": invalid value for FO rate (line:" << (i + 1) << ")"; ++errors; } - if (poRate < 0. or poRate > 1.) + if (poRate < 0. || poRate > 1.) { logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() << ": invalid value for PO rate (line:" << (i + 1) << ")"; ++errors; } - if (foDuration < 1. or foDuration > 365.) + if (foDuration < 1. || foDuration > 365.) { logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() << ": invalid value for FO Duration (line:" << (i + 1) << ")"; ++errors; } - if (poDuration < 1. or poDuration > 365.) + if (poDuration < 1. || poDuration > 365.) { logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() << ": invalid value for PO Duration (line:" << (i + 1) << ")"; @@ -191,11 +189,8 @@ bool PreproThermal::normalizeAndCheckNPO() auto& columnNPOMax = data[npoMax]; auto& columnNPOMin = data[npoMin]; // errors management - uint errors = 0; - enum - { - maxErrors = 10 - }; + uint errors = 0, maxErrors = 10; + // Flag to determine whether the column NPO max has been normalized or not bool normalized = false; @@ -231,5 +226,4 @@ bool PreproThermal::normalizeAndCheckNPO() return (0 == errors); } -} // namespace Data -} // namespace Antares +} // namespace Antares::Data diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index 309d707ff8..3b16622c02 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -636,7 +636,7 @@ bool generateThermalTimeSeries(Data::Study& study, } bool generateLinkTimeSeries(Data::Study& study, - listOfLinks& links, + const listOfLinks& links, Solver::IResultWriter& writer, const std::string& savePath) { From 4e0732f6b04e60cc1666e3647a620d551433d2d0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 4 Apr 2024 17:21:11 +0200 Subject: [PATCH 073/101] Fix description --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 2311d79909..d55edbf87c 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -61,7 +61,7 @@ std::unique_ptr createTsGeneratorParser(Settings& settings parser->addFlag(settings.thermalListToGen, ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); - parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of area IDs and links name, usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); + parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of 2 area IDs, usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); parser->remainingArguments(settings.studyFolder); @@ -158,7 +158,7 @@ int main(int argc, char *argv[]) } study->initializeRuntimeInfos(); - // Force the writing of generated TS into output/YYYYMMDD-HHSSeco/ts-generator/thermal/mc-0 + // Force the writing of generated TS into output/YYYYMMDD-HHSSeco/ts-generator/thermal study->parameters.timeSeriesToArchive |= Antares::Data::timeSeriesThermal; try { From 6b7414d2b254d369174c8a77c1bfefd80e2e2879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= <26088210+flomnes@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:12:06 +0200 Subject: [PATCH 074/101] Add I/O for links' TS generation (#2019) Add read for - "modulation" timeseries => `input/links//prepro/_{direct, indirect}.txt` - "prepro" timeseries => `input/links//prepro/_mod_{direct, indirect}.txt` - link parameters => `tsgen_direct_XXX`, `tsgen_indirect_XXX`, with XXX = unitcount, nominalcapacity, etc. - number of TS to generate => `generaldata.ini/General/nbtimeserieslinks` Add `bool` argument to optionally load time-series. This bool is `false` (default value) in `antares-solver`, and `true` in `antares-ts-generator`. Parameters are loaded in any case. De-couple `PreproThermal` and `ThermalCluster` (remove the dependency of the 1st to the 2nd). --------- Co-authored-by: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Co-authored-by: Vincent Payet --- docs/CHANGELOG.md | 4 + docs/reference-guide/13-file-format.md | 51 +++ simtest.json | 2 +- src/libs/antares/study/CMakeLists.txt | 2 - src/libs/antares/study/area/links.cpp | 136 +++++- src/libs/antares/study/area/list.cpp | 18 +- .../antares/study/cleaner/cleaner-v20.cpp | 3 +- .../study/include/antares/study/area/area.h | 10 +- .../study/include/antares/study/area/links.h | 25 +- .../include/antares/study/load-options.h | 4 + .../STStorageOutputCaptions.h | 29 -- .../parts/short-term-storage/properties.h | 20 +- .../antares/study/parts/thermal/cluster.h | 6 +- .../antares/study/parts/thermal/cluster.hxx | 14 +- .../antares/study/parts/thermal/defines.h | 2 +- src/libs/antares/study/parameters.cpp | 29 ++ .../STStorageOutputCaptions.cpp | 54 --- .../parts/short-term-storage/properties.cpp | 54 +-- .../antares/study/parts/thermal/cluster.cpp | 14 +- .../study/parts/thermal/cluster_list.cpp | 18 +- src/solver/ts-generator/CMakeLists.txt | 2 +- .../{thermal.cpp => availability.cpp} | 176 ++++---- .../antares/solver/ts-generator/generator.h | 19 +- .../include/antares/solver/ts-generator/law.h | 6 +- .../antares/solver/ts-generator/prepro.h | 36 +- .../antares/solver/ts-generator/prepro.hxx | 4 +- src/solver/ts-generator/prepro.cpp | 188 ++++---- src/solver/variable/CMakeLists.txt | 2 +- .../antares/solver/variable/adequacy/all.h | 10 +- .../solver/variable/economy/STSbyGroup.h | 420 ++++++++++++++++++ .../antares/solver/variable/economy/all.h | 21 +- .../variable/economy/shortTermStorage.h | 293 ------------ .../end-to-end/simple_study/simple-study.cpp | 7 +- src/tests/end-to-end/utils/utils.cpp | 9 +- src/tests/end-to-end/utils/utils.h | 2 +- src/tools/ts-generator/main.cpp | 1 + .../datagrid/renderer/area/thermalprepro.cpp | 28 +- .../datagrid/renderer/area/thermalprepro.h | 2 +- .../datagrid/renderer/connection.cpp | 3 + .../windows/inspector/accumulator.hxx | 4 +- .../simulator/windows/inspector/constants.cpp | 4 +- .../simulator/windows/inspector/constants.h | 4 +- src/ui/simulator/windows/inspector/frame.cpp | 4 +- .../windows/inspector/property.update.cpp | 12 +- 44 files changed, 963 insertions(+), 789 deletions(-) delete mode 100644 src/libs/antares/study/include/antares/study/parts/short-term-storage/STStorageOutputCaptions.h delete mode 100644 src/libs/antares/study/parts/short-term-storage/STStorageOutputCaptions.cpp rename src/solver/ts-generator/{thermal.cpp => availability.cpp} (79%) create mode 100644 src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h delete mode 100644 src/solver/variable/include/antares/solver/variable/economy/shortTermStorage.h diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 29ea80e3c6..780f4a17f8 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,9 @@ Antares Changelog ================= +Next version +-------------------- +## Improvements +* STS groups are now "dynamic" : group names are no longer fixed by code, user is free to define these groups. 9.0.0 -------------------- diff --git a/docs/reference-guide/13-file-format.md b/docs/reference-guide/13-file-format.md index 832639abca..e0c39c0ed5 100644 --- a/docs/reference-guide/13-file-format.md +++ b/docs/reference-guide/13-file-format.md @@ -1,6 +1,25 @@ # Study format changes This is a list of all recent changes that came with new Antares Simulator features. The main goal of this document is to lower the costs of changing existing interfaces, both GUI and scripts. ## v9.1.0 +### (TS-generator only) TS generation for links +In files input/links//properties.ini, add the following properties +- tsgen_direct_XXX, +- tsgen_indirect_XXX +with XXX in +- unitcount (unsigned int, default 1) +- nominalcapacity (float) +- law.planned (string "uniform"/"geometric") +- law.forced (same) +- volatility.planned (double in [0,1]) +- volatility.forced (same) + +- "prepro" timeseries => input/links//prepro/_{direct, indirect}.txt, 365x6 values, respectively "forced outage duration", "planned outage duration", "forced outage rate", "planned outage rate", "minimum of groups in maintenance", "maximum of groups in maintenance". +- "modulation" timeseries => input/links//prepro/_mod_{direct, indirect}.txt, 8760x1 values each in [0, 1] +- number of TS to generate => generaldata.ini/General/nbtimeserieslinks (unsigned int, default value 1) + +Add bool argument to optionally load time-series. This bool is false (default value) in antares-solver, and true in antares-ts-generator. Parameters are loaded in any case.- + + ### (Input) Hydro Maximum Generation/Pumping Power * For time series ![Migration diagram](migration.png "Migration diagram"), for more details, see [this Python script](migration.py) * In the existing file **settings/scenariobuilder.dat**, under **<ruleset>** section following properties added: **hgp,<area>,<year> = <hgp-value>** @@ -14,6 +33,38 @@ This implies that, inside one of the previous categories, the number of availabl * [Logic changes](17-v91.md) +### Short term storage groups +STS groups in input are now "dynamic" : group names are no longer fixed by code, user is free to define these groups. + +In the "thematic trimming" section, the new dynamic variable `STS by group` is now used to enable/disable all variables (level/injection/withdrawal) for all groups. The following variables are obsolete and must not be provided + +``` +PSP_open_injection +PSP_open_withdrawal +PSP_open_level +... + +Other1_injection +Other1_withdral +Other1_level +... +Other5_injection +Other5_withdral +Other5_level +``` +(3*9=27 variables in total) + +The default value for group is "OTHER1". + +## Output +### Hydro maximum generation/pumping power +In existing directory `ts-numbers`, add sub-directory `hgp` containing TS numbers for hydro max pumping/generation, for each area. + +### ST Storage +- Output columns for ST storage are capitalized. For any STS group name my_group, 3 output columns are created : `MY_GROUP_INJECTION`, `MY_GROUP_WITHDRAWAL`, `MY_GROUP_LEVEL`. +- If a group is empty, no column is produced. +- There is now a variable number of columns in files values-XXX.txt, depending on the groups of ST storages provided by the user. Note that groups are case-insensitive, for example `battery`, `Battery` and `BATTERY` all represent the same group. If no ST storage exist for a given area, no variables associated to ST storages will be produced. + ## v9.0.0 ### Input ### Study version diff --git a/simtest.json b/simtest.json index 0dac6b89cd..0fa973328a 100644 --- a/simtest.json +++ b/simtest.json @@ -1,3 +1,3 @@ { - "version": "v9.1.0b" + "version": "v9.1.0-rc3" } diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 6c9340c11b..917b428c5f 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -102,8 +102,6 @@ set(SRC_STUDY_PART_SHORT_TERM_STORAGE include/antares/study/parts/short-term-storage/series.h include/antares/study/parts/short-term-storage/cluster.h parts/short-term-storage/cluster.cpp - include/antares/study/parts/short-term-storage/STStorageOutputCaptions.h - parts/short-term-storage/STStorageOutputCaptions.cpp ) source_group("study\\part\\short-term-storage" FILES ${SRC_STUDY_PART_SHORT_TERM_SOTRAGE}) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 31828b9975..8954a36f5d 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -21,10 +21,12 @@ #include #include +#include #include "antares/study//study.h" #include "antares/utils/utils.h" #include "antares/study/area/links.h" #include "antares/study/area/area.h" +#include #include #include @@ -135,6 +137,67 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol return success; } +// This function is "lazy", it only loads files if they exist +// and set a `valid` flag +bool AreaLink::loadTSGenTimeSeries(const AnyString& folder) +{ + const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); + tsGenerationDirect.prepro + = std::make_unique(id_direct, tsGenerationDirect.unitCount); + + const std::string id_indirect = std::string(with->id) + "/" + std::string(from->id); + tsGenerationIndirect.prepro + = std::make_unique(id_indirect, tsGenerationIndirect.unitCount); + + String preproFolder; + preproFolder << folder << SEP << "prepro"; + + // Prepro + String filename; + filename.clear() << preproFolder << SEP << with->id << "_direct.txt"; + bool anyFileWasLoaded = false; + if (std::filesystem::exists(filename.to())) + { + anyFileWasLoaded = true; + tsGenerationDirect.valid + = tsGenerationDirect.prepro->data.loadFromCSVFile( + filename, Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) + && tsGenerationDirect.prepro->validate(); + } + + filename.clear() << preproFolder << SEP << with->id << "_indirect.txt"; + if (std::filesystem::exists(filename.to())) + { + anyFileWasLoaded = true; + tsGenerationIndirect.valid + = tsGenerationIndirect.prepro->data.loadFromCSVFile( + filename, Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) + && tsGenerationIndirect.prepro->validate(); + } + + // Modulation + filename.clear() << preproFolder << SEP << with->id << "_mod_direct.txt"; + if (std::filesystem::exists(filename.to())) + { + anyFileWasLoaded = true; + tsGenerationDirect.valid + &= tsGenerationDirect.modulationCapacity.loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + } + + filename.clear() << preproFolder << SEP << with->id << "_mod_indirect.txt"; + if (std::filesystem::exists(filename.to())) + { + anyFileWasLoaded = true; + tsGenerationIndirect.valid + &= tsGenerationIndirect.modulationCapacity.loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + } + if (anyFileWasLoaded) + { + return tsGenerationDirect.valid && tsGenerationIndirect.valid; + } + return true; +} + bool AreaLink::isLinkPhysical() const { // All link types are physical, except arVirt @@ -170,9 +233,9 @@ void AreaLink::overrideTransmissionCapacityAccordingToGlobalParameter( } } -bool AreaLink::loadTimeSeries(const Study& study, const AnyString& folder) +bool AreaLink::loadTimeSeries(const StudyVersion& version, const AnyString& folder) { - if (study.header.version < StudyVersion(8, 2)) + if (version < StudyVersion(8, 2)) return linkLoadTimeSeries_for_version_below_810(folder); else return linkLoadTimeSeries_for_version_820_and_later(folder); @@ -295,7 +358,7 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning) namespace // anonymous { -bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) +bool handleKey(Data::AreaLink& link, const String& key, const String& value) { if (key == "hurdles-cost") return value.to(link.useHurdlesCost); @@ -406,10 +469,56 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const link.filterYearByYear = stringIntoDatePrecision(value); return true; } + return false; +} + +bool handleTSGenKey_internal(const std::string& key, + const String& value, + const std::string& prefix, + Data::LinkTsGeneration& out) +{ + const auto checkPrefixed = [&prefix, &key](const std::string& s) { + auto key_lowercase(key); + boost::to_lower(key_lowercase); + return key_lowercase == prefix + "_" + s; + }; + + if (checkPrefixed("unitcount")) + return value.to(out.unitCount); + + if (checkPrefixed("nominalcapacity")) + return value.to(out.nominalCapacity); + + if (checkPrefixed("law.planned")) + return value.to(out.plannedLaw); + + if (checkPrefixed("law.forced")) + return value.to(out.forcedLaw); + + if (checkPrefixed("volatility.planned")) + return value.to(out.plannedVolatility); + if (checkPrefixed("volatility.forced")) + return value.to(out.forcedVolatility); + + return false; +} + +bool handleTSGenKey(Data::AreaLink& link, const std::string& key, const String& value) +{ + if (key.starts_with("tsgen_direct")) + return handleTSGenKey_internal(key, value, "tsgen_direct", link.tsGenerationDirect); + else if (key.starts_with("tsgen_indirect")) + return handleTSGenKey_internal(key, value, "tsgen_indirect", link.tsGenerationIndirect); return false; } +bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) +{ + return handleKey(link, key, value) || handleTSGenKey(link, key, value); +} + +[[ noreturn ]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) { logs.error() << "Link (" << link.from->name << "/" << link.with->name << "): Invalid values (" @@ -417,9 +526,8 @@ void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) throw Antares::Error::ReadingStudy(); } -void logLinkDataCheckErrorDirectIndirect(const AreaLink& link, - uint direct, - uint indirect) +[[ noreturn ]] +void logLinkDataCheckErrorDirectIndirect(const AreaLink& link, uint direct, uint indirect) { logs.error() << "Link (" << link.from->name << "/" << link.with->name << "): Found " << direct << " direct TS " @@ -428,7 +536,11 @@ void logLinkDataCheckErrorDirectIndirect(const AreaLink& link, } } // anonymous namespace -bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const AnyString& folder) +bool AreaLinksLoadFromFolder(const Study& study, + AreaList* l, + Area* area, + const AnyString& folder, + bool loadTSGen) { // Assert assert(area); @@ -471,7 +583,7 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const AnyStr link.comments.clear(); link.displayComments = true; - ret = link.loadTimeSeries(study, folder) && ret; + ret = link.loadTimeSeries(study.header.version, folder) && ret; // Checks on loaded link's data if (study.usedByTheSolver) @@ -531,9 +643,8 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const AnyStr { if (directHurdlesCost[h] + indirectHurdlesCost[h] < 0) { - logLinkDataCheckError(link, - "hurdle costs direct + hurdle cost indirect < 0", - h); + logLinkDataCheckError( + link, "hurdle costs direct + hurdle cost indirect < 0", h); return false; } } @@ -560,6 +671,9 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const AnyStr logs.warning() << '`' << p->key << "`: Unknown property"; } + if (loadTSGen) + ret = link.loadTSGenTimeSeries(folder) && ret; + // From the solver only if (study.usedByTheSolver) { diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 7dff01e952..512c741104 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -778,6 +778,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, area.spreadSpilledEnergyCost = 0.; bool ret = true; + const auto studyVersion = study.header.version; // DSM, Reserves, D-1 buffer.clear() << study.folderInput << SEP << "reserves" << SEP << area.id << ".txt"; @@ -810,7 +811,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, // Links { buffer.clear() << study.folderInput << SEP << "links" << SEP << area.id; - ret = AreaLinksLoadFromFolder(study, list, &area, buffer) && ret; + ret = AreaLinksLoadFromFolder(study, list, &area, buffer, options.linksLoadTSGen) && ret; } // UI @@ -879,12 +880,12 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, if (!options.loadOnlyNeeded || !area.hydro.prepro) // Series { buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "series"; - ret = hydroSeries->loadGenerationTS(area.id, buffer, study.header.version) && ret; + ret = hydroSeries->loadGenerationTS(area.id, buffer, studyVersion) && ret; hydroSeries->EqualizeGenerationTSsizes(area, study.usedByTheSolver); } - if (study.header.version < StudyVersion(9,1)) + if (studyVersion < StudyVersion(9,1)) { buffer.clear() << study.folderInput << SEP << "hydro"; @@ -905,7 +906,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, } hydroSeries->resizeTSinDeratedMode( - study.parameters.derated, study.header.version, study.usedByTheSolver); + study.parameters.derated, studyVersion, study.usedByTheSolver); } // Wind @@ -940,7 +941,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, } // Short term storage - if (study.header.version >= StudyVersion(8, 6)) + if (studyVersion >= StudyVersion(8, 6)) { buffer.clear() << study.folderInput << SEP << "st-storage" << SEP << "series" << SEP << area.id; @@ -950,7 +951,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, } // Renewable cluster list - if (study.header.version >= StudyVersion(8, 1)) + if (studyVersion >= StudyVersion(8, 1)) { buffer.clear() << study.folderInput << SEP << "renewables" << SEP << "series"; ret = area.renewable.list.loadDataSeriesFromFolder(study, buffer) && ret; @@ -1064,6 +1065,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) { bool ret = true; Clob buffer; + auto studyVersion = pStudy.header.version; // Load the list of all available areas { @@ -1102,7 +1104,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) } // Short term storage data, specific to areas - if (pStudy.header.version >= StudyVersion(8, 6)) + if (studyVersion >= StudyVersion(8, 6)) { logs.info() << "Loading short term storage clusters..."; buffer.clear() << pStudy.folderInput << SEP << "st-storage"; @@ -1123,7 +1125,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) } // Renewable data, specific to areas - if (pStudy.header.version >= StudyVersion(8, 1)) + if (studyVersion >= StudyVersion(8, 1)) { // The cluster list must be loaded before the method // ensureDataIsInitialized is called diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 1d43d79d6b..8603a0b537 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -359,7 +359,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) logs.verbosityLevel = Logs::Verbosity::Warning::level; // load all links buffer.clear() << infos->folder << "/input/links/" << area->id; - if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer)) + if (not AreaLinksLoadFromFolder(*study, arealist, area, buffer, false)) { delete arealist; delete study; @@ -417,4 +417,3 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) } } // namespace Antares::Data - diff --git a/src/libs/antares/study/include/antares/study/area/area.h b/src/libs/antares/study/include/antares/study/area/area.h index b6baf3f4d3..d5e095c57c 100644 --- a/src/libs/antares/study/include/antares/study/area/area.h +++ b/src/libs/antares/study/include/antares/study/area/area.h @@ -718,7 +718,11 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning = true); ** \param folder The target folder ** \return A non-null value if the operation succeeded, 0 otherwise */ -bool AreaLinksLoadFromFolder(Study& s, AreaList* l, Area* area, const AnyString& folder); +bool AreaLinksLoadFromFolder(const Study& s, + AreaList* l, + Area* area, + const AnyString& folder, + bool loadTSGen); /*! ** \brief Save interconnections of a given area into a folder (`input/areas/[area]/ntc`) @@ -777,9 +781,7 @@ Area* addAreaToListOfAreas(AreaList& list, const AnyString& name); ** \param lname The name of the area in lowercase ** \return A valid pointer to the area if successful, NULL otherwise */ -Area* AreaListAddFromNames(AreaList& list, - const AnyString& name, - const AnyString& lname); +Area* AreaListAddFromNames(AreaList& list, const AnyString& name, const AnyString& lname); /*! ** \brief Try to establish a link between two areas diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index a2a1c12bdb..04b416df66 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -22,7 +22,7 @@ #define __ANTARES_LIBS_STUDY_LINKS_H__ #include -#include +#include #include #include #include @@ -32,9 +32,6 @@ #include #include -//! The minimal allowed value for hurdle costs when not null -#define LINK_MINIMAL_HURDLE_COSTS_NOT_NULL 0.005 - namespace Antares { namespace Data @@ -69,7 +66,9 @@ class AreaLink final : public Yuni::NonCopyable ~AreaLink(); //@} - bool loadTimeSeries(const Study& study, const AnyString& folder); + bool loadTimeSeries(const StudyVersion& version, const AnyString& folder); + + bool loadTSGenTimeSeries(const AnyString& folder); void storeTimeseriesNumbers(Solver::IResultWriter& writer) const; @@ -207,22 +206,6 @@ class AreaLink final : public Yuni::NonCopyable friend struct CompareLinkName; - struct LinkTsGeneration - { - unsigned unitCount; - double nominalCapacity; - - double forcedVolatility; - double plannedVolatility; - - Data::ThermalLaw forcedLaw; - Data::ThermalLaw plannedLaw; - - Data::PreproThermal* prepro; - - Matrix<> modulationCapacity; - }; - LinkTsGeneration tsGenerationDirect; LinkTsGeneration tsGenerationIndirect; diff --git a/src/libs/antares/study/include/antares/study/load-options.h b/src/libs/antares/study/include/antares/study/load-options.h index aa751fbb07..c5fb87d12d 100644 --- a/src/libs/antares/study/include/antares/study/load-options.h +++ b/src/libs/antares/study/include/antares/study/load-options.h @@ -49,6 +49,10 @@ class StudyLoadOptions bool loadOnlyNeeded; //! Force the year-by-year flag bool forceYearByYear; + + //! Load data associated to link TS generation + bool linksLoadTSGen = false; + //! Force the derated mode bool forceDerated; diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/STStorageOutputCaptions.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/STStorageOutputCaptions.h deleted file mode 100644 index b291c9c184..0000000000 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/STStorageOutputCaptions.h +++ /dev/null @@ -1,29 +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 Antares::Data::ShortTermStorage -{ -std::string getVariableCaptionFromColumnIndex(unsigned int index); -} diff --git a/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h b/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h index 1b573ef20a..b1b2eaa107 100644 --- a/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h +++ b/src/libs/antares/study/include/antares/study/parts/short-term-storage/properties.h @@ -28,21 +28,6 @@ namespace Antares::Data::ShortTermStorage { -enum class Group -{ - PSP_open, - PSP_closed, - Pondage, - Battery, - Other1, - Other2, - Other3, - Other4, - Other5 -}; - -unsigned int groupIndex(Group group); - class Properties { public: @@ -62,15 +47,14 @@ class Properties bool initialLevelOptim = false; /// Efficiency factor between 0 and 1 double efficiencyFactor = 1; - /// Used to sort outputs - Group group = Group::Other1; + // Used to sort outputs + std::string groupName = "OTHER1"; /// cluster name std::string name; /// Enabled ? bool enabled = true; - static const std::map ST_STORAGE_PROPERTY_GROUP_ENUM; private: static constexpr double initiallevelDefault = .5; }; diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h index dbdcae4123..2c9872f5d6 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h @@ -286,9 +286,9 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this double plannedVolatility = 0.; //! Law (ts-generator) - ThermalLaw forcedLaw = thermalLawUniform; + StatisticalLaw forcedLaw = LawUniform; //! Law (ts-generator) - ThermalLaw plannedLaw = thermalLawUniform; + StatisticalLaw plannedLaw = LawUniform; //! \name Costs // Marginal (€/MWh) MA @@ -346,7 +346,7 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this std::vector PthetaInf; //! Data for the preprocessor - PreproThermal* prepro = nullptr; + PreproAvailability* prepro = nullptr; /*! ** \brief Production Cost, Market Bid Cost and Marginal Cost Matrixes - Per Hour and per Time diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx index 49f4ad21e3..494383edae 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx @@ -28,17 +28,17 @@ namespace Extension namespace CString { template -class Append +class Append { public: - static void Perform(CStringT& string, Antares::Data::ThermalLaw law) + static void Perform(CStringT& string, Antares::Data::StatisticalLaw law) { switch (law) { - case Antares::Data::thermalLawUniform: + case Antares::Data::LawUniform: string += "uniform"; break; - case Antares::Data::thermalLawGeometric: + case Antares::Data::LawGeometric: string += "geometric"; break; } @@ -85,10 +85,10 @@ public: }; template<> -class Into +class Into { public: - using TargetType = Antares::Data::ThermalLaw; + using TargetType = Antares::Data::StatisticalLaw; enum { valid = 1 @@ -99,7 +99,7 @@ public: template static TargetType Perform(const StringT& s) { - TargetType law = Antares::Data::thermalLawUniform; + TargetType law = Antares::Data::LawUniform; Perform(s, law); return law; } diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/defines.h b/src/libs/antares/study/include/antares/study/parts/thermal/defines.h index a04c2feeae..5d74c795ff 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/defines.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/defines.h @@ -28,7 +28,7 @@ namespace Data // Forward declaration class ThermalCluster; class ThermalClusterList; -class PreproThermal; +class PreproAvailability; } // namespace Data } // namespace Antares diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 12088231b0..a085e9d01f 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -33,6 +33,7 @@ #include #include "antares/study/load-options.h" #include +#include #include "antares/solver/variable/economy/all.h" #include @@ -477,6 +478,9 @@ static bool SGDIntLoadFamily_General(Parameters& d, return value.to(d.nbTimeSeriesThermal); if (key == "nbtimeseriessolar") return value.to(d.nbTimeSeriesSolar); + if (key == "nbtimeserieslinks") + return value.to(d.nbLinkTStoGenerate); + // Interval values if (key == "refreshintervalload") return value.to(d.refreshIntervalLoad); @@ -854,6 +858,24 @@ static bool SGDIntLoadFamily_Playlist(Parameters& d, return false; } +static bool deprecatedVariable(std::string var) +{ + static const std::vector STSGroups_legacy + = {"psp_open_level", "psp_closed_level", "pondage_level", + "battery_level", "other1_level", "other2_level", + "other3_level", "other4_level", "other5_level", + + "psp_open_injection", "psp_closed_injection", "pondage_injection", + "battery_injection", "other1_injection", "other2_injection", + "other3_injection", "other4_injection", "other5_injection", + + "psp_open_withdrawal", "psp_closed_withdrawal", "pondage_withdrawal", + "battery_withdrawal", "other1_withdrawal", "other2_withdrawal", + "other3_withdrawal", "other4_withdrawal", "other5_withdrawal"}; + boost::to_lower(var); + return std::ranges::find(STSGroups_legacy, var) != STSGroups_legacy.end(); +} + static bool SGDIntLoadFamily_VariablesSelection(Parameters& d, const String& key, const String& value, @@ -867,6 +889,12 @@ static bool SGDIntLoadFamily_VariablesSelection(Parameters& d, } if (key == "select_var +" || key == "select_var -") { + if (deprecatedVariable(value.to())) + { + logs.warning() << "Output variable `" << original + << "` no longer exists and has been ignored"; + return true; + } // Check if the read output variable exists if (not d.variablesPrintInfo.exists(value.to())) { @@ -1544,6 +1572,7 @@ void Parameters::saveToINI(IniFile& ini) const section->add("nbTimeSeriesWind", nbTimeSeriesWind); section->add("nbTimeSeriesThermal", nbTimeSeriesThermal); section->add("nbTimeSeriesSolar", nbTimeSeriesSolar); + section->add("nbtimeserieslinks", nbLinkTStoGenerate); // Refresh ParametersSaveTimeSeries(section, "refreshTimeSeries", timeSeriesToRefresh); diff --git a/src/libs/antares/study/parts/short-term-storage/STStorageOutputCaptions.cpp b/src/libs/antares/study/parts/short-term-storage/STStorageOutputCaptions.cpp deleted file mode 100644 index 29abc31b7f..0000000000 --- a/src/libs/antares/study/parts/short-term-storage/STStorageOutputCaptions.cpp +++ /dev/null @@ -1,54 +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 -#include "antares/study/parts/short-term-storage/STStorageOutputCaptions.h" - -namespace Antares::Data::ShortTermStorage -{ -static const std::vector groups = {"PSP_open", - "PSP_closed", - "Pondage", - "Battery", - "Other1", - "Other2", - "Other3", - "Other4", - "Other5"}; - -static const std::vector variables = {"injection", "withdrawal", "level"}; - -const unsigned int nb_groups = groups.size(); -const unsigned int nb_variables = variables.size(); - -std::string getVariableCaptionFromColumnIndex(unsigned int col_index) -{ - if (col_index < nb_groups * nb_variables) - { - unsigned int group_index = col_index / nb_variables; - unsigned int variable_index = col_index % nb_variables; - return groups[group_index] + "_" + variables[variable_index]; - } - else - return ""; -} - -} // End namespace Antares::Data::ShortTermStorage diff --git a/src/libs/antares/study/parts/short-term-storage/properties.cpp b/src/libs/antares/study/parts/short-term-storage/properties.cpp index 3bbe3ec181..1a01c9486e 100644 --- a/src/libs/antares/study/parts/short-term-storage/properties.cpp +++ b/src/libs/antares/study/parts/short-term-storage/properties.cpp @@ -21,6 +21,7 @@ #include #include +#include #include "antares/study/parts/short-term-storage/properties.h" @@ -28,43 +29,6 @@ namespace Antares::Data::ShortTermStorage { -const std::map Properties::ST_STORAGE_PROPERTY_GROUP_ENUM - = {{"PSP_open", Group::PSP_open}, - {"PSP_closed", Group::PSP_closed}, - {"Pondage", Group::Pondage}, - {"Battery", Group::Battery}, - {"Other1", Group::Other1}, - {"Other2", Group::Other2}, - {"Other3", Group::Other3}, - {"Other4", Group::Other4}, - {"Other5", Group::Other5}}; - -unsigned int groupIndex(Group group) -{ - switch (group) - { - case Group::PSP_open: - return 0; - case Group::PSP_closed: - return 1; - case Group::Pondage: - return 2; - case Group::Battery: - return 3; - case Group::Other1: - return 4; - case Group::Other2: - return 5; - case Group::Other3: - return 6; - case Group::Other4: - return 7; - case Group::Other5: - return 8; - default: - throw std::invalid_argument("Group not recognized"); - } -} bool Properties::loadKey(const IniFile::Property* p) { @@ -100,13 +64,9 @@ bool Properties::loadKey(const IniFile::Property* p) if (p->key == "group") { - if (auto it = Properties::ST_STORAGE_PROPERTY_GROUP_ENUM.find(p->value.c_str()); - it != Properties::ST_STORAGE_PROPERTY_GROUP_ENUM.end()) - { - this->group = it->second; - return true; - } - return false; + this->groupName = p->value.c_str(); + boost::to_upper(this->groupName); + return true; } if (p->key == "enabled") @@ -120,11 +80,7 @@ void Properties::save(IniFile& ini) const IniFile::Section* s = ini.addSection(this->name); s->add("name", this->name); - - for (const auto& [key, value] : ST_STORAGE_PROPERTY_GROUP_ENUM) - if (value == this->group) - s->add("group", key); - + s->add("group", this->groupName); s->add("reservoircapacity", this->reservoirCapacity); s->add("initiallevel", this->initialLevel); s->add("injectionnominalcapacity", this->injectionNominalCapacity); diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index 60f2e2cecb..e026d92b59 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -42,7 +42,7 @@ using namespace Antares; namespace Yuni::Extension::CString { -bool Into::Perform(AnyString string, TargetType& out) +bool Into::Perform(AnyString string, TargetType& out) { string.trim(); if (string.empty()) @@ -50,12 +50,12 @@ bool Into::Perform(AnyString string, TargetType& out) if (string.equalsInsensitive("uniform")) { - out = Antares::Data::thermalLawUniform; + out = Antares::Data::LawUniform; return true; } if (string.equalsInsensitive("geometric")) { - out = Antares::Data::thermalLawGeometric; + out = Antares::Data::LawGeometric; return true; } return false; @@ -189,7 +189,7 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster) // Making sure that the data related to the prepro and timeseries are present // prepro if (!prepro) - prepro = new PreproThermal(this->weak_from_this()); + prepro = new PreproAvailability(id(), unitCount); prepro->copyFrom(*cluster.prepro); ecoInput.copyFrom(cluster.ecoInput); @@ -431,8 +431,8 @@ void Data::ThermalCluster::reset() forcedVolatility = 0.; plannedVolatility = 0.; // laws - plannedLaw = thermalLawUniform; - forcedLaw = thermalLawUniform; + plannedLaw = LawUniform; + forcedLaw = LawUniform; // costs costgeneration = setManually; @@ -454,7 +454,7 @@ void Data::ThermalCluster::reset() // since the interface may still have a pointer to them. // we must simply reset their content. if (!prepro) - prepro = new PreproThermal(this->weak_from_this()); + prepro = new PreproAvailability(id(), unitCount); prepro->reset(); ecoInput.reset(); } diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index d739750615..6efb5376ab 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -331,7 +331,7 @@ void ThermalClusterList::ensureDataPrepro() { for (const auto& c : all()) if (!c->prepro) - c->prepro = new PreproThermal(c); + c->prepro = new PreproAvailability(c->id(), c->unitCount); } bool ThermalClusterList::saveToFolder(const AnyString& folder) const @@ -399,9 +399,9 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const s->add("volatility.planned", Utils::round(c->plannedVolatility, 3)); // laws - if (c->forcedLaw != thermalLawUniform) + if (c->forcedLaw != LawUniform) s->add("law.forced", c->forcedLaw); - if (c->plannedLaw != thermalLawUniform) + if (c->plannedLaw != LawUniform) s->add("law.planned", c->plannedLaw); // costs @@ -478,14 +478,13 @@ bool ThermalClusterList::saveEconomicCosts(const AnyString& folder) const return ret; } -bool ThermalClusterList::loadPreproFromFolder(Study& study, - const AnyString& folder) +bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& folder) { const bool globalThermalTSgeneration - = study.parameters.timeSeriesToGenerate & timeSeriesThermal; + = study.parameters.timeSeriesToGenerate & timeSeriesThermal; Clob buffer; - auto hasPrepro = [](auto c) { return (bool) c->prepro; }; + auto hasPrepro = [](auto c) { return (bool)c->prepro; }; auto loadAndCheckPrepro = [&buffer, &folder, &study, &globalThermalTSgeneration](auto c) { @@ -494,6 +493,11 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, bool result = c->prepro->loadFromFolder(study, buffer); + if (study.usedByTheSolver && globalThermalTSgeneration) + { + result = c->prepro->validate() && result; + } + if (result && study.usedByTheSolver && c->doWeGenerateTS(globalThermalTSgeneration)) { result = c->prepro->normalizeAndCheckNPO(); diff --git a/src/solver/ts-generator/CMakeLists.txt b/src/solver/ts-generator/CMakeLists.txt index 97960c7c48..5ad6672021 100644 --- a/src/solver/ts-generator/CMakeLists.txt +++ b/src/solver/ts-generator/CMakeLists.txt @@ -7,7 +7,7 @@ set(SRC_GENERATORS include/antares/solver/ts-generator/generator.h include/antares/solver/ts-generator/generator.hxx generator.cpp - thermal.cpp + availability.cpp hydro.cpp ) source_group("ts-generator" FILES ${SRC_GENERATORS}) diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/availability.cpp similarity index 79% rename from src/solver/ts-generator/thermal.cpp rename to src/solver/ts-generator/availability.cpp index 3b16622c02..902fab314c 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -33,11 +33,11 @@ #define SEP Yuni::IO::Separator -#define FAILURE_RATE_EQ_1 0.999 +constexpr double FAILURE_RATE_EQ_1 = 0.999; namespace Antares::TSGenerator { -ThermalInterface::ThermalInterface(Data::ThermalCluster* source) : +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* source) : unitCount(source->unitCount), nominalCapacity(source->nominalCapacity), forcedVolatility(source->forcedVolatility), @@ -51,7 +51,7 @@ ThermalInterface::ThermalInterface(Data::ThermalCluster* source) : { } -ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, Data::TimeSeries& capacity, const std::string& areaDestName) : unitCount(source.unitCount), @@ -60,7 +60,7 @@ ThermalInterface::ThermalInterface(Data::AreaLink::LinkTsGeneration& source, plannedVolatility(source.plannedVolatility), forcedLaw(source.forcedLaw), plannedLaw(source.plannedLaw), - prepro(source.prepro), + prepro(source.prepro.get()), series(capacity), modulationCapacity(source.modulationCapacity[0]), name(areaDestName) @@ -74,79 +74,60 @@ class GeneratorTempData final public: explicit GeneratorTempData(Data::Study&, unsigned); - void generateTS(const Data::Area& area, ThermalInterface& cluster); + void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster); -public: +private: Data::Study& study; - bool derated; -private: - int durationGenerator(Data::ThermalLaw law, int expec, double volat, double a, double b); - - template - void prepareIndispoFromLaw(Data::ThermalLaw law, - double volatility, - double A[], - double B[], - const T& duration); - -private: uint nbOfSeriesToGen_; MersenneTwister& rndgenerator; - enum - { - Log_size = 4000 - }; - - double lf[366]; - double lp[366]; - double ff[366]; - double pp[366]; - double af[366]; - double ap[366]; - double bf[366]; - double bp[366]; + static constexpr int Log_size = 4000; + + int durationGenerator(Data::StatisticalLaw law, int expec, double volat, double a, double b) const; + template + void prepareIndispoFromLaw(Data::StatisticalLaw law, + double volatility, + std::array& A, + std::array& B, + const T& duration) const; }; GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : - study(study), - nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]) -{ - auto& parameters = study.parameters; - - derated = parameters.derated; -} + study(study), + derated(study.parameters.derated), + nbOfSeriesToGen_(nbOfSeriesToGen), + rndgenerator(study.runtime->random[Data::seedTsGenThermal]) +{} template -void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, +void GeneratorTempData::prepareIndispoFromLaw(Data::StatisticalLaw law, double volatility, - double A[], - double B[], - const T& duration) + std::array& A, + std::array& B, + const T& duration) const { switch (law) { - case Data::thermalLawUniform: + case Data::LawUniform: { for (uint d = 0; d < DAYS_PER_YEAR; ++d) { - double D = (double)duration[d]; + double D = duration[d]; double xtemp = volatility * (D - 1.); A[d] = D - xtemp; B[d] = 2. * xtemp + 1.; } break; } - case Data::thermalLawGeometric: + case Data::LawGeometric: { for (uint d = 0; d < DAYS_PER_YEAR; ++d) { - double D = (double)duration[d]; + double D = duration[d]; double xtemp = volatility * volatility * D * (D - 1.); if (xtemp != 0) { @@ -168,40 +149,38 @@ void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, } } -int GeneratorTempData::durationGenerator(Data::ThermalLaw law, +int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, int expec, double volat, double a, - double b) + double b) const { - if (volat == 0 or expec == 1) + if (volat == 0 || expec == 1) return expec; double rndnumber = rndgenerator.next(); switch (law) { - case Data::thermalLawUniform: + case Data::LawUniform: { return (int(a + rndnumber * b)); } - case Data::thermalLawGeometric: + case Data::LawGeometric: { int resultat = (1 + int(a + (b)*log(rndnumber))); - enum - { - limit = Log_size / 2 - 1 - }; + int limit = Log_size / 2 - 1; + assert(limit == 1999); return (resultat <= limit) ? resultat : limit; } } - assert(false and "return is missing"); + assert(false && "return is missing"); return 0; } -void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& cluster) +void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) { - if (not cluster.prepro) + if (!cluster.prepro) { logs.error() << "Cluster: " << area.name << '/' << cluster.name @@ -212,24 +191,24 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu assert(cluster.prepro); - if (0 == cluster.unitCount or 0 == cluster.nominalCapacity) + if (0 == cluster.unitCount || 0 == cluster.nominalCapacity) return; const auto& preproData = *(cluster.prepro); int AUN = (int)cluster.unitCount; - auto& FOD = preproData.data[Data::PreproThermal::foDuration]; + auto& FOD = preproData.data[Data::PreproAvailability::foDuration]; - auto& POD = preproData.data[Data::PreproThermal::poDuration]; + auto& POD = preproData.data[Data::PreproAvailability::poDuration]; - auto& FOR = preproData.data[Data::PreproThermal::foRate]; + auto& FOR = preproData.data[Data::PreproAvailability::foRate]; - auto& POR = preproData.data[Data::PreproThermal::poRate]; + auto& POR = preproData.data[Data::PreproAvailability::poRate]; - auto& NPOmin = preproData.data[Data::PreproThermal::npoMin]; + auto& NPOmin = preproData.data[Data::PreproAvailability::npoMin]; - auto& NPOmax = preproData.data[Data::PreproThermal::npoMax]; + auto& NPOmax = preproData.data[Data::PreproAvailability::npoMax]; double f_volatility = cluster.forcedVolatility; @@ -242,6 +221,15 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu std::vector> FPOW(DAYS_PER_YEAR); std::vector> PPOW(DAYS_PER_YEAR); + std::array lf; + std::array lp; + std::array ff; + std::array pp; + std::array af; + std::array ap; + std::array bf; + std::array bp; + int FODOfTheDay; int PODOfTheDay; @@ -259,10 +247,10 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu lf[d] = FOR[d] / (FOR[d] + (FODOfTheDay) * (1. - FOR[d])); lp[d] = POR[d] / (POR[d] + (PODOfTheDay) * (1. - POR[d])); - if (0. < lf[d] and lf[d] < lp[d]) + if (0. < lf[d] && lf[d] < lp[d]) lf[d] *= (1. - lp[d]) / (1. - lf[d]); - if (0. < lp[d] and lp[d] < lf[d]) + if (0. < lp[d] && lp[d] < lf[d]) lp[d] *= (1. - lf[d]) / (1. - lp[d]); double a = 0.; @@ -290,9 +278,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu prepareIndispoFromLaw(f_law, f_volatility, af, bf, FOD); prepareIndispoFromLaw(p_law, p_volatility, ap, bp, POD); - std::array AVP {}; - std::array LOG {}; - std::array LOGP {}; + std::array AVP{}; + std::array LOG{}; + std::array LOGP{}; int MXO = 0; @@ -326,8 +314,8 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) { assert(dayInTheYear < 366); - assert(not(lf[dayInTheYear] < 0.)); - assert(not(lp[dayInTheYear] < 0.)); + assert(lf[dayInTheYear] >= 0.); + assert(lp[dayInTheYear] >= 0.); PODOfTheDay = (int)POD[dayInTheYear]; FODOfTheDay = (int)FOD[dayInTheYear]; @@ -378,7 +366,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu int POC = 0; - if (lf[dayInTheYear] > 0. and lf[dayInTheYear] <= FAILURE_RATE_EQ_1) + if (lf[dayInTheYear] > 0. && lf[dayInTheYear] <= FAILURE_RATE_EQ_1) { A = rndgenerator.next(); last = FPOW[dayInTheYear][AUN]; @@ -401,10 +389,10 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu FOC = (lf[dayInTheYear] > 0.) ? AUN : 0; } - if (lp[dayInTheYear] > 0. and lp[dayInTheYear] <= FAILURE_RATE_EQ_1) + if (lp[dayInTheYear] > 0. && lp[dayInTheYear] <= FAILURE_RATE_EQ_1) { int AUN_app = AUN; - if (stock >= 0 and stock <= AUN) + if (stock >= 0 && stock <= AUN) AUN_app -= stock; if (stock > AUN) AUN_app = 0; @@ -432,7 +420,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu } int candidat = POC + stock; - if (0 <= candidat and candidat <= AUN) + if (0 <= candidat && candidat <= AUN) { POC = candidat; @@ -487,7 +475,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu if (cluster.unitCount == 1) { - if (POC == 1 and FOC == 1) + if (POC == 1 && FOC == 1) { PPO = 0; PFO = 0; @@ -518,10 +506,10 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu AUN = AUN - (PPO + PFO + MXO); - if (PFO != 0 or MXO != 0) + if (PFO != 0 || MXO != 0) FOD_reel = durationGenerator( f_law, FODOfTheDay, f_volatility, af[dayInTheYear], bf[dayInTheYear]); - if (PPO != 0 or MXO != 0) + if (PPO != 0 || MXO != 0) POD_reel = durationGenerator( p_law, PODOfTheDay, p_volatility, ap[dayInTheYear], bp[dayInTheYear]); @@ -564,12 +552,12 @@ void GeneratorTempData::generateTS(const Data::Area& area, ThermalInterface& clu } } // namespace -std::vector getAllClustersToGen(Data::AreaList& areas, +std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration) { std::vector clusters; - areas.each([&clusters, &globalThermalTSgeneration](Data::Area& area) { + areas.each([&clusters, &globalThermalTSgeneration](const Data::Area& area) { for (const auto& cluster : area.thermal.list.all()) if (cluster->doWeGenerateTS(globalThermalTSgeneration)) clusters.push_back(cluster.get()); @@ -582,7 +570,7 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) { listOfLinks links; - areas.each([&links](Data::Area& area) { + areas.each([&links](const Data::Area& area) { std::ranges::for_each(area.links, [&links](auto& l) { links.emplace_back(l.second, linkDirection::direct); links.emplace_back(l.second, linkDirection::indirect); @@ -606,7 +594,7 @@ void writeResultsToDisk(const Data::Study& study, } bool generateThermalTimeSeries(Data::Study& study, - std::vector clusters, + const std::vector& clusters, Solver::IResultWriter& writer, const std::string& savePath) { @@ -620,12 +608,13 @@ bool generateThermalTimeSeries(Data::Study& study, // TODO VP: parallel for (auto* cluster : clusters) { - ThermalInterface clusterInterface(cluster); + AvailabilityTSGeneratorData clusterInterface(cluster); generator.generateTS(*cluster->parentArea, clusterInterface); if (archive) // compatibilty with in memory { - std::string filePath = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; + std::string filePath + = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; writeResultsToDisk(study, writer, cluster->series.timeSeries, filePath); } @@ -650,15 +639,20 @@ bool generateLinkTimeSeries(Data::Study& study, Data::TimeSeries ts(link->timeseriesNumbers); ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); - auto& tsGenStruct = direction == linkDirection::direct ? link->tsGenerationDirect : link->tsGenerationIndirect; - - ThermalInterface linkInterface(tsGenStruct, ts, link->with->name); + auto& tsGenStruct = direction == linkDirection::direct ? link->tsGenerationDirect + : link->tsGenerationIndirect; + if (!tsGenStruct.valid) + { + logs.error() << "Missing data for link " << link->from->id << "/" << link->with->id; + return false; + } + AvailabilityTSGeneratorData linkInterface(tsGenStruct, ts, link->with->name); generator.generateTS(*link->from, linkInterface); std::string capacityType = direction == linkDirection::direct ? "_direct" : "_indirect"; - std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() - + capacityType + ".txt"; + std::string filePath + = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + capacityType + ".txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 11dce8b3a3..32cc053f1b 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -33,11 +33,11 @@ namespace Antares::TSGenerator { -class ThermalInterface +class AvailabilityTSGeneratorData { public: - explicit ThermalInterface(Data::ThermalCluster*); - ThermalInterface(Data::AreaLink::LinkTsGeneration&, Data::TimeSeries&, const std::string& name); + explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); + AvailabilityTSGeneratorData(Data::LinkTsGeneration&, Data::TimeSeries&, const std::string& name); const unsigned& unitCount; const double& nominalCapacity; @@ -45,10 +45,10 @@ class ThermalInterface const double& forcedVolatility; const double& plannedVolatility; - Data::ThermalLaw& forcedLaw; - Data::ThermalLaw& plannedLaw; + Data::StatisticalLaw& forcedLaw; + Data::StatisticalLaw& plannedLaw; - Data::PreproThermal* prepro; + Data::PreproAvailability* prepro; Data::TimeSeries& series; @@ -63,8 +63,7 @@ enum class linkDirection indirect }; -using listOfLinks = std::vector>; - +using listOfLinks = std::vector>; void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); @@ -75,7 +74,7 @@ template bool GenerateTimeSeries(Data::Study& study, uint year, IResultWriter& writer); bool generateThermalTimeSeries(Data::Study& study, - std::vector clusters, + const std::vector& clusters, Solver::IResultWriter& writer, const std::string& savePath); @@ -84,7 +83,7 @@ bool generateLinkTimeSeries(Data::Study& study, Solver::IResultWriter& writer, const std::string& savePath); -std::vector getAllClustersToGen(Data::AreaList& areas, +std::vector getAllClustersToGen(const Data::AreaList& areas, bool globalThermalTSgeneration); listOfLinks getAllLinksToGen(Data::AreaList& areas); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/law.h b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h index 35214c540d..5dfb2a2014 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/law.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h @@ -2,9 +2,9 @@ namespace Antares::Data { -enum ThermalLaw +enum StatisticalLaw { - thermalLawUniform, - thermalLawGeometric + LawUniform, + LawGeometric }; } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index d7d91c4f67..564c6d803e 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace Antares::Data @@ -31,7 +32,7 @@ namespace Antares::Data /*! ** \brief Thermal */ -class PreproThermal +class PreproAvailability { public: enum @@ -49,7 +50,7 @@ class PreproThermal //! NPO max (nombre maximal de groupes en maintenance) npoMax, // max - thermalPreproMax, + preproAvailabilityMax, }; //! \name Constructor @@ -57,7 +58,7 @@ class PreproThermal /*! ** \brief Default constructor */ - explicit PreproThermal(std::weak_ptr cluster); + explicit PreproAvailability(const YString& id, unsigned int unitCount); //@} bool forceReload(bool reload) const; @@ -70,7 +71,7 @@ class PreproThermal void reset(); //! Copy data from another struct - void copyFrom(const PreproThermal& rhs); + void copyFrom(const PreproAvailability& rhs); /*! ** \brief Load settings for the thermal prepro from a folder @@ -80,6 +81,11 @@ class PreproThermal */ bool loadFromFolder(Study& study, const AnyString& folder); + /*! + ** \brief Validate most settings against min/max rules + */ + bool validate() const; + /*! ** \brief Save settings used by the thermal prepro to a folder ** @@ -104,9 +110,27 @@ class PreproThermal // max x DAYS_PER_YEAR Matrix<> data; // Parent thermal cluster - std::weak_ptr itsThermalCluster; -}; // class PreproThermal + YString id; + unsigned int unitCount; +}; // class PreproAvailability + +struct LinkTsGeneration +{ + unsigned unitCount; + double nominalCapacity; + + double forcedVolatility; + double plannedVolatility; + + Data::StatisticalLaw forcedLaw; + Data::StatisticalLaw plannedLaw; + + std::unique_ptr prepro; + + Matrix<> modulationCapacity; + bool valid = false; +}; } // namespace Antares::Data #include "prepro.hxx" diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx index 0fba61efcc..966e9d14f3 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx @@ -25,9 +25,9 @@ namespace Antares { namespace Data { -inline uint64_t PreproThermal::memoryUsage() const +inline uint64_t PreproAvailability::memoryUsage() const { - return sizeof(PreproThermal); + return sizeof(PreproAvailability); } } // namespace Data diff --git a/src/solver/ts-generator/prepro.cpp b/src/solver/ts-generator/prepro.cpp index ba9a63f18f..898da4f6b5 100644 --- a/src/solver/ts-generator/prepro.cpp +++ b/src/solver/ts-generator/prepro.cpp @@ -33,19 +33,20 @@ using namespace Yuni; namespace Antares::Data { -PreproThermal::PreproThermal(std::weak_ptr cluster) : - itsThermalCluster(cluster) +PreproAvailability::PreproAvailability(const YString& id, unsigned int unitCount) : + id(id), unitCount(unitCount) { } -void PreproThermal::copyFrom(const PreproThermal& rhs) +void PreproAvailability::copyFrom(const PreproAvailability& rhs) { - itsThermalCluster = rhs.itsThermalCluster; + id = rhs.id; + unitCount = rhs.unitCount; data = rhs.data; rhs.data.unloadFromMemory(); } -bool PreproThermal::saveToFolder(const AnyString& folder) const +bool PreproAvailability::saveToFolder(const AnyString& folder) const { if (IO::Directory::Create(folder)) { @@ -56,116 +57,106 @@ bool PreproThermal::saveToFolder(const AnyString& folder) const return false; } -bool PreproThermal::loadFromFolder(Study& study, const AnyString& folder) +bool PreproAvailability::loadFromFolder(Study& study, const AnyString& folder) { bool ret = true; auto& buffer = study.bufferLoadingTS; - auto cluster = itsThermalCluster.lock(); - if (!cluster) - return false; - - auto parentArea = cluster->parentArea; - buffer.clear() << folder << SEP << "data.txt"; // standard loading - ret = data.loadFromCSVFile( - buffer, thermalPreproMax, DAYS_PER_YEAR, Matrix<>::optFixedSize, &study.dataBuffer) - && ret; + return data.loadFromCSVFile( + buffer, preproAvailabilityMax, DAYS_PER_YEAR, Matrix<>::optFixedSize, &study.dataBuffer); +} + +bool PreproAvailability::validate() const +{ + const auto& colFoRate = data[foRate]; + const auto& colPoRate = data[poRate]; + const auto& colFoDuration = data[foDuration]; + const auto& colPoDuration = data[poDuration]; + const auto& colNPOMin = data[npoMin]; + const auto& colNPOMax = data[npoMax]; + uint errors = 0; - bool thermalTSglobalGeneration = study.parameters.isTSGeneratedByPrepro(timeSeriesThermal); - if (study.usedByTheSolver && cluster->doWeGenerateTS(thermalTSglobalGeneration)) + for (uint i = 0; i != DAYS_PER_YEAR; ++i) { - auto& colFoRate = data[foRate]; - auto& colPoRate = data[poRate]; - auto& colFoDuration = data[foDuration]; - auto& colPoDuration = data[poDuration]; - auto& colNPOMin = data[npoMin]; - auto& colNPOMax = data[npoMax]; - uint errors = 0; - - for (uint i = 0; i != DAYS_PER_YEAR; ++i) + double foRate = colFoRate[i]; + double poRate = colPoRate[i]; + double foDuration = colFoDuration[i]; + double poDuration = colPoDuration[i]; + double cNPOMin = colNPOMin[i]; + double cNPOMax = colNPOMax[i]; + + if (cNPOMin < 0) { - double foRate = colFoRate[i]; - double poRate = colPoRate[i]; - double foDuration = colFoDuration[i]; - double poDuration = colPoDuration[i]; - double cNPOMin = colNPOMin[i]; - double cNPOMax = colNPOMax[i]; - - if (cNPOMin < 0) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": NPO min can not be negative (line:" << (i + 1) << ")"; - ++errors; - } - if (cNPOMax < 0) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": NPO max can not be negative (line:" << (i + 1) << ")"; - ++errors; - } - if (cNPOMin > cNPOMax) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": NPO max must be greater or equal to NPO min (line:" << (i + 1) - << ")"; - ++errors; - } + logs.error() << "Prepro: " << id << ": NPO min can not be negative (line:" << (i + 1) + << ")"; + ++errors; + } + if (cNPOMax < 0) + { + logs.error() << "Prepro: " << id << ": NPO max can not be negative (line:" << (i + 1) + << ")"; + ++errors; + } + if (cNPOMin > cNPOMax) + { + logs.error() << "Prepro: " << id + << ": NPO max must be greater or equal to NPO min (line:" << (i + 1) + << ")"; + ++errors; + } - if (foRate < 0. || foRate > 1.) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": invalid value for FO rate (line:" << (i + 1) << ")"; - ++errors; - } + if (foRate < 0. || foRate > 1.) + { + logs.error() << "Prepro: " << id << ": invalid value for FO rate (line:" << (i + 1) + << ")"; + ++errors; + } - if (poRate < 0. || poRate > 1.) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": invalid value for PO rate (line:" << (i + 1) << ")"; - ++errors; - } + if (poRate < 0. || poRate > 1.) + { + logs.error() << "Prepro: " << id << ": invalid value for PO rate (line:" << (i + 1) + << ")"; + ++errors; + } - if (foDuration < 1. || foDuration > 365.) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": invalid value for FO Duration (line:" << (i + 1) << ")"; - ++errors; - } - if (poDuration < 1. || poDuration > 365.) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": invalid value for PO Duration (line:" << (i + 1) << ")"; - ++errors; - } + if (foDuration < 1. || foDuration > 365.) + { + logs.error() << "Prepro: " << id << ": invalid value for FO Duration (line:" << (i + 1) + << ")"; + ++errors; + } + if (poDuration < 1. || poDuration > 365.) + { + logs.error() << "Prepro: " << id << ": invalid value for PO Duration (line:" << (i + 1) + << ")"; + ++errors; + } - if (errors > 30) - { - logs.error() << "Thermal: Prepro: " << parentArea->id << '/' << cluster->id() - << ": too many errors. skipping"; - break; - } + if (errors > 30) + { + logs.error() << "Prepro: " << id << ": too many errors. skipping"; + break; } } - - return ret; + return errors == 0; } -bool PreproThermal::forceReload(bool reload) const +bool PreproAvailability::forceReload(bool reload) const { return data.forceReload(reload); } -void PreproThermal::markAsModified() const +void PreproAvailability::markAsModified() const { data.markAsModified(); } -void PreproThermal::reset() +void PreproAvailability::reset() { - data.reset(thermalPreproMax, DAYS_PER_YEAR, true); + data.reset(preproAvailabilityMax, DAYS_PER_YEAR, true); auto& colFoDuration = data[foDuration]; auto& colPoDuration = data[poDuration]; @@ -177,14 +168,8 @@ void PreproThermal::reset() } } -bool PreproThermal::normalizeAndCheckNPO() +bool PreproAvailability::normalizeAndCheckNPO() { - auto cluster = itsThermalCluster.lock(); - if (!cluster) - return false; - - auto parentArea = cluster->parentArea; - // alias to our data columns auto& columnNPOMax = data[npoMax]; auto& columnNPOMin = data[npoMin]; @@ -196,9 +181,9 @@ bool PreproThermal::normalizeAndCheckNPO() for (uint y = 0; y != data.height; ++y) { - if (columnNPOMax[y] > cluster->unitCount) + if (columnNPOMax[y] > unitCount) { - columnNPOMax[y] = cluster->unitCount; + columnNPOMax[y] = unitCount; normalized = true; } @@ -206,8 +191,7 @@ bool PreproThermal::normalizeAndCheckNPO() { if (++errors < maxErrors) { - logs.error() << cluster->id() << " in area " << cluster->parentArea->id - << ": NPO min can not be greater than NPO max (hour: " << (y + 1) + logs.error() << id << ": NPO min can not be greater than NPO max (hour: " << (y + 1) << ", npo-min: " << columnNPOMin[y] << ", npo-max: " << columnNPOMax[y] << ')'; } @@ -215,12 +199,10 @@ bool PreproThermal::normalizeAndCheckNPO() } if (errors >= maxErrors) - logs.error() << cluster->id() << " in area " << parentArea->id - << ": too many errors. skipping (total: " << errors << ')'; + logs.error() << id << ": too many errors. skipping (total: " << errors << ')'; if (normalized) - logs.info() << " NPO max for the thermal cluster '" << parentArea->id - << "' has been normalized"; + logs.info() << " NPO max for entity '" << id << "' has been normalized"; data.markAsModified(); return (0 == errors); diff --git a/src/solver/variable/CMakeLists.txt b/src/solver/variable/CMakeLists.txt index a396bfb80e..c8e027546e 100644 --- a/src/solver/variable/CMakeLists.txt +++ b/src/solver/variable/CMakeLists.txt @@ -103,7 +103,7 @@ set(SRC_VARIABLE_ECONOMY include/antares/solver/variable/economy/overflow.h include/antares/solver/variable/economy/waterValue.h include/antares/solver/variable/economy/hydroCost.h - include/antares/solver/variable/economy/shortTermStorage.h + include/antares/solver/variable/economy/STSbyGroup.h include/antares/solver/variable/economy/STStorageInjectionByCluster.h include/antares/solver/variable/economy/STStorageWithdrawalByCluster.h include/antares/solver/variable/economy/STStorageLevelsByCluster.h diff --git a/src/solver/variable/include/antares/solver/variable/adequacy/all.h b/src/solver/variable/include/antares/solver/variable/adequacy/all.h index b6a67a3e33..cc13070a87 100644 --- a/src/solver/variable/include/antares/solver/variable/adequacy/all.h +++ b/src/solver/variable/include/antares/solver/variable/adequacy/all.h @@ -51,13 +51,13 @@ #include "antares/solver/variable/economy/overflow.h" #include "antares/solver/variable/economy/waterValue.h" #include "antares/solver/variable/economy/hydroCost.h" -#include "antares/solver/variable/economy/shortTermStorage.h" + #include "antares/solver/variable/economy/unsupliedEnergy.h" #include "antares/solver/variable/adequacy/spilledEnergy.h" #include "antares/solver/variable/economy/productionByDispatchablePlant.h" #include "antares/solver/variable/economy/productionByRenewablePlant.h" -// Short term storage output variables by cluster +#include "antares/solver/variable/economy/STSbyGroup.h" #include "antares/solver/variable/economy/STStorageInjectionByCluster.h" #include "antares/solver/variable/economy/STStorageWithdrawalByCluster.h" #include "antares/solver/variable/economy/STStorageLevelsByCluster.h" @@ -142,7 +142,7 @@ typedef // Prices >>>>>>>>>>>>>>>>>>>>>>>>>>>> + Marge>>>>>>>>>>>>>>>>>>>>>>>>>>>> VariablesPerSetOfAreas; typedef Variable::Economy::BindingConstMarginCost< // Marginal cost for a binding constraint diff --git a/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h b/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h new file mode 100644 index 0000000000..f9d43962aa --- /dev/null +++ b/src/solver/variable/include/antares/solver/variable/economy/STSbyGroup.h @@ -0,0 +1,420 @@ +/* +** 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/variable/variable.h" + +namespace +{ +inline std::vector sortedUniqueGroups( + const std::vector& storages) +{ + std::set names; + for (const auto& cluster : storages) + names.insert(cluster.properties.groupName); + return {names.begin(), names.end()}; +} + +inline std::map giveNumbersToGroups( + const std::vector& groupNames) +{ + unsigned int groupNumber{0}; + std::map groupToNumbers; + for (const auto& name : groupNames) + { + groupToNumbers[name] = groupNumber++; + } + return groupToNumbers; +} +} // namespace + +namespace Antares::Solver::Variable::Economy +{ +struct VCardSTSbyGroup +{ + //! Caption + static std::string Caption() + { + return "STS by group"; + } + //! Unit + static std::string Unit() + { + return "MWh"; + } + + //! The short description of the variable + static std::string Description() + { + return "STS injections, withdrawals and levels"; + } + + //! The synhesis results + typedef Results>>>> + ResultsType; + + //! The VCard to look for for calculating spatial aggregates + typedef VCardSTSbyGroup VCardForSpatialAggregate; + + enum + { + //! Data Level + categoryDataLevel = Category::area, + //! File level (provided by the type of the results) + categoryFileLevel = ResultsType::categoryFile & (Category::id | Category::va), + //! Precision (views) + precision = Category::all, + //! Indentation (GUI) + nodeDepthForGUI = +0, + //! Decimal precision + decimal = 0, + // Nb of columns occupied by this variable in year-by-year results + columnCount = Category::dynamicColumns, + //! The Spatial aggregation + spatialAggregate = Category::spatialAggregateSum, + spatialAggregateMode = Category::spatialAggregateEachYear, + spatialAggregatePostProcessing = 0, + //! Intermediate values + hasIntermediateValues = 1, + //! Can this variable be non applicable (0 : no, 1 : yes) + isPossiblyNonApplicable = 0, + }; + + typedef IntermediateValues IntermediateValuesDeepType; + typedef IntermediateValues* IntermediateValuesBaseType; + typedef IntermediateValuesBaseType* IntermediateValuesType; + +}; // class VCard + +/*! +** \brief Variables related to short term storage groups +*/ +template +class STSbyGroup : public Variable::IVariable, NextT, VCardSTSbyGroup> +{ +private: + enum VariableType + { + injection = 0, + withdrawal = 1, + level = 2 + }; + +public: + //! Type of the next static variable + typedef NextT NextType; + //! VCard + typedef VCardSTSbyGroup VCardType; + //! Ancestor + typedef Variable::IVariable, NextT, VCardType> AncestorType; + + //! List of expected results + typedef typename VCardType::ResultsType ResultsType; + + typedef VariableAccessor VariableAccessorType; + + enum + { + //! How many items have we got + count = 1 + NextT::count, + }; + + template + struct Statistics + { + enum + { + count + = ((VCardType::categoryDataLevel & CDataLevel && VCardType::categoryFileLevel & CFile) + ? (NextType::template Statistics::count + + VCardType::columnCount * ResultsType::count) + : NextType::template Statistics::count), + }; + }; + +public: + STSbyGroup() : pValuesForTheCurrentYear(nullptr) + { + } + + ~STSbyGroup() + { + for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++) + delete[] pValuesForTheCurrentYear[numSpace]; + delete[] pValuesForTheCurrentYear; + } + + void initializeFromArea(Data::Study* study, Data::Area* area) + { + // Get the number of years in parallel + pNbYearsParallel = study->maxNbYearsInParallel; + pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel]; + + // Building the vector of group names the clusters belong to. + groupNames_ = sortedUniqueGroups(area->shortTermStorage.storagesByIndex); + groupToNumbers_ = giveNumbersToGroups(groupNames_); + + nbColumns_ = groupNames_.size() * NB_COLS_PER_GROUP; + + if (nbColumns_) + { + AncestorType::pResults.resize(nbColumns_); + + for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++) + pValuesForTheCurrentYear[numSpace] + = new VCardType::IntermediateValuesDeepType[nbColumns_]; + + for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++) + for (unsigned int i = 0; i != nbColumns_; ++i) + pValuesForTheCurrentYear[numSpace][i].initializeFromStudy(*study); + + for (unsigned int i = 0; i != nbColumns_; ++i) + { + AncestorType::pResults[i].initializeFromStudy(*study); + AncestorType::pResults[i].reset(); + } + } + else + { + for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++) + { + pValuesForTheCurrentYear[numSpace] = nullptr; + } + + AncestorType::pResults.clear(); + } + // Next + NextType::initializeFromArea(study, area); + } + + size_t getMaxNumberColumns() const + { + return nbColumns_ * ResultsType::count; + } + + void yearBegin(unsigned int year, unsigned int numSpace) + { + // Reset the values for the current year + for (unsigned int i = 0; i != nbColumns_; ++i) + { + pValuesForTheCurrentYear[numSpace][i].reset(); + } + // Next variable + NextType::yearBegin(year, numSpace); + } + + void yearEnd(unsigned int year, unsigned int numSpace) + { + // Here we perform time-aggregations : + // --------------------------------- + // For a given MC year, from hourly results we compute daily, weekly, monthly and annual + // results by aggregation operations (averages or sums). + // Caution : + // - level results are stored in columns of which indices satisfy : col_index % 3 == 2. + // They are time-aggregated by means of averages + // - injection and withdrawal results are stored in columns of which indices + // satisfy : col_index % 3 != 2. + // They are time-aggregated by means of sums. + + for (unsigned int column = 0; column < nbColumns_; column++) + { + switch (column % NB_COLS_PER_GROUP) + { + case VariableType::level: + pValuesForTheCurrentYear[numSpace][column] + .computeAveragesForCurrentYearFromHourlyResults(); + break; + case VariableType::injection: + case VariableType::withdrawal: + pValuesForTheCurrentYear[numSpace][column].computeStatisticsForTheCurrentYear(); + break; + } + } + // Next variable + NextType::yearEnd(year, numSpace); + } + + void computeSummary(std::map& numSpaceToYear, + unsigned int nbYearsForCurrentSummary) + { + // Here we compute synthesis : + // for each interval of any time period results (hourly, daily, weekly, ...), + // we compute the average over all MC years : + // For instance : + // - we compute the average of the results of the first hour over all MC years + // - or we compute the average of the results of the n-th day over all MC years + for (unsigned int numSpace = 0; numSpace < nbYearsForCurrentSummary; ++numSpace) + { + VariableAccessorType::ComputeSummary( + pValuesForTheCurrentYear[numSpace], AncestorType::pResults, numSpaceToYear[numSpace]); + } + + // Next variable + NextType::computeSummary(numSpaceToYear, nbYearsForCurrentSummary); + } + + void hourBegin(unsigned int hourInTheYear) + { + NextType::hourBegin(hourInTheYear); + } + + void hourForEachArea(State& state, unsigned int numSpace) + { + using namespace Antares::Data::ShortTermStorage; + const auto& shortTermStorage = state.area->shortTermStorage; + + uint clusterIndex = 0; + for (const auto& cluster : shortTermStorage.storagesByIndex) + { + unsigned int groupNumber = groupToNumbers_[cluster.properties.groupName]; + const auto& result = state.hourlyResults->ShortTermStorage[state.hourInTheWeek]; + // Injection + pValuesForTheCurrentYear[numSpace][NB_COLS_PER_GROUP * groupNumber + + VariableType::injection][state.hourInTheYear] + += result.injection[clusterIndex]; + + // Withdrawal + pValuesForTheCurrentYear[numSpace][NB_COLS_PER_GROUP * groupNumber + + VariableType::withdrawal][state.hourInTheYear] + += result.withdrawal[clusterIndex]; + + // Levels + pValuesForTheCurrentYear[numSpace][NB_COLS_PER_GROUP * groupNumber + + VariableType::level][state.hourInTheYear] + += result.level[clusterIndex]; + + clusterIndex++; + } + + // Next variable + NextType::hourForEachArea(state, numSpace); + } + + inline void buildDigest(SurveyResults& results, int digestLevel, int dataLevel) const + { + // Ask to build the digest to the next variable + NextType::buildDigest(results, digestLevel, dataLevel); + } + + Antares::Memory::Stored::ConstReturnType retrieveRawHourlyValuesForCurrentYear( + unsigned int column, + unsigned int numSpace) const + { + return pValuesForTheCurrentYear[numSpace][column].hour; + } + + inline uint64_t memoryUsage() const + { + uint64_t r = (sizeof(IntermediateValues) * nbColumns_ + IntermediateValues::MemoryUsage()) + * pNbYearsParallel; + r += sizeof(double) * nbColumns_ * maxHoursInAYear * pNbYearsParallel; + r += AncestorType::memoryUsage(); + return r; + } + + std::string caption(unsigned int column) const + { + static const std::vector VAR_POSSIBLE_KINDS + = {"INJECTION", "WITHDRAWAL", "LEVEL"}; + const std::string& groupName = groupNames_[column / NB_COLS_PER_GROUP]; + const std::string& variableKind = VAR_POSSIBLE_KINDS[column % NB_COLS_PER_GROUP]; + return groupName + "_" + variableKind; + } + + std::string unit(unsigned int column) const + { + switch (column % NB_COLS_PER_GROUP) + { + case VariableType::level: + return "MWh"; + case VariableType::injection: + case VariableType::withdrawal: + return "MW"; + default: + return "error"; + } + } + + void localBuildAnnualSurveyReport(SurveyResults& results, + int fileLevel, + int precision, + unsigned int numSpace) const + { + // Initializing external pointer on current variable non applicable status + results.isCurrentVarNA = AncestorType::isNonApplicable; + + if (!AncestorType::isPrinted[0]) + return; + + for (unsigned int column = 0; column < nbColumns_; column++) + { + results.variableCaption = caption(column); + results.variableUnit = unit(column); + pValuesForTheCurrentYear[numSpace][column].template buildAnnualSurveyReport( + results, fileLevel, precision); + } + } + + void buildSurveyReport(SurveyResults& results, + int dataLevel, + int fileLevel, + int precision) const + { + // Building syntheses results + // ------------------------------ + if (!AncestorType::isPrinted[0]) + return; + + // And only if we match the current data level _and_ precision level + if ((dataLevel & VCardType::categoryDataLevel) && (fileLevel & VCardType::categoryFileLevel) + && (precision & VCardType::precision)) + { + results.isCurrentVarNA[0] = AncestorType::isNonApplicable[0]; + + for (unsigned int column = 0; column < nbColumns_; column++) + { + results.variableCaption = caption(column); + results.variableUnit = unit(column); + AncestorType::pResults[column].template buildSurveyReport( + results, AncestorType::pResults[column], dataLevel, fileLevel, precision); + } + } + + // Ask to the next item in the static list to export its results as well + NextType::buildSurveyReport(results, dataLevel, fileLevel, precision); + } + +private: + //! Intermediate values for each year + typename VCardType::IntermediateValuesType pValuesForTheCurrentYear; + size_t nbColumns_ = 0; + std::vector groupNames_; // Names of group containing the clusters of the area + std::map groupToNumbers_; // Gives to each group (of area) a number + const int NB_COLS_PER_GROUP = 3; // Injection + withdrawal + levels = 3 variables + unsigned int pNbYearsParallel; + +}; // class STSbyGroup + +} // End namespace Antares::Solver::Variable::Economy diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h index ef061493b5..1a46c130f1 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/all.h +++ b/src/solver/variable/include/antares/solver/variable/economy/all.h @@ -53,7 +53,6 @@ #include "overflow.h" #include "waterValue.h" #include "hydroCost.h" -#include "shortTermStorage.h" #include "unsupliedEnergy.h" #include "domesticUnsuppliedEnergy.h" #include "localMatchingRuleViolations.h" @@ -77,7 +76,7 @@ // By RES plant #include "productionByRenewablePlant.h" -// Short term storage output variables by cluster +#include "STSbyGroup.h" #include "STStorageInjectionByCluster.h" #include "STStorageWithdrawalByCluster.h" #include "STStorageLevelsByCluster.h" @@ -122,8 +121,7 @@ class Links; typedef // Prices OverallCost // Overall Cost (Op. Cost + Unsupplied Eng.) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> VariablesPerSetOfAreas; typedef BindingConstMarginCost< // Marginal cost for a binding constraint diff --git a/src/solver/variable/include/antares/solver/variable/economy/shortTermStorage.h b/src/solver/variable/include/antares/solver/variable/economy/shortTermStorage.h deleted file mode 100644 index 808b2f4dd4..0000000000 --- a/src/solver/variable/include/antares/solver/variable/economy/shortTermStorage.h +++ /dev/null @@ -1,293 +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 "antares/solver/variable/variable.h" -#include "antares/study/parts/short-term-storage/STStorageOutputCaptions.h" - -namespace Antares::Solver::Variable::Economy -{ -struct VCardShortTermStorage -{ - //! Caption - static std::string Caption() - { - return "ST storage"; - } - //! Unit - static std::string Unit() - { - return "MWh"; - } - - //! The short description of the variable - static std::string Description() - { - return "Value of all short term storage throughout all MC years"; - } - - //! The expecte results - typedef Results>>>> - ResultsType; - - //! The VCard to look for for calculating spatial aggregates - typedef VCardShortTermStorage VCardForSpatialAggregate; - - enum - { - //! Data Level - categoryDataLevel = Category::area, - //! File level (provided by the type of the results) - categoryFileLevel = ResultsType::categoryFile & (Category::id | Category::va), - //! Precision (views) - precision = Category::all, - //! Indentation (GUI) - nodeDepthForGUI = +0, - //! Decimal precision - decimal = 0, - //! Number of columns used by the variable (One ResultsType per column) - columnCount = 27, - //! The Spatial aggregation - spatialAggregate = Category::spatialAggregateSum, - spatialAggregateMode = Category::spatialAggregateEachYear, - spatialAggregatePostProcessing = 0, - //! Intermediate values - hasIntermediateValues = 1, - //! Can this variable be non applicable (0 : no, 1 : yes) - isPossiblyNonApplicable = 0, - }; - - typedef IntermediateValues IntermediateValuesBaseType[columnCount]; - typedef IntermediateValuesBaseType* IntermediateValuesType; - - typedef IntermediateValuesBaseType* IntermediateValuesTypeForSpatialAg; - - struct Multiple - { - static std::string Caption(const unsigned int indx) - { - return Antares::Data::ShortTermStorage::getVariableCaptionFromColumnIndex(indx); - } - - static std::string Unit(const unsigned int indx) - { - if (indx % 3 == 2) // Level - return "MWh"; - else // Injection, withdrawal - return "MW"; - } - }; -}; // class VCard - -template -class ShortTermStorageByGroup - : public Variable::IVariable, NextT, VCardShortTermStorage> -{ -public: - //! Type of the next static variable - typedef NextT NextType; - //! VCard - typedef VCardShortTermStorage VCardType; - //! Ancestor - typedef Variable::IVariable, NextT, VCardType> AncestorType; - - //! List of expected results - typedef typename VCardType::ResultsType ResultsType; - - typedef VariableAccessor VariableAccessorType; - - enum - { - //! How many items have we got - count = 1 + NextT::count, - }; - - template - struct Statistics - { - enum - { - count - = ((VCardType::categoryDataLevel & CDataLevel && VCardType::categoryFileLevel & CFile) - ? (NextType::template Statistics::count - + VCardType::columnCount * ResultsType::count) - : NextType::template Statistics::count), - }; - }; - -public: - ~ShortTermStorageByGroup() - { - delete[] pValuesForTheCurrentYear; - } - - void initializeFromStudy(Data::Study& study) - { - pNbYearsParallel = study.maxNbYearsInParallel; - - InitializeResultsFromStudy(AncestorType::pResults, study); - - pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel]; - for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; ++numSpace) - for (unsigned int i = 0; i != VCardType::columnCount; ++i) - pValuesForTheCurrentYear[numSpace][i].initializeFromStudy(study); - - // Next - NextType::initializeFromStudy(study); - } - - template - static void InitializeResultsFromStudy(R& results, Data::Study& study) - { - for (unsigned int i = 0; i != VCardType::columnCount; ++i) - { - results[i].initializeFromStudy(study); - results[i].reset(); - } - } - - void yearBegin(unsigned int year, unsigned int numSpace) - { - // Reset the values for the current year - for (unsigned int i = 0; i != VCardType::columnCount; ++i) - pValuesForTheCurrentYear[numSpace][i].reset(); - // Next variable - NextType::yearBegin(year, numSpace); - } - - void yearEnd(unsigned int year, unsigned int numSpace) - { - // Here we perform time-aggregations : - // --------------------------------- - // For a given MC year, from hourly results we compute daily, weekly, monthly and annual - // results by aggregation operations (averages or sums). - // Caution : - // - level results are stored in columns of which indices satisfy : col_index % 3 == 2. - // They are time-aggregated by means of averages - // - injection and withdrawal results are stored in columns of which indices - // satisfy : col_index % 3 != 2. - // They are time-aggregated by means of sums. - - for (unsigned int col_index = 0; col_index != VCardType::columnCount; ++col_index) - { - bool isAnInjectionColumn = (col_index % 3) == 0; - bool isAnWithdrawalColumn = (col_index % 3) == 1; - bool isALevelColumn = (col_index % 3) == 2; - - if (isALevelColumn) - pValuesForTheCurrentYear[numSpace][col_index].computeAveragesForCurrentYearFromHourlyResults(); - if (isAnInjectionColumn || isAnWithdrawalColumn) - pValuesForTheCurrentYear[numSpace][col_index].computeStatisticsForTheCurrentYear(); - } - - // Next variable - NextType::yearEnd(year, numSpace); - } - - void computeSummary(std::map& numSpaceToYear, - unsigned int nbYearsForCurrentSummary) - { - // Here we compute synthesis : - // for each interval of any time period results (hourly, daily, weekly, ...), - // we compute the average over all MC years : - // For instance : - // - we compute the average of the results of the first hour over all MC years - // - or we compute the average of the results of the n-th day over all MC years - for (unsigned int numSpace = 0; numSpace < nbYearsForCurrentSummary; ++numSpace) - { - VariableAccessorType::ComputeSummary(pValuesForTheCurrentYear[numSpace], - AncestorType::pResults, - numSpaceToYear[numSpace]); - } - - // Next variable - NextType::computeSummary(numSpaceToYear, nbYearsForCurrentSummary); - } - - void hourForEachArea(State& state, unsigned int numSpace) - { - using namespace Antares::Data::ShortTermStorage; - const auto& shortTermStorage = state.area->shortTermStorage; - - // Write the data for the current year - uint clusterIndex = 0; - for (const auto& cluster : shortTermStorage.storagesByIndex) - { - const uint group = groupIndex(cluster.properties.group); - // Injection - pValuesForTheCurrentYear[numSpace][3 * group][state.hourInTheYear] - += state.hourlyResults->ShortTermStorage[state.hourInTheWeek].injection[clusterIndex]; - - // Withdrawal - pValuesForTheCurrentYear[numSpace][3 * group + 1][state.hourInTheYear] - += state.hourlyResults->ShortTermStorage[state.hourInTheWeek].withdrawal[clusterIndex]; - - // Levels - pValuesForTheCurrentYear[numSpace][3 * group + 2][state.hourInTheYear] - += state.hourlyResults->ShortTermStorage[state.hourInTheWeek].level[clusterIndex]; - clusterIndex++; - } - - // Next item in the list - NextType::hourForEachArea(state, numSpace); - } - - Antares::Memory::Stored::ConstReturnType retrieveRawHourlyValuesForCurrentYear( - unsigned int column, - unsigned int numSpace) const - { - return pValuesForTheCurrentYear[numSpace][column].hour; - } - - void localBuildAnnualSurveyReport(SurveyResults& results, - int fileLevel, - int precision, - unsigned int numSpace) const - { - // The current variable is actually a multiple-variable. - results.isCurrentVarNA = AncestorType::isNonApplicable; - - for (uint i = 0; i != VCardType::columnCount; ++i) - { - if (AncestorType::isPrinted[i]) - { - // Write the data for the current year - results.variableCaption = VCardType::Multiple::Caption(i); - results.variableUnit = VCardType::Multiple::Unit(i); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( - results, fileLevel, precision); - } - results.isCurrentVarNA++; - } - } - -private: - //! Intermediate values for each year - typename VCardType::IntermediateValuesType pValuesForTheCurrentYear; - unsigned int pNbYearsParallel; - -}; // class ShortTermStorageByGroup - -} // namespace Antares::Solver::Variable::Economy diff --git a/src/tests/end-to-end/simple_study/simple-study.cpp b/src/tests/end-to-end/simple_study/simple-study.cpp index e34407c645..2a71bff01c 100644 --- a/src/tests/end-to-end/simple_study/simple-study.cpp +++ b/src/tests/end-to-end/simple_study/simple-study.cpp @@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE(error_on_wrong_hydro_data) BOOST_AUTO_TEST_SUITE_END() BOOST_FIXTURE_TEST_SUITE(ONE_AREA__ONE_STS_THERMAL_CLUSTER, StudyFixture) -BOOST_AUTO_TEST_CASE(sts_initial_level) +BOOST_AUTO_TEST_CASE(STS_initial_level_is_also_weekly_final_level) { using namespace Antares::Data::ShortTermStorage; setNumberMCyears(1); @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(sts_initial_level) props.reservoirCapacity = 100; props.efficiencyFactor = .9; props.initialLevel = .443; - props.group = Group::PSP_open; + props.groupName = std::string("Some STS group"); // Default values for series sts.series->fillDefaultSeriesIfEmpty(); @@ -349,8 +349,9 @@ BOOST_AUTO_TEST_CASE(sts_initial_level) simulation->create(); simulation->run(); + unsigned int groupNb = 0; // Used to reach the first group of STS results OutputRetriever output(simulation->rawSimu()); - BOOST_TEST(output.STSLevel_PSP_Open(area).hour(167) == props.initialLevel * props.reservoirCapacity.value(), tt::tolerance(0.001)); + BOOST_TEST(output.levelForSTSgroup(area, groupNb).hour(167) == props.initialLevel * props.reservoirCapacity.value(), tt::tolerance(0.001)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/end-to-end/utils/utils.cpp index 970e56d085..b9c2f00500 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/end-to-end/utils/utils.cpp @@ -113,12 +113,11 @@ averageResults OutputRetriever::overallCost(Area* area) return averageResults(result->avgdata); } -averageResults OutputRetriever::STSLevel_PSP_Open(Area* area) +averageResults OutputRetriever::levelForSTSgroup(Area* area, unsigned int groupNb) { - auto result = retrieveAreaResults(area); - // PSP_open / Level, see STStorageOutputCaptions.cpp - const unsigned int PSP_Open_Level = 2; - return result[area->index][PSP_Open_Level].avgdata; + auto result = retrieveAreaResults(area); + unsigned int levelIndex = groupNb * 3 + 2; + return result[area->index][levelIndex].avgdata; } averageResults OutputRetriever::load(Area* area) diff --git a/src/tests/end-to-end/utils/utils.h b/src/tests/end-to-end/utils/utils.h index a0f8f2f4fb..a2df7b1b50 100644 --- a/src/tests/end-to-end/utils/utils.h +++ b/src/tests/end-to-end/utils/utils.h @@ -88,7 +88,7 @@ class OutputRetriever public: OutputRetriever(ISimulation& simulation) : simulation_(simulation) {} averageResults overallCost(Area* area); - averageResults STSLevel_PSP_Open(Area* area); + averageResults levelForSTSgroup(Area* area, unsigned int groupNb); averageResults load(Area* area); averageResults hydroStorage(Area* area); averageResults flow(AreaLink* link); diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index d55edbf87c..1fb506b39d 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -150,6 +150,7 @@ int main(int argc, char *argv[]) auto study = std::make_shared(true); Data::StudyLoadOptions studyOptions; studyOptions.prepareOutput = true; + studyOptions.linksLoadTSGen = true; if (!study->loadFromFolder(settings.studyFolder, studyOptions)) { diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp index 9aaa24761d..4c39002613 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.cpp @@ -38,13 +38,13 @@ namespace Renderer ** ** MTBF: Mean Time Between Failure */ -static double MTBFForFO(Antares::Data::PreproThermal* preproThermal, int y) +static double MTBFForFO(Antares::Data::PreproAvailability* preproThermal, int y) { if (y >= 0 and y < DAYS_PER_YEAR and preproThermal) { auto& data = preproThermal->data; - double rate = data[Antares::Data::PreproThermal::foRate][y]; - double duration = data[Antares::Data::PreproThermal::foDuration][y]; + double rate = data[Antares::Data::PreproAvailability::foRate][y]; + double duration = data[Antares::Data::PreproAvailability::foDuration][y]; if (Math::Zero(rate)) return std::numeric_limits::infinity(); @@ -60,13 +60,13 @@ static double MTBFForFO(Antares::Data::PreproThermal* preproThermal, int y) ** ** MTBF: Mean Time Between Failure */ -static double MTBFForPO(Antares::Data::PreproThermal* preproThermal, int y) +static double MTBFForPO(Antares::Data::PreproAvailability* preproThermal, int y) { if (y >= 0 and y < DAYS_PER_YEAR and preproThermal) { auto& data = preproThermal->data; - double rate = data[Antares::Data::PreproThermal::poRate][y]; - double duration = data[Antares::Data::PreproThermal::poDuration][y]; + double rate = data[Antares::Data::PreproAvailability::poRate][y]; + double duration = data[Antares::Data::PreproAvailability::poDuration][y]; if (Math::Zero(rate)) return std::numeric_limits::infinity(); @@ -79,7 +79,7 @@ static double MTBFForPO(Antares::Data::PreproThermal* preproThermal, int y) ThermalClusterPrepro::ThermalClusterPrepro(wxWindow* control, Toolbox::InputSelector::ThermalCluster* notifier) : - MatrixAncestorType(control), pPreproThermal(nullptr) + MatrixAncestorType(control) { if (notifier) notifier->onThermalClusterChanged.connect( @@ -147,14 +147,14 @@ double ThermalClusterPrepro::cellNumericValue(int x, int y) const { if (x > 5) { - if (y >= 0 and y < DAYS_PER_YEAR and pPreproThermal) + if (y >= 0 and y < DAYS_PER_YEAR and pPreproAvailability) { switch (x) { case 6: - return MTBFForFO(pPreproThermal, y); + return MTBFForFO(pPreproAvailability, y); case 7: - return MTBFForPO(pPreproThermal, y); + return MTBFForPO(pPreproAvailability, y); } } return 0.; @@ -183,8 +183,8 @@ bool ThermalClusterPrepro::cellValue(int x, int y, const String& value) void ThermalClusterPrepro::internalThermalClusterChanged(Antares::Data::ThermalCluster* cluster) { pCluster = cluster; - pPreproThermal = (cluster) ? cluster->prepro : nullptr; - MatrixAncestorType::matrix((pPreproThermal) ? &pPreproThermal->data : nullptr); + pPreproAvailability = (cluster) ? cluster->prepro : nullptr; + MatrixAncestorType::matrix((pPreproAvailability) ? &pPreproAvailability->data : nullptr); onRefresh(); } @@ -202,14 +202,14 @@ IRenderer::CellStyle ThermalClusterPrepro::cellStyle(int col, int row) const // MTBF FO if (col == 6) { - double mtbf = MTBFForFO(pPreproThermal, row); + double mtbf = MTBFForFO(pPreproAvailability, row); if (Math::Zero(mtbf)) return IRenderer::cellStyleWarning; } // MTBF PO if (col == 7) { - double mtbf = MTBFForPO(pPreproThermal, row); + double mtbf = MTBFForPO(pPreproAvailability, row); if (Math::Zero(mtbf)) return IRenderer::cellStyleWarning; } diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h index 90f372eea7..60dd2231f0 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermalprepro.h @@ -104,7 +104,7 @@ class ThermalClusterPrepro : public Renderer::Matrix<> virtual void onStudyClosed() override; private: - Antares::Data::PreproThermal* pPreproThermal; + Antares::Data::PreproAvailability* pPreproAvailability = nullptr; Antares::Data::ThermalCluster* pCluster; }; // class ThermalClusterPrepro diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/connection.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/connection.cpp index 1ec1f3d6fe..69d8cb6a42 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/connection.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/connection.cpp @@ -24,6 +24,9 @@ #include #include +//! The minimal allowed value for hurdle costs when not null +#define LINK_MINIMAL_HURDLE_COSTS_NOT_NULL 0.005 + using namespace Yuni; namespace Antares diff --git a/src/ui/simulator/windows/inspector/accumulator.hxx b/src/ui/simulator/windows/inspector/accumulator.hxx index a3ea93c849..778d0fe2ce 100644 --- a/src/ui/simulator/windows/inspector/accumulator.hxx +++ b/src/ui/simulator/windows/inspector/accumulator.hxx @@ -1048,7 +1048,7 @@ struct PClusterLawForced } static wxString ConvertToString(const Type v) { - return (v < thermalLawCount) ? thermalLaws[v] : nullptr; + return (v < LawCount) ? Laws[v] : nullptr; } }; @@ -1061,7 +1061,7 @@ struct PClusterLawPlanned } static wxString ConvertToString(const Type v) { - return (v < thermalLawCount) ? thermalLaws[v] : nullptr; + return (v < LawCount) ? Laws[v] : nullptr; } }; diff --git a/src/ui/simulator/windows/inspector/constants.cpp b/src/ui/simulator/windows/inspector/constants.cpp index d652287bcc..95e05b83b5 100644 --- a/src/ui/simulator/windows/inspector/constants.cpp +++ b/src/ui/simulator/windows/inspector/constants.cpp @@ -235,8 +235,8 @@ const unsigned int renewableTSModeCount = 2; const wxChar* const renewableTSMode[] = {wxT("power generation"), wxT("production factor"), nullptr}; -const unsigned int thermalLawCount = 2; -const wxChar* const thermalLaws[] = {wxT("uniform"), wxT("geometric"), nullptr}; +const unsigned int LawCount = 2; +const wxChar* const Laws[] = {wxT("uniform"), wxT("geometric"), nullptr}; const unsigned int costgenerationCount = 2; const wxChar* const costgeneration[] = {wxT("Set manually"), wxT("Use cost timeseries"), nullptr}; diff --git a/src/ui/simulator/windows/inspector/constants.h b/src/ui/simulator/windows/inspector/constants.h index be7b0e23c4..90b996098f 100644 --- a/src/ui/simulator/windows/inspector/constants.h +++ b/src/ui/simulator/windows/inspector/constants.h @@ -36,8 +36,8 @@ extern const unsigned int arrayClusterGroupCount; extern const wxChar* const arrayClusterGroup[]; // Thermal laws -extern const unsigned int thermalLawCount; -extern const wxChar* const thermalLaws[]; +extern const unsigned int LawCount; +extern const wxChar* const Laws[]; // Thermal cost generation extern const unsigned int costgenerationCount; diff --git a/src/ui/simulator/windows/inspector/frame.cpp b/src/ui/simulator/windows/inspector/frame.cpp index e2a4770101..da6e46946a 100644 --- a/src/ui/simulator/windows/inspector/frame.cpp +++ b/src/ui/simulator/windows/inspector/frame.cpp @@ -510,8 +510,8 @@ Frame::Frame(wxWindow* parent, bool allowAnyObject) : pPGThClusterDoGenerateTS = P_ENUM("Generate timeseries", "cluster.gen-ts", localGenTS); pPGThClusterVolatilityForced = P_FLOAT("Volatility (forced)", "cluster.forcedVolatility"); pPGThClusterVolatilityPlanned = P_FLOAT("Volatility (planned)", "cluster.plannedVolatility"); - pPGThClusterLawForced = P_ENUM("Law (forced)", "cluster.forcedlaw", thermalLaws); - pPGThClusterLawPlanned = P_ENUM("Law (planned)", "cluster.plannedlaw", thermalLaws); + pPGThClusterLawForced = P_ENUM("Law (forced)", "cluster.forcedlaw", Laws); + pPGThClusterLawPlanned = P_ENUM("Law (planned)", "cluster.plannedlaw", Laws); // --- RENEWABLE CLUSTERS --- pPGRnClusterSeparator = Group(pg, wxEmptyString, wxEmptyString); diff --git a/src/ui/simulator/windows/inspector/property.update.cpp b/src/ui/simulator/windows/inspector/property.update.cpp index 06e7c619bb..1c1879dfae 100644 --- a/src/ui/simulator/windows/inspector/property.update.cpp +++ b/src/ui/simulator/windows/inspector/property.update.cpp @@ -977,15 +977,15 @@ bool InspectorGrid::onPropertyChanging_ThermalCluster(wxPGProperty*, if (name == "cluster.forcedlaw") { long index = value.GetLong(); - Data::ThermalLaw law = Data::thermalLawUniform; + Data::StatisticalLaw law = Data::LawUniform; switch (index) { case 0: - law = Data::thermalLawUniform; + law = Data::LawUniform; break; case 1: - law = Data::thermalLawGeometric; + law = Data::LawGeometric; break; default: return false; @@ -998,15 +998,15 @@ bool InspectorGrid::onPropertyChanging_ThermalCluster(wxPGProperty*, if (name == "cluster.plannedlaw") { long index = value.GetLong(); - Data::ThermalLaw law = Data::thermalLawUniform; + Data::StatisticalLaw law = Data::LawUniform; switch (index) { case 0: - law = Data::thermalLawUniform; + law = Data::LawUniform; break; case 1: - law = Data::thermalLawGeometric; + law = Data::LawGeometric; break; default: return false; From b71152840a20ada4bf32cac23ffc5de339d5b4d1 Mon Sep 17 00:00:00 2001 From: Florian OMNES Date: Tue, 9 Apr 2024 17:57:42 +0200 Subject: [PATCH 075/101] Code smells --- src/libs/antares/study/area/links.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 8954a36f5d..e2c31f4e29 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -518,16 +518,16 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const return handleKey(link, key, value) || handleTSGenKey(link, key, value); } -[[ noreturn ]] -void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) +[[noreturn]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) { logs.error() << "Link (" << link.from->name << "/" << link.with->name << "): Invalid values (" << msg << ") for hour " << hour; throw Antares::Error::ReadingStudy(); } -[[ noreturn ]] -void logLinkDataCheckErrorDirectIndirect(const AreaLink& link, uint direct, uint indirect) +[[noreturn]] void logLinkDataCheckErrorDirectIndirect(const AreaLink& link, + uint direct, + uint indirect) { logs.error() << "Link (" << link.from->name << "/" << link.with->name << "): Found " << direct << " direct TS " @@ -594,7 +594,6 @@ bool AreaLinksLoadFromFolder(const Study& study, if (nbDirectTS != nbIndirectTS) { logLinkDataCheckErrorDirectIndirect(link, nbDirectTS, nbIndirectTS); - return false; } auto& directHurdlesCost = link.parameters[fhlHurdlesCostDirect]; @@ -614,12 +613,10 @@ bool AreaLinksLoadFromFolder(const Study& study, if (directCapacities[h] < 0.) { logLinkDataCheckError(link, "direct capacity < 0", h); - return false; } if (directCapacities[h] < loopFlow[h]) { logLinkDataCheckError(link, "direct capacity < loop flow", h); - return false; } } @@ -629,12 +626,10 @@ bool AreaLinksLoadFromFolder(const Study& study, if (indirectCapacities[h] < 0.) { logLinkDataCheckError(link, "indirect capacitity < 0", h); - return false; } if (indirectCapacities[h] + loopFlow[h] < 0) { logLinkDataCheckError(link, "indirect capacity + loop flow < 0", h); - return false; } } } @@ -645,7 +640,6 @@ bool AreaLinksLoadFromFolder(const Study& study, { logLinkDataCheckError( link, "hurdle costs direct + hurdle cost indirect < 0", h); - return false; } } @@ -655,7 +649,6 @@ bool AreaLinksLoadFromFolder(const Study& study, if (PShiftPlus[h] < PShiftMinus[h]) { logLinkDataCheckError(link, "phase shift plus < phase shift minus", h); - return false; } } } From c9b34ef67f7b209f4a2941ff3357fdd3ff685c42 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 10 Apr 2024 10:23:43 +0200 Subject: [PATCH 076/101] Fix arg name linksToGen --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 1fb506b39d..ba13258a55 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -99,10 +99,10 @@ std::vector getClustersToGen(Data::AreaList& areas, } TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, - const std::string& clustersToGen) + const std::string& linksToGen) { TSGenerator::listOfLinks links; - const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); + const auto ids = splitStringIntoPairs(linksToGen, ';', '.'); for (const auto& [areaFromID, areaWithID] : ids) { From cc0f30a7dfc6bd4776ce3737961621451c252f0d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 10 Apr 2024 10:47:05 +0200 Subject: [PATCH 077/101] Remove prepro.hxx, few fix --- src/solver/ts-generator/CMakeLists.txt | 1 - .../antares/solver/ts-generator/prepro.h | 2 -- .../antares/solver/ts-generator/prepro.hxx | 36 ------------------- src/solver/ts-generator/prepro.cpp | 20 ++++++----- 4 files changed, 11 insertions(+), 48 deletions(-) delete mode 100644 src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx diff --git a/src/solver/ts-generator/CMakeLists.txt b/src/solver/ts-generator/CMakeLists.txt index 5ad6672021..f2ef1559a9 100644 --- a/src/solver/ts-generator/CMakeLists.txt +++ b/src/solver/ts-generator/CMakeLists.txt @@ -25,7 +25,6 @@ set(SRC_XCAST prepro.cpp include/antares/solver/ts-generator/prepro.h - include/antares/solver/ts-generator/prepro.hxx xcast/studydata.cpp xcast/gamma-euler.cpp xcast/gamma-inc.cpp diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index 564c6d803e..c08b2d4ab6 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -133,6 +133,4 @@ struct LinkTsGeneration }; } // namespace Antares::Data -#include "prepro.hxx" - #endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx deleted file mode 100644 index 966e9d14f3..0000000000 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.hxx +++ /dev/null @@ -1,36 +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 . - */ -#ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ -#define __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ - -namespace Antares -{ -namespace Data -{ -inline uint64_t PreproAvailability::memoryUsage() const -{ - return sizeof(PreproAvailability); -} - -} // namespace Data -} // namespace Antares - -#endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_HXX__ diff --git a/src/solver/ts-generator/prepro.cpp b/src/solver/ts-generator/prepro.cpp index 898da4f6b5..920e9f4a2b 100644 --- a/src/solver/ts-generator/prepro.cpp +++ b/src/solver/ts-generator/prepro.cpp @@ -59,7 +59,6 @@ bool PreproAvailability::saveToFolder(const AnyString& folder) const bool PreproAvailability::loadFromFolder(Study& study, const AnyString& folder) { - bool ret = true; auto& buffer = study.bufferLoadingTS; buffer.clear() << folder << SEP << "data.txt"; @@ -154,6 +153,11 @@ void PreproAvailability::markAsModified() const data.markAsModified(); } +uint64_t PreproAvailability::memoryUsage() const +{ + return sizeof(PreproAvailability); +} + void PreproAvailability::reset() { data.reset(preproAvailabilityMax, DAYS_PER_YEAR, true); @@ -174,7 +178,8 @@ bool PreproAvailability::normalizeAndCheckNPO() auto& columnNPOMax = data[npoMax]; auto& columnNPOMin = data[npoMin]; // errors management - uint errors = 0, maxErrors = 10; + uint errors = 0; + uint maxErrors = 10; // Flag to determine whether the column NPO max has been normalized or not bool normalized = false; @@ -187,14 +192,11 @@ bool PreproAvailability::normalizeAndCheckNPO() normalized = true; } - if (columnNPOMin[y] > columnNPOMax[y]) + if (columnNPOMin[y] > columnNPOMax[y] && ++errors < maxErrors) { - if (++errors < maxErrors) - { - logs.error() << id << ": NPO min can not be greater than NPO max (hour: " << (y + 1) - << ", npo-min: " << columnNPOMin[y] << ", npo-max: " << columnNPOMax[y] - << ')'; - } + logs.error() << id << ": NPO min can not be greater than NPO max (hour: " << (y + 1) + << ", npo-min: " << columnNPOMin[y] << ", npo-max: " << columnNPOMax[y] + << ')'; } } From 269769aa62dea3529f863a5ca152eb5ea833799d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 10 Apr 2024 10:57:23 +0200 Subject: [PATCH 078/101] Default value for tsGenLink struct --- .../include/antares/solver/ts-generator/prepro.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index c08b2d4ab6..03d354f51a 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -116,14 +116,14 @@ class PreproAvailability struct LinkTsGeneration { - unsigned unitCount; - double nominalCapacity; + unsigned unitCount = 0; + double nominalCapacity = 0; - double forcedVolatility; - double plannedVolatility; + double forcedVolatility = 0.; + double plannedVolatility = 0.; - Data::StatisticalLaw forcedLaw; - Data::StatisticalLaw plannedLaw; + Data::StatisticalLaw forcedLaw = LawUniform; + Data::StatisticalLaw plannedLaw = LawUniform; std::unique_ptr prepro; From d7edcb6ad39ada2f778d1020d1c5d78a4fff2103 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 10 Apr 2024 11:00:15 +0200 Subject: [PATCH 079/101] Remove unused member study from generator class --- src/solver/ts-generator/availability.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 902fab314c..6fae6ffaa6 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -74,10 +74,9 @@ class GeneratorTempData final public: explicit GeneratorTempData(Data::Study&, unsigned); - void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster); + void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const; private: - Data::Study& study; bool derated; uint nbOfSeriesToGen_; @@ -97,7 +96,6 @@ class GeneratorTempData final }; GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : - study(study), derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(study.runtime->random[Data::seedTsGenThermal]) @@ -178,7 +176,7 @@ int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, return 0; } -void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) +void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const { if (!cluster.prepro) { @@ -196,7 +194,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat const auto& preproData = *(cluster.prepro); - int AUN = (int)cluster.unitCount; + int AUN = cluster.unitCount; auto& FOD = preproData.data[Data::PreproAvailability::foDuration]; From 5a5893e85c58ea2541b2b0a2af86cfc6ada771d8 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 16 Apr 2024 15:14:46 +0200 Subject: [PATCH 080/101] rename to tsConfigData --- src/solver/ts-generator/availability.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 6fae6ffaa6..6814833a23 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -606,8 +606,8 @@ bool generateThermalTimeSeries(Data::Study& study, // TODO VP: parallel for (auto* cluster : clusters) { - AvailabilityTSGeneratorData clusterInterface(cluster); - generator.generateTS(*cluster->parentArea, clusterInterface); + AvailabilityTSGeneratorData tsConfigData(cluster); + generator.generateTS(*cluster->parentArea, tsConfigData); if (archive) // compatibilty with in memory { @@ -644,9 +644,9 @@ bool generateLinkTimeSeries(Data::Study& study, logs.error() << "Missing data for link " << link->from->id << "/" << link->with->id; return false; } - AvailabilityTSGeneratorData linkInterface(tsGenStruct, ts, link->with->name); + AvailabilityTSGeneratorData tsConfigData(tsGenStruct, ts, link->with->name); - generator.generateTS(*link->from, linkInterface); + generator.generateTS(*link->from, tsConfigData); std::string capacityType = direction == linkDirection::direct ? "_direct" : "_indirect"; std::string filePath From b4b807d39bdf7ffd4f049fe365177281bdb42b41 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 16 Apr 2024 16:18:47 +0200 Subject: [PATCH 081/101] use matrix instead of timeseries object --- src/solver/ts-generator/availability.cpp | 12 ++++++------ .../include/antares/solver/ts-generator/generator.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 6814833a23..9810537760 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -45,15 +45,15 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* s forcedLaw(source->forcedLaw), plannedLaw(source->plannedLaw), prepro(source->prepro), - series(source->series), + series(source->series.timeSeries), modulationCapacity(source->modulation[Data::thermalModulationCapacity]), name(source->name()) { } AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, - Data::TimeSeries& capacity, - const std::string& areaDestName) : + Data::TimeSeries& capacity, + const std::string& areaDestName) : unitCount(source.unitCount), nominalCapacity(source.nominalCapacity), forcedVolatility(source.forcedVolatility), @@ -61,7 +61,7 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& forcedLaw(source.forcedLaw), plannedLaw(source.plannedLaw), prepro(source.prepro.get()), - series(capacity), + series(capacity.timeSeries), modulationCapacity(source.modulationCapacity[0]), name(areaDestName) { @@ -307,7 +307,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat uint hour = 0; if (tsIndex > 1) - dstSeries = cluster.series.timeSeries[tsIndex - 2]; + dstSeries = cluster.series[tsIndex - 2]; for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) { @@ -546,7 +546,7 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat } if (derated) - cluster.series.timeSeries.averageTimeseries(); + cluster.series.averageTimeseries(); } } // namespace diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 32cc053f1b..7446ef2bc0 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -50,7 +50,7 @@ class AvailabilityTSGeneratorData Data::PreproAvailability* prepro; - Data::TimeSeries& series; + Matrix<>& series; Matrix<>::ColumnType& modulationCapacity; From 86601ef2f51f151a81c998b75c608cc7bd823372 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 17 Apr 2024 10:25:32 +0200 Subject: [PATCH 082/101] move spinning to solver.hxx --- .../simulation/include/antares/solver/simulation/solver.hxx | 4 ++++ src/solver/ts-generator/availability.cpp | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index 0dac0489b9..c536302581 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -494,6 +494,10 @@ void ISimulation::regenerateTimeSeries(uint year) "mc-" + std::to_string(year); #undef SEP generateThermalTimeSeries(study, clusters, pResultWriter, savePath); + + // apply the spinning if we generated some in memory clusters + for (auto* cluster : clusters) + cluster->calculationOfSpinning(); } timer.stop(); diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 9810537760..f0dc2cd324 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -615,8 +615,6 @@ bool generateThermalTimeSeries(Data::Study& study, = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; writeResultsToDisk(study, writer, cluster->series.timeSeries, filePath); } - - cluster->calculationOfSpinning(); } return true; From f1c9caa4c9e9f65ba10eede948cef8c7f3f6ef77 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 13 May 2024 15:22:51 +0200 Subject: [PATCH 083/101] checkout clang format and script from develop --- src/.clang-format | 218 ++++++++++++++++++++++++++++++++++++++------- src/format-code.sh | 4 +- 2 files changed, 189 insertions(+), 33 deletions(-) diff --git a/src/.clang-format b/src/.clang-format index d6263eff26..0db7cae595 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -50,16 +50,25 @@ AccessModifierOffset: -4 # argument2) AlignAfterOpenBracket: Align +# If not None, when using initialization for an array of structs aligns the fields into columns. +# Possible values: Left, Right, None +AlignArrayOfStructures: None + # If true, aligns consecutive assignments # -> false: since it can be strange when types with different length are near # each other AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false + # If true, aligns consecutive declarations # -> false: since it can be strange when types with different length are near # each other AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: false + + # Options for aligning backslashes in escaped newlines # -> Align: escaped newlines as far left as possible # #define A \ @@ -82,6 +91,9 @@ AlignOperands: true # double* c // Comment AlignTrailingComments: true +# We favor breaking between arguments +AllowAllArgumentsOnNextLine: false + # If the function declaration doesn’t fit on a line, allow putting all # parameters of a function declaration onto the next line even if # BinPackParameters is false. @@ -93,10 +105,15 @@ AlignTrailingComments: true # int e); AllowAllParametersOfDeclarationOnNextLine: false +AllowBreakBeforeNoexceptSpecifier: Never + # If true, allows contracting simple braced statements to a single line # -> false: Not allowed for the sake of absolute clarity AllowShortBlocksOnASingleLine: false +# No short instructions on single line +AllowShortEnumsOnASingleLine: false + # If true, short case labels will be contracted to a single line # -> false: Not allowed, only one instruction per line AllowShortCaseLabelsOnASingleLine: false @@ -109,17 +126,18 @@ AllowShortFunctionsOnASingleLine: false # -> false: Not allowed AllowShortIfStatementsOnASingleLine: false +# Exception to our "no single line" rule, +# to allow for lambda-based one liners: +# std::sort(vec.begin(), vec.end(), [](auto v) { return v.a < v.b; }); +AllowShortLambdasOnASingleLine: All + # If true, while (true) continue; can be put on a single line # -> false: Not allowed AllowShortLoopsOnASingleLine: false -# DEPRECATED -# The function definition return type breaking style to use -# -> None: Break after return type automatically -AlwaysBreakAfterDefinitionReturnType: None - # The function declaration return type breaking style to use -# -> None: Break after return type automatically +# -> None: Break after return type automatically, +# according to penalty system AlwaysBreakAfterReturnType: None # If true, always break before multiline string literals @@ -149,8 +167,6 @@ BinPackParameters: false # the same way: break before all braces # See BreakBeforeBraces -# BreakAfterJavaFieldAnnotations: ignored for C++ - # The way to wrap binary operators when expression are too long to hold on a # single line # -> All: Break before operators, so that they can easily be identified at the @@ -191,7 +207,7 @@ BreakStringLiterals: true # Maximum number of characters per line # -> 100: Historically 80 for C++, but quite deprecated today; it is dicutable -# but 100 seemed to be more adequat in our case +# but 100 seemed to be more adequat in our case. ColumnLimit: 100 # A regular expression that describes comments with special meaning, which @@ -204,16 +220,10 @@ CommentPragmas: '^ IWYU pragma:' # -> false: one line per namespace, ugly otherwise CompactNamespaces: false -# If the constructor initializers don’t fit on a line, put each initializer on -# its own line -# -> true -ConstructorInitializerAllOnOneLineOrOnePerLine: true - # The number of characters to use for indentation of constructor initializer # lists -# -> 1 to highlight the brace at the end of the initialization and emphasize -# that it is inside the constructor, but before any instruction -ConstructorInitializerIndentWidth: 1 +# -> 4 Same indentation level as the block instructions +ConstructorInitializerIndentWidth: 4 # Indent width for line continuations # -> 2: So that it is differenciable from other identations @@ -234,41 +244,120 @@ DerivePointerAlignment: false # -> false DisableFormat: false +# No line between access modifier and code +EmptyLineAfterAccessModifier: Never + +# Always one line before public/private/protected +# to clearly separate the following block +EmptyLineBeforeAccessModifier: Always + # If true, clang-format detects whether function calls and definitions are # formatted with one parameter per line # -> false: allways use the convention specified in this file ExperimentalAutoDetectBinPacking: false -# A vector of macros that should be interpreted as foreach loops instead of as -# function calls. -# -> no macro -ForEachMacros: [] - # If true, clang-format adds missing namespace end comments and fixes invalid # existing ones # -> true: add a lot of clarity to these endless braces at the end of a file FixNamespaceComments: true +# A vector of macros that should be interpreted as foreach loops instead of as +# function calls. +# -> no macro +ForEachMacros: [ ] + +# Use include blocks +IncludeBlocks: Regroup + +# First main header, then std libs, then boost, then yuni, then antares +IncludeCategories: + # antares headers with " + - Regex: '^"antares/.*' + Priority: 10 + SortPriority: 10 + CaseSensitive: false + # antares headers with < + - Regex: '^|")' + Priority: 5 + SortPriority: 4 + # yuni headers + - Regex: '^(<|")yuni/.*' + Priority: 5 + CaseSensitive: false + # boost + - Regex: '^(<|")boost/.*' + Priority: 2 + # stdlib + - Regex: '^<.*' + Priority: 1 + CaseSensitive: false + # everything else (targets to be internal lib headers) + - Regex: '.*' + Priority: 15 + CaseSensitive: false + +# Definition of main header of a cpp file +IncludeIsMainRegex: '([-_](test))?$' +IncludeIsMainSourceRegex: '' + + +# public/private/protected not indented +IndentAccessModifiers: false + +IndentCaseBlocks: false + # Indent case labels one level from the switch statement # -> false IndentCaseLabels: false +IndentExternBlock: NoIndent + +IndentGotoLabels: false + # The preprocessor directive indenting style to use # -> None: never indent preprocessor directives IndentPPDirectives: None +IndentRequiresClause: false + # The number of columns to use for indentation # -> 4: Good compromise between visible and limiting additional spaces IndentWidth: 4 # Indent if a function definition or declaration is wrapped after the type -# -> true: to be clear on the fact that this is not another function declaration -IndentWrappedFunctionNames: true +# -> false: so that function name remains at indentation level +IndentWrappedFunctionNames: false + +# We always use braces to identify blocks, even one-lines +InsertBraces: true + +# This is standard +InsertNewlineAtEOF: true + +# Leave integer literals as they are +IntegerLiteralSeparator: + Binary: 0 + Decimal: 0 + Hex: 0 + +# Remove unnecessary empty lines +KeepEmptyLinesAtEOF: false # If true, the empty line at the start of blocks is kept # -> false: this is useless KeepEmptyLinesAtTheStartOfBlocks: false +# Indent lambda according to its signature, to make it clear it relates to it +LambdaBodyIndentation: Signature + +# Ensure consistent use of unix like EOF. +LineEnding: LF + # The maximum number of consecutive empty lines to keep # -> 1: Use comments to differenciate important parts of a big portion of code # (or split it into functions for instance) rather than a big block of @@ -279,27 +368,66 @@ MaxEmptyLinesToKeep: 1 # -> None: Do not add an indentation level NamespaceIndentation: None + +# Each constructor initializer on its own line. +PackConstructorInitializers: Never + +# Penalties are used to decide where to break long lines, +# when multiple alternatives are possible. +# We use a "high" cost for breaking before assignment and first parameter, +# to favor breaking between function parameters and chained methods. +PenaltyBreakAssignment: 1000 +PenaltyBreakBeforeFirstCallParameter: 100 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +# Important to allow method chaining, +# and not breaking assignment or after function parenthesis +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 200 + # Pointer and reference alignment style # -> Left: the type of a variable is at its left, and the * or the & are part of # this type PointerAlignment: Left +# const goes before type +QualifierAlignment: Left + +# & and * go with type, not variable name +ReferenceAlignment: Left + # If true, clang-format will attempt to re-flow comments # -> true: because clang-format does it better than you ReflowComments: true +# No unnecessary ; +RemoveSemicolon: true + +# Concept-related options to be discussed at some point +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope + +# Always have empty lines between function and classes definitions +SeparateDefinitionBlocks: Always + # If true, clang-format will sort #includes # -> false: see coding guidelines -SortIncludes: false +SortIncludes: true # If true, clang-format will sort using declarations -# -> false -SortUsingDeclarations: false +# -> LexicographicNumeric to take into account sub-namespaces +SortUsingDeclarations: LexicographicNumeric # If true, a space is inserted after C style casts # -> false SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false + # If true, a space will be inserted after the ‘template’ keyword # -> false SpaceAfterTemplateKeyword: false @@ -308,10 +436,31 @@ SpaceAfterTemplateKeyword: false # -> true SpaceBeforeAssignmentOperators: true +# "case 1: break;" instead of "case 1 : break;" +SpaceBeforeCaseColon: false + +# Foo foo{ bar }; +SpaceBeforeCpp11BracedList: false + +# Foo::Foo(): a(a) {} +SpaceBeforeCtorInitializerColon: false + +# class Foo: Bar {} +SpaceBeforeInheritanceColon: false + # Defines in which cases to put a space before opening parentheses # -> ControlStatements: Before if/while/for statements SpaceBeforeParens: ControlStatements +# for (auto v: values) {} +SpaceBeforeRangeBasedForLoopColon: false + +# int a[5] +SpaceBeforeSquareBrackets: false + +# void f() {} +SpaceInEmptyBlock: false + # If true, spaces may be inserted into () # -> false SpaceInEmptyParentheses: false @@ -334,9 +483,17 @@ SpacesInCStyleCastParentheses: false # -> false SpacesInContainerLiterals: false +# Minimum one space to separate the start of the comment +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 + # If true, spaces will be inserted after ( and before ) # -> false -SpacesInParentheses: false +# SpacesInParentheses: false + +# Keep previous behaviour with SpacesInParentheses: false +SpacesInParens: Never # If true, spaces will be inserted after [ and before ]. Lambdas or unspecified # size array declarations will not be affected @@ -345,8 +502,7 @@ SpacesInSquareBrackets: false # Format compatible with this standard, e.g. use A > instead of A> # for LS_Cpp03 -# Cpp11 -Standard: Cpp11 +Standard: c++20 # The number of columns used for tab stops # Note: this property is not used since tabs are forbidden (see UseTab) @@ -355,4 +511,4 @@ TabWidth: 8 # The way to use tab characters in the resulting file # -> Never: Allways use spaces -UseTab: Never \ No newline at end of file +UseTab: Never diff --git a/src/format-code.sh b/src/format-code.sh index 6a5cb565c1..30b51bd2e2 100755 --- a/src/format-code.sh +++ b/src/format-code.sh @@ -3,8 +3,8 @@ if [ $# -eq 0 ] then # No arguments: format all - SOURCE_DIRS="analyzer/ ext/ libs/ solver/ tools/ ui/ config/ tests/ packaging/" - SOURCE_FILES=$(find -regextype egrep -regex ".*/*\.(c|cxx|cpp|cc|h|hxx|hpp)$") + SOURCE_DIRS="analyzer/ libs/ solver/ tools/ config/ tests/ packaging/" + SOURCE_FILES=$(find $SOURCE_DIRS -regextype egrep -regex ".*/*\.(c|cxx|cpp|cc|h|hxx|hpp)$") else # Format files provided as arguments SOURCE_FILES="$@" From f2b159261d21bcd17a8d4957e45a46e6a5f67841 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 13 May 2024 15:25:42 +0200 Subject: [PATCH 084/101] format conflicting filers --- src/libs/antares/study/area/links.cpp | 186 +++++--- .../study/include/antares/study/area/links.h | 13 +- .../study/include/antares/study/parts/parts.h | 12 +- .../antares/study/parts/thermal/cluster.h | 24 +- .../antares/study/parts/thermal/cluster.hxx | 2 + src/libs/antares/study/parameters.cpp | 416 +++++++++++++++--- .../antares/study/parts/thermal/cluster.cpp | 87 +++- .../study/parts/thermal/cluster_list.cpp | 214 +++++++-- .../antares/solver/simulation/solver.hxx | 413 ++++++++++------- src/solver/ts-generator/availability.cpp | 161 ++++--- .../antares/solver/ts-generator/generator.h | 12 +- .../include/antares/solver/ts-generator/law.h | 2 +- .../antares/solver/ts-generator/prepro.h | 5 +- src/solver/ts-generator/prepro.cpp | 25 +- src/tools/ts-generator/main.cpp | 81 ++-- 15 files changed, 1188 insertions(+), 465 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index e2c31f4e29..54bf00dac5 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -19,16 +19,20 @@ ** along with Antares_Simulator. If not, see . */ +#include "antares/study/area/links.h" + +#include #include + +#include + #include -#include + +#include +#include #include "antares/study//study.h" -#include "antares/utils/utils.h" -#include "antares/study/area/links.h" #include "antares/study/area/area.h" -#include -#include -#include +#include "antares/utils/utils.h" using namespace Yuni; using namespace Antares; @@ -55,25 +59,25 @@ namespace Antares { namespace Data { -AreaLink::AreaLink() : - from(nullptr), - with(nullptr), - parameters(fhlMax, HOURS_PER_YEAR), - directCapacities(timeseriesNumbers), - indirectCapacities(timeseriesNumbers), - useLoopFlow(false), - usePST(false), - useHurdlesCost(false), - transmissionCapacities(LocalTransmissionCapacities::enabled), - assetType(Data::atAC), - index(0), - indexForArea(0), - displayComments(true), - filterSynthesis(filterAll), - filterYearByYear(filterAll), - color{112, 112, 112}, - style(stPlain), - linkWidth(1) +AreaLink::AreaLink(): + from(nullptr), + with(nullptr), + parameters(fhlMax, HOURS_PER_YEAR), + directCapacities(timeseriesNumbers), + indirectCapacities(timeseriesNumbers), + useLoopFlow(false), + usePST(false), + useHurdlesCost(false), + transmissionCapacities(LocalTransmissionCapacities::enabled), + assetType(Data::atAC), + index(0), + indexForArea(0), + displayComments(true), + filterSynthesis(filterAll), + filterYearByYear(filterAll), + color{112, 112, 112}, + style(stPlain), + linkWidth(1) { directCapacities.reset(); indirectCapacities.reset(); @@ -91,8 +95,10 @@ bool AreaLink::linkLoadTimeSeries_for_version_below_810(const AnyString& folder) // Load link's data Matrix<> tmpMatrix; const uint matrixWidth = 8; - if (!tmpMatrix.loadFromCSVFile( - buffer, matrixWidth, HOURS_PER_YEAR, Matrix<>::optFixedSize | Matrix<>::optImmediate)) + if (!tmpMatrix.loadFromCSVFile(buffer, + matrixWidth, + HOURS_PER_YEAR, + Matrix<>::optFixedSize | Matrix<>::optImmediate)) { return false; } @@ -142,12 +148,14 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol bool AreaLink::loadTSGenTimeSeries(const AnyString& folder) { const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); - tsGenerationDirect.prepro - = std::make_unique(id_direct, tsGenerationDirect.unitCount); + tsGenerationDirect.prepro = std::make_unique( + id_direct, + tsGenerationDirect.unitCount); const std::string id_indirect = std::string(with->id) + "/" + std::string(from->id); - tsGenerationIndirect.prepro - = std::make_unique(id_indirect, tsGenerationIndirect.unitCount); + tsGenerationIndirect.prepro = std::make_unique( + id_indirect, + tsGenerationIndirect.unitCount); String preproFolder; preproFolder << folder << SEP << "prepro"; @@ -159,20 +167,22 @@ bool AreaLink::loadTSGenTimeSeries(const AnyString& folder) if (std::filesystem::exists(filename.to())) { anyFileWasLoaded = true; - tsGenerationDirect.valid - = tsGenerationDirect.prepro->data.loadFromCSVFile( - filename, Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) - && tsGenerationDirect.prepro->validate(); + tsGenerationDirect.valid = tsGenerationDirect.prepro->data.loadFromCSVFile( + filename, + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGenerationDirect.prepro->validate(); } filename.clear() << preproFolder << SEP << with->id << "_indirect.txt"; if (std::filesystem::exists(filename.to())) { anyFileWasLoaded = true; - tsGenerationIndirect.valid - = tsGenerationIndirect.prepro->data.loadFromCSVFile( - filename, Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) - && tsGenerationIndirect.prepro->validate(); + tsGenerationIndirect.valid = tsGenerationIndirect.prepro->data.loadFromCSVFile( + filename, + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGenerationIndirect.prepro->validate(); } // Modulation @@ -180,16 +190,16 @@ bool AreaLink::loadTSGenTimeSeries(const AnyString& folder) if (std::filesystem::exists(filename.to())) { anyFileWasLoaded = true; - tsGenerationDirect.valid - &= tsGenerationDirect.modulationCapacity.loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + tsGenerationDirect.valid &= tsGenerationDirect.modulationCapacity + .loadFromCSVFile(filename, 1, HOURS_PER_YEAR); } filename.clear() << preproFolder << SEP << with->id << "_mod_indirect.txt"; if (std::filesystem::exists(filename.to())) { anyFileWasLoaded = true; - tsGenerationIndirect.valid - &= tsGenerationIndirect.modulationCapacity.loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + tsGenerationIndirect.valid &= tsGenerationIndirect.modulationCapacity + .loadFromCSVFile(filename, 1, HOURS_PER_YEAR); } if (anyFileWasLoaded) { @@ -221,12 +231,16 @@ void AreaLink::overrideTransmissionCapacityAccordingToGlobalParameter( break; case GlobalTransmissionCapacities::nullForPhysicalLinks: // Use '0' only for physical links if (isLinkPhysical()) + { transmissionCapacities = LocalTransmissionCapacities::null; + } break; case GlobalTransmissionCapacities::infiniteForPhysicalLinks: // Use 'infinity' only for physical // links if (isLinkPhysical()) + { transmissionCapacities = LocalTransmissionCapacities::infinite; + } break; default: logs.error() << "Wrong global transmission capacity given to function" << __FUNCTION__; @@ -236,9 +250,13 @@ void AreaLink::overrideTransmissionCapacityAccordingToGlobalParameter( bool AreaLink::loadTimeSeries(const StudyVersion& version, const AnyString& folder) { if (version < StudyVersion(8, 2)) + { return linkLoadTimeSeries_for_version_below_810(folder); + } else + { return linkLoadTimeSeries_for_version_820_and_later(folder); + } } void AreaLink::storeTimeseriesNumbers(Solver::IResultWriter& writer) const @@ -329,7 +347,9 @@ void AreaLink::reverse() bool AreaLink::isVisibleOnLayer(const size_t& layerID) const { if (from && with) + { return from->isVisibleOnLayer(layerID) && with->isVisibleOnLayer(layerID); + } return false; } @@ -340,7 +360,9 @@ AreaLink* AreaAddLinkBetweenAreas(Area* area, Area* with, bool warning) assert(with); if (warning && area->id > with->id) + { logs.warning() << "Link: `" << area->id << "` - `" << with->id << "`: Invalid orientation"; + } if (area->id == with->id) { @@ -361,19 +383,25 @@ namespace // anonymous bool handleKey(Data::AreaLink& link, const String& key, const String& value) { if (key == "hurdles-cost") + { return value.to(link.useHurdlesCost); + } if (key == "loop-flow") + { return value.to(link.useLoopFlow); + } if (key == "use-phase-shifter") + { return value.to(link.usePST); + } if (key == "copper-plate") { bool copperPlate; if (value.to(copperPlate)) { using LocalNTCtype = Data::LocalTransmissionCapacities; - link.transmissionCapacities - = copperPlate ? LocalNTCtype::infinite : LocalNTCtype::enabled; + link.transmissionCapacities = copperPlate ? LocalNTCtype::infinite + : LocalNTCtype::enabled; return true; } return false; @@ -381,15 +409,25 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) if (key == "asset-type") { if (value == "ac") + { link.assetType = atAC; + } else if (value == "dc") + { link.assetType = atDC; + } else if (value == "gaz") + { link.assetType = atGas; + } else if (value == "virt") + { link.assetType = atVirt; + } else if (value == "other") + { link.assetType = atOther; + } else { link.assetType = atOther; @@ -400,13 +438,21 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) if (key == "link-style") { if (value == "plain") + { link.style = stPlain; + } else if (value == "dot") + { link.style = stDot; + } else if (value == "dash") + { link.style = stDash; + } else if (value == "dotdash") + { link.style = stDotDash; + } else { link.style = stPlain; @@ -439,11 +485,17 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) { using LocalNTCtype = Data::LocalTransmissionCapacities; if (value == "enabled") + { link.transmissionCapacities = LocalNTCtype::enabled; + } else if (value == "infinite") + { link.transmissionCapacities = LocalNTCtype::infinite; + } else if (value == "ignore") + { link.transmissionCapacities = LocalNTCtype::null; + } else { link.transmissionCapacities = LocalNTCtype::null; @@ -453,7 +505,9 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) } if (key == "display-comments") + { return value.to(link.displayComments); + } if (key == "comments") { link.comments = value; @@ -477,29 +531,42 @@ bool handleTSGenKey_internal(const std::string& key, const std::string& prefix, Data::LinkTsGeneration& out) { - const auto checkPrefixed = [&prefix, &key](const std::string& s) { + const auto checkPrefixed = [&prefix, &key](const std::string& s) + { auto key_lowercase(key); boost::to_lower(key_lowercase); return key_lowercase == prefix + "_" + s; }; if (checkPrefixed("unitcount")) + { return value.to(out.unitCount); + } if (checkPrefixed("nominalcapacity")) + { return value.to(out.nominalCapacity); + } if (checkPrefixed("law.planned")) + { return value.to(out.plannedLaw); + } if (checkPrefixed("law.forced")) + { return value.to(out.forcedLaw); + } if (checkPrefixed("volatility.planned")) + { return value.to(out.plannedVolatility); + } if (checkPrefixed("volatility.forced")) + { return value.to(out.forcedVolatility); + } return false; } @@ -507,9 +574,13 @@ bool handleTSGenKey_internal(const std::string& key, bool handleTSGenKey(Data::AreaLink& link, const std::string& key, const String& value) { if (key.starts_with("tsgen_direct")) + { return handleTSGenKey_internal(key, value, "tsgen_direct", link.tsGenerationDirect); + } else if (key.starts_with("tsgen_indirect")) + { return handleTSGenKey_internal(key, value, "tsgen_indirect", link.tsGenerationIndirect); + } return false; } @@ -530,8 +601,8 @@ bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const uint indirect) { logs.error() << "Link (" << link.from->name << "/" << link.with->name << "): Found " << direct - << " direct TS " - << " and " << indirect << " indirect TS, expected the same number"; + << " direct TS " << " and " << indirect + << " indirect TS, expected the same number"; throw Antares::Error::ReadingStudy(); } } // anonymous namespace @@ -551,7 +622,9 @@ bool AreaLinksLoadFromFolder(const Study& study, IniFile ini; if (!ini.open(buffer)) + { return 0; + } bool ret = true; String key; @@ -638,8 +711,9 @@ bool AreaLinksLoadFromFolder(const Study& study, { if (directHurdlesCost[h] + indirectHurdlesCost[h] < 0) { - logLinkDataCheckError( - link, "hurdle costs direct + hurdle cost indirect < 0", h); + logLinkDataCheckError(link, + "hurdle costs direct + hurdle cost indirect < 0", + h); } } @@ -661,11 +735,15 @@ bool AreaLinksLoadFromFolder(const Study& study, key.toLower(); value = p->value; if (!AreaLinksInternalLoadFromProperty(link, key, value)) + { logs.warning() << '`' << p->key << "`: Unknown property"; + } } if (loadTSGen) + { ret = link.loadTSGenTimeSeries(folder) && ret; + } // From the solver only if (study.usedByTheSolver) @@ -768,7 +846,9 @@ bool saveAreaLinksConfigurationFileToFolder(const Area* area, const char* const section->add("colorb", link.color[2]); section->add("display-comments", link.displayComments); if (!link.comments.empty()) + { section->add("comments", link.comments); + } section->add("filter-synthesis", datePrecisionIntoString(link.filterSynthesis)); section->add("filter-year-by-year", datePrecisionIntoString(link.filterYearByYear)); } @@ -791,10 +871,14 @@ bool AreaLinksSaveToFolder(const Area* area, const char* const folder) } if (!saveAreaLinksConfigurationFileToFolder(area, folder)) + { return false; + } if (!saveAreaLinksTimeSeriesToFolder(area, folder)) + { return false; + } return true; } @@ -802,7 +886,9 @@ bool AreaLinksSaveToFolder(const Area* area, const char* const folder) void AreaLinkRemove(AreaLink* link) { if (!link) + { return; + } // Asserts assert(link->from); diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index 04b416df66..d06beaf1e4 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -21,16 +21,19 @@ #ifndef __ANTARES_LIBS_STUDY_LINKS_H__ #define __ANTARES_LIBS_STUDY_LINKS_H__ -#include -#include +#include + #include #include #include -#include "../fwd.h" + #include #include +#include +#include #include -#include + +#include "../fwd.h" namespace Antares { @@ -43,7 +46,7 @@ struct CompareLinkName; ** ** \ingroup area */ -class AreaLink final : public Yuni::NonCopyable +class AreaLink final: public Yuni::NonCopyable { public: //! Vector of links diff --git a/src/libs/antares/study/include/antares/study/parts/parts.h b/src/libs/antares/study/include/antares/study/parts/parts.h index db927118f9..8f3657d210 100644 --- a/src/libs/antares/study/include/antares/study/parts/parts.h +++ b/src/libs/antares/study/include/antares/study/parts/parts.h @@ -25,28 +25,28 @@ #include "load/container.h" // Solar -#include "solar/prepro.h" #include "solar/container.h" +#include "solar/prepro.h" // Hydro -#include "hydro/prepro.h" -#include "hydro/series.h" #include "hydro/container.h" #include "hydro/hydromaxtimeseriesreader.h" +#include "hydro/prepro.h" +#include "hydro/series.h" // Wind -#include "wind/prepro.h" #include "wind/container.h" +#include "wind/prepro.h" // Thermal -#include "thermal/defines.h" #include "thermal/cluster.h" #include "thermal/container.h" +#include "thermal/defines.h" // Renewable -#include "renewable/defines.h" #include "renewable/cluster.h" #include "renewable/container.h" +#include "renewable/defines.h" // Short-term storage #include "short-term-storage/container.h" diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h index 2c9872f5d6..7d1ce30bac 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.h @@ -21,19 +21,22 @@ #ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_CLUSTER_H__ #define __ANTARES_LIBS_STUDY_PARTS_THERMAL_CLUSTER_H__ +#include +#include +#include +#include + #include #include + #include #include + +#include "../../fwd.h" +#include "../common/cluster.h" #include "defines.h" #include "ecoInput.h" -#include "../common/cluster.h" -#include "../../fwd.h" #include "pollutant.h" -#include -#include -#include -#include namespace Antares { @@ -64,7 +67,7 @@ enum class LocalTSGenerationBehavior /*! ** \brief A single thermal cluster */ -class ThermalCluster final : public Cluster, public std::enable_shared_from_this +class ThermalCluster final: public Cluster, public std::enable_shared_from_this { public: enum ThermalDispatchableGroup @@ -233,6 +236,7 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this //! Mustrun bool mustrun = false; + bool isMustRun() const { return mustrun; @@ -255,7 +259,10 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this struct DivModulation { - DivModulation() : value(0.0), isCalculated(false), isValidated(false) + DivModulation(): + value(0.0), + isCalculated(false), + isValidated(false) { } @@ -358,6 +365,7 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this std::array marketBidCostTS; std::array marginalCostTS; }; + std::vector costsTimeSeries; EconomicInputData ecoInput; diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx index 494383edae..8c2eaaf7cd 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster.hxx @@ -89,6 +89,7 @@ class Into { public: using TargetType = Antares::Data::StatisticalLaw; + enum { valid = 1 @@ -131,6 +132,7 @@ class Into { public: using TargetType = Antares::Data::LocalTSGenerationBehavior; + enum { valid = 1 diff --git a/src/libs/antares/study/parameters.cpp b/src/libs/antares/study/parameters.cpp index 1e2eb4f0a1..c0e623f1fd 100644 --- a/src/libs/antares/study/parameters.cpp +++ b/src/libs/antares/study/parameters.cpp @@ -18,26 +18,27 @@ ** You should have received a copy of the Mozilla Public Licence 2.0 ** along with Antares_Simulator. If not, see . */ -#include +#include "antares/study/parameters.h" -#include -#include +#include #include -#include // std::tuple +#include +#include #include // std::list #include // std::stringstream +#include // std::tuple -#include "antares/study/parameters.h" -#include "antares/antares/constants.h" -#include -#include -#include "antares/study/load-options.h" -#include #include -#include "antares/solver/variable/economy/all.h" + +#include #include +#include +#include #include "antares/antares/Enum.hpp" +#include "antares/antares/constants.h" +#include "antares/solver/variable/economy/all.h" +#include "antares/study/load-options.h" using namespace Yuni; @@ -50,29 +51,49 @@ static bool ConvertCStrToListTimeSeries(const String& value, uint& v) { v = 0; if (!value) + { return true; + } - value.words(" ,;\t\r\n", [&](const AnyString& element) -> bool { - ShortString16 word(element); - word.toLower(); - if (word == "load") - v |= timeSeriesLoad; - else if (word == "wind") - v |= timeSeriesWind; - else if (word == "hydro") - v |= timeSeriesHydro; - else if (word == "thermal") - v |= timeSeriesThermal; - else if (word == "solar") - v |= timeSeriesSolar; - else if (word == "renewables") - v |= timeSeriesRenewable; - else if (word == "ntc") - v |= timeSeriesTransmissionCapacities; - else if (word == "max-power") - v |= timeSeriesHydroMaxPower; - return true; - }); + value.words(" ,;\t\r\n", + [&](const AnyString& element) -> bool + { + ShortString16 word(element); + word.toLower(); + if (word == "load") + { + v |= timeSeriesLoad; + } + else if (word == "wind") + { + v |= timeSeriesWind; + } + else if (word == "hydro") + { + v |= timeSeriesHydro; + } + else if (word == "thermal") + { + v |= timeSeriesThermal; + } + else if (word == "solar") + { + v |= timeSeriesSolar; + } + else if (word == "renewables") + { + v |= timeSeriesRenewable; + } + else if (word == "ntc") + { + v |= timeSeriesTransmissionCapacities; + } + else if (word == "max-power") + { + v |= timeSeriesHydroMaxPower; + } + return true; + }); return true; } @@ -145,9 +166,13 @@ static void ParametersSaveResultFormat(IniFile::Section* section, ResultFormat f bool StringToSimulationMode(SimulationMode& mode, CString<20, false> text) { if (!text) + { return false; + } if (text.size() == 1) + { return false; + } // Converting into lowercase text.toLower(); @@ -189,7 +214,8 @@ const char* SimulationModeToCString(SimulationMode mode) } } -Parameters::Parameters() : noOutput(false) +Parameters::Parameters(): + noOutput(false) { } @@ -217,7 +243,9 @@ void Parameters::resetSeeds() seed[seedTsGenWind] = s; // The same way for all others for (auto i = (uint)seedTsGenLoad; i != seedMax; ++i) + { seed[i] = (s += increment); + } } void Parameters::resetPlayedYears(uint nbOfYears) @@ -357,47 +385,63 @@ static void ParametersSaveTimeSeries(IniFile::Section* s, const char* name, uint CString<60, false> v; if (value & timeSeriesLoad) + { v += "load"; + } if (value & timeSeriesHydro) { if (not v.empty()) + { v += ", "; + } v += "hydro"; } if (value & timeSeriesWind) { if (not v.empty()) + { v += ", "; + } v += "wind"; } if (value & timeSeriesThermal) { if (not v.empty()) + { v += ", "; + } v += "thermal"; } if (value & timeSeriesSolar) { if (not v.empty()) + { v += ", "; + } v += "solar"; } if (value & timeSeriesRenewable) { if (not v.empty()) + { v += ", "; + } v += "renewables"; } if (value & timeSeriesTransmissionCapacities) { if (!v.empty()) + { v += ", "; + } v += "ntc"; } if (value & timeSeriesHydroMaxPower) { if (!v.empty()) + { v += ", "; + } v += "max-power"; } s->add(name, v); @@ -414,22 +458,34 @@ static bool SGDIntLoadFamily_General(Parameters& d, return true; } if (key == "custom-scenario") + { return value.to(d.useCustomScenario); + } if (key == "derated") + { return value.to(d.derated); + } if (key == "first-month-in-year") + { return Date::StringToMonth(d.firstMonthInYear, value); + } if (key == "first.weekday") + { return Date::StringToDayOfTheWeek(d.firstWeekday, value); + } if (key == "geographic-trimming") + { return value.to(d.geographicTrimming); + } if (key == "generate") + { return ConvertCStrToListTimeSeries(value, d.timeSeriesToGenerate); + } if (key == "horizon") { @@ -440,21 +496,33 @@ static bool SGDIntLoadFamily_General(Parameters& d, // Same time-series if (key == "intra-modal") + { return ConvertCStrToListTimeSeries(value, d.intraModal); + } // Same time-series if (key == "inter-modal") + { return ConvertCStrToListTimeSeries(value, d.interModal); + } if (key == "improveunitsstartup") + { return true; // value.to(d.improveUnitsStartup); + } if (key == "january.1st") // after 4.3 + { return Date::StringToDayOfTheWeek(d.dayOfThe1stJanuary, value); + } if (key == "leapyear") + { return value.to(d.leapYear); + } if (key == "mode") + { return StringToSimulationMode(d.mode, value); + } if (key == "nbyears") { @@ -468,47 +536,79 @@ static bool SGDIntLoadFamily_General(Parameters& d, return false; } if (key == "nbtimeseriesload") + { return value.to(d.nbTimeSeriesLoad); + } if (key == "nbtimeserieshydro") + { return value.to(d.nbTimeSeriesHydro); + } if (key == "nbtimeserieswind") + { return value.to(d.nbTimeSeriesWind); + } if (key == "nbtimeseriesthermal") + { return value.to(d.nbTimeSeriesThermal); + } if (key == "nbtimeseriessolar") + { return value.to(d.nbTimeSeriesSolar); + } if (key == "nbtimeserieslinks") + { return value.to(d.nbLinkTStoGenerate); + } // Interval values if (key == "refreshintervalload") + { return value.to(d.refreshIntervalLoad); + } if (key == "refreshintervalhydro") + { return value.to(d.refreshIntervalHydro); + } if (key == "refreshintervalwind") + { return value.to(d.refreshIntervalWind); + } if (key == "refreshintervalthermal") + { return value.to(d.refreshIntervalThermal); + } if (key == "refreshintervalsolar") + { return value.to(d.refreshIntervalSolar); + } // What timeSeries to refresh ? if (key == "refreshtimeseries") + { return ConvertCStrToListTimeSeries(value, d.timeSeriesToRefresh); + } // readonly if (key == "readonly") + { return value.to(d.readonly); + } if (key == "simulation.start") { uint day; if (not value.to(day)) + { return false; + } if (day == 0) + { day = 1; + } else { if (day > 365) + { day = 365; + } --day; } d.simulationDays.first = day; @@ -518,76 +618,121 @@ static bool SGDIntLoadFamily_General(Parameters& d, { uint day; if (not value.to(day)) + { return false; + } if (day == 0) + { day = 1; + } else if (day > 365) + { day = 365; + } d.simulationDays.end = day; // not included return true; } if (key == "thematic-trimming") + { return value.to(d.thematicTrimming); + } if (key == "user-playlist") + { return value.to(d.userPlaylist); + } if (key == "year-by-year") + { return value.to(d.yearByYear); + } return false; } + static bool SGDIntLoadFamily_Input(Parameters& d, const String& key, const String& value, const String&) { if (key == "import") + { return ConvertCStrToListTimeSeries(value, d.exportTimeSeriesInInput); + } return false; } + static bool SGDIntLoadFamily_Output(Parameters& d, const String& key, const String& value, const String&) { if (key == "archives") + { return ConvertCStrToListTimeSeries(value, d.timeSeriesToArchive); + } if (key == "storenewset") + { return value.to(d.storeTimeseriesNumbers); + } if (key == "synthesis") + { return value.to(d.synthesis); + } if (key == "hydro-debug") + { return value.to(d.hydroDebug); + } if (key == "result-format") + { return ConvertCStrToResultFormat(value, d.resultFormat); + } return false; } + static bool SGDIntLoadFamily_Optimization(Parameters& d, const String& key, const String& value, const String&) { if (key == "include-constraints") + { return value.to(d.include.constraints); + } if (key == "include-hurdlecosts") + { return value.to(d.include.hurdleCosts); + } if (key == "include-loopflowfee") // backward compatibility - return true; // value.to(d.include.loopFlowFee); + { + return true; // value.to(d.include.loopFlowFee); + } if (key == "include-tc-minstablepower") + { return value.to(d.include.thermal.minStablePower); + } if (key == "include-tc-min-ud-time") + { return value.to(d.include.thermal.minUPTime); + } if (key == "include-dayahead") + { return value.to(d.include.reserve.dayAhead); + } if (key == "include-strategicreserve") + { return value.to(d.include.reserve.strategic); + } if (key == "include-spinningreserve") + { return value.to(d.include.reserve.spinning); + } if (key == "include-primaryreserve") + { return value.to(d.include.reserve.primary); + } if (key == "include-exportmps") { @@ -602,7 +747,9 @@ static bool SGDIntLoadFamily_Optimization(Parameters& d, } if (key == "include-exportstructure") + { return value.to(d.include.exportStructure); + } if (key == "include-unfeasible-problem-behavior") { bool result = true; @@ -610,8 +757,8 @@ static bool SGDIntLoadFamily_Optimization(Parameters& d, try { - d.include.unfeasibleProblemBehavior - = Enum::fromString(string); + d.include.unfeasibleProblemBehavior = Enum::fromString( + string); } catch (AssertionError& ex) { @@ -644,6 +791,7 @@ static bool SGDIntLoadFamily_Optimization(Parameters& d, } return false; } + static bool SGDIntLoadFamily_AdqPatch(Parameters& d, const String& key, const String& value, @@ -751,20 +899,26 @@ static bool SGDIntLoadFamily_OtherPreferences(Parameters& d, } // Renewable generation modelling if (key == "renewable-generation-modelling") + { return ConvertStringToRenewableGenerationModelling(value, d.renewableGeneration.rgModelling); + } return false; } + static bool SGDIntLoadFamily_AdvancedParameters(Parameters& d, const String& key, const String& value, const String&) { if (key == "accuracy-on-correlation") + { return ConvertCStrToListTimeSeries(value, d.timeSeriesAccuracyOnCorrelation); + } return false; } + static bool SGDIntLoadFamily_Playlist(Parameters& d, const String& key, const String& value, @@ -776,12 +930,16 @@ static bool SGDIntLoadFamily_Playlist(Parameters& d, if (mode) { for (uint i = 0; i != d.nbYears; ++i) + { d.yearsFilter[i] = true; + } } else { for (uint i = 0; i != d.nbYears; ++i) + { d.yearsFilter[i] = false; + } } return true; } @@ -791,7 +949,9 @@ static bool SGDIntLoadFamily_Playlist(Parameters& d, if (value.to(y)) { if (y < d.nbYears) + { d.yearsFilter[y] = true; + } return true; } return false; @@ -802,7 +962,9 @@ static bool SGDIntLoadFamily_Playlist(Parameters& d, if (value.to(y)) { if (y < d.nbYears) + { d.yearsFilter[y] = false; + } return true; } return false; @@ -859,18 +1021,18 @@ static bool SGDIntLoadFamily_Playlist(Parameters& d, static bool deprecatedVariable(std::string var) { - static const std::vector STSGroups_legacy - = {"psp_open_level", "psp_closed_level", "pondage_level", - "battery_level", "other1_level", "other2_level", - "other3_level", "other4_level", "other5_level", - - "psp_open_injection", "psp_closed_injection", "pondage_injection", - "battery_injection", "other1_injection", "other2_injection", - "other3_injection", "other4_injection", "other5_injection", - - "psp_open_withdrawal", "psp_closed_withdrawal", "pondage_withdrawal", - "battery_withdrawal", "other1_withdrawal", "other2_withdrawal", - "other3_withdrawal", "other4_withdrawal", "other5_withdrawal"}; + static const std::vector STSGroups_legacy = { + "psp_open_level", "psp_closed_level", "pondage_level", + "battery_level", "other1_level", "other2_level", + "other3_level", "other4_level", "other5_level", + + "psp_open_injection", "psp_closed_injection", "pondage_injection", + "battery_injection", "other1_injection", "other2_injection", + "other3_injection", "other4_injection", "other5_injection", + + "psp_open_withdrawal", "psp_closed_withdrawal", "pondage_withdrawal", + "battery_withdrawal", "other1_withdrawal", "other2_withdrawal", + "other3_withdrawal", "other4_withdrawal", "other5_withdrawal"}; boost::to_lower(var); return std::ranges::find(STSGroups_legacy, var) != STSGroups_legacy.end(); } @@ -907,6 +1069,7 @@ static bool SGDIntLoadFamily_VariablesSelection(Parameters& d, } return false; } + static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, const String& key, const String& value, @@ -918,19 +1081,33 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, { // This block is kept for compatibility with very old studies if (key == "seed_load") + { return value.to(d.seed[seedTsGenLoad]); + } if (key == "seed_wind") + { return value.to(d.seed[seedTsGenWind]); + } if (key == "seed_hydro") + { return value.to(d.seed[seedTsGenHydro]); + } if (key == "seed_thermal") + { return value.to(d.seed[seedTsGenThermal]); + } if (key == "seed_solar") + { return value.to(d.seed[seedTsGenSolar]); + } if (key == "seed_links") + { return value.to(d.seed[seedTsGenLinks]); + } if (key == "seed_timeseriesnumbers") + { return value.to(d.seed[seedTimeseriesNumbers]); + } } else { @@ -939,12 +1116,15 @@ static bool SGDIntLoadFamily_SeedsMersenneTwister(Parameters& d, for (uint sd = 0; sd != (uint)seedMax; ++sd) { if (SeedToID((SeedIndex)sd) == key) + { return value.to(d.seed[sd]); + } } } } return false; } + static bool SGDIntLoadFamily_Legacy(Parameters& d, const String& key, const String& value, @@ -955,33 +1135,51 @@ static bool SGDIntLoadFamily_Legacy(Parameters& d, // Same time-series if (key == "correlateddraws") + { return ConvertCStrToListTimeSeries(value, d.intraModal); + } // Scenario builder if (key == "custom-ts-numbers") + { return value.to(d.useCustomScenario); + } if (key == "filtering" && version < StudyVersion(7, 1)) + { return value.to(d.geographicTrimming); + } // Custom set if (key == "customset") + { return true; // value ignored + } if (key == "shedding-strategy") // Was never used + { return true; + } if (key == "day-ahead-reserve-management") // ignored since 8.4 + { return true; + } if (key == "link-type") // ignored since 8.5.2 + { return true; + } if (key == "adequacy-block-size") // ignored since 8.5 + { return true; + } // deprecated but needed for testing old studies if (key == "include-split-exported-mps") + { return true; + } return false; } @@ -1005,17 +1203,17 @@ bool Parameters::loadFromINI(const IniFile& ini, const String&, // [in] Lowercase value, comes right to the '=' sign in the .ini file const String&); // [in] Raw value as writtent right to the '=' sign in the .ini file - static const std::map sectionAssociatedToKeysProcess - = {{"general", &SGDIntLoadFamily_General}, - {"input", &SGDIntLoadFamily_Input}, - {"output", &SGDIntLoadFamily_Output}, - {"optimization", &SGDIntLoadFamily_Optimization}, - {"adequacy patch", &SGDIntLoadFamily_AdqPatch}, - {"other preferences", &SGDIntLoadFamily_OtherPreferences}, - {"advanced parameters", &SGDIntLoadFamily_AdvancedParameters}, - {"playlist", &SGDIntLoadFamily_Playlist}, - {"variables selection", &SGDIntLoadFamily_VariablesSelection}, - {"seeds - mersenne twister", &SGDIntLoadFamily_SeedsMersenneTwister}}; + static const std::map sectionAssociatedToKeysProcess = { + {"general", &SGDIntLoadFamily_General}, + {"input", &SGDIntLoadFamily_Input}, + {"output", &SGDIntLoadFamily_Output}, + {"optimization", &SGDIntLoadFamily_Optimization}, + {"adequacy patch", &SGDIntLoadFamily_AdqPatch}, + {"other preferences", &SGDIntLoadFamily_OtherPreferences}, + {"advanced parameters", &SGDIntLoadFamily_AdvancedParameters}, + {"playlist", &SGDIntLoadFamily_Playlist}, + {"variables selection", &SGDIntLoadFamily_VariablesSelection}, + {"seeds - mersenne twister", &SGDIntLoadFamily_SeedsMersenneTwister}}; Callback handleAllKeysInSection; // Foreach section on the ini file... @@ -1038,9 +1236,13 @@ bool Parameters::loadFromINI(const IniFile& ini, for (const IniFile::Property* p = section->firstProperty; p; p = p->next) { if (p->key.empty()) + { continue; + } if (!firstKeyLetterIsValid(p->key)) + { continue; + } // We convert the key and the value into the lower case format String value = p->value; value.toLower(); @@ -1084,10 +1286,14 @@ bool Parameters::loadFromINI(const IniFile& ini, logs.info() << " forcing the simulation mode " << SimulationModeToCString(mode); } else + { logs.info() << " simulation mode: " << SimulationModeToCString(mode); + } if (options.forceDerated) + { derated = true; + } // Define ortools parameters from options ortoolsUsed = options.ortoolsUsed; @@ -1107,7 +1313,9 @@ bool Parameters::loadFromINI(const IniFile& ini, // Specific action before launching a simulation if (options.usedByTheSolver) + { prepareForSimulation(options); + } if (options.mpsToExport || options.namedProblems) { @@ -1130,7 +1338,7 @@ void Parameters::fixRefreshIntervals() {refreshIntervalWind, timeSeriesWind, "wind"}, {refreshIntervalThermal, timeSeriesThermal, "thermal"}}; - for (const auto& [refreshInterval, ts, label] : timeSeriesToCheck) + for (const auto& [refreshInterval, ts, label]: timeSeriesToCheck) { if (ts & timeSeriesToRefresh && 0 == refreshInterval) { @@ -1202,15 +1410,25 @@ void Parameters::fixBadValues() } if (!nbTimeSeriesLoad) + { nbTimeSeriesLoad = 1; + } if (!nbTimeSeriesThermal) + { nbTimeSeriesThermal = 1; + } if (!nbTimeSeriesHydro) + { nbTimeSeriesHydro = 1; + } if (!nbTimeSeriesWind) + { nbTimeSeriesWind = 1; + } if (!nbTimeSeriesSolar) + { nbTimeSeriesSolar = 1; + } } uint64_t Parameters::memoryUsage() const @@ -1240,6 +1458,7 @@ std::vector Parameters::getYearsWeight() const return result; } + float Parameters::getYearsWeightSum() const { float result = 0.f; @@ -1324,7 +1543,9 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options) for (uint i = 0; i < nbYears; ++i) { if (yearsFilter[i]) + { ++effectiveNbYears; + } } switch (effectiveNbYears) { @@ -1405,7 +1626,9 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options) { // The year-by-year mode might have been requested from the command line if (options.forceYearByYear) + { yearByYear = true; + } break; } case SimulationMode::Unknown: @@ -1435,15 +1658,25 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options) { // Removing `refresh` if (!(timeSeriesToGenerate & timeSeriesLoad)) + { timeSeriesToRefresh &= ~timeSeriesLoad; + } if (!(timeSeriesToGenerate & timeSeriesSolar)) + { timeSeriesToRefresh &= ~timeSeriesSolar; + } if (!(timeSeriesToGenerate & timeSeriesWind)) + { timeSeriesToRefresh &= ~timeSeriesWind; + } if (!(timeSeriesToGenerate & timeSeriesHydro)) + { timeSeriesToRefresh &= ~timeSeriesHydro; + } if (!(timeSeriesToGenerate & timeSeriesThermal)) + { timeSeriesToRefresh &= ~timeSeriesThermal; + } // Force mode refresh if the timeseries must be regenerated if (timeSeriesToGenerate & timeSeriesLoad && !(timeSeriesToRefresh & timeSeriesLoad)) @@ -1480,42 +1713,78 @@ void Parameters::prepareForSimulation(const StudyLoadOptions& options) } if (mode == SimulationMode::Expansion) + { logs.info() << " :: enabling expansion"; + } if (yearByYear) + { logs.info() << " :: enabling the 'year-by-year' mode"; + } if (derated) + { logs.info() << " :: enabling the 'derated' mode"; + } if (userPlaylist) + { logs.info() << " :: enabling the user playlist"; + } if (thematicTrimming) + { logs.info() << " :: enabling the user variable selection"; + } if (useCustomScenario) + { logs.info() << " :: enabling the custom build mode"; + } if (geographicTrimming) + { logs.info() << " :: enabling filtering by file"; + } if (!include.constraints) + { logs.info() << " :: ignoring binding constraints"; + } if (!include.reserve.dayAhead) + { logs.info() << " :: ignoring day ahead reserves"; + } if (!include.reserve.primary) + { logs.info() << " :: ignoring primary reserves"; + } if (!include.reserve.strategic) + { logs.info() << " :: ignoring strategic reserves"; + } if (!include.reserve.spinning) + { logs.info() << " :: ignoring spinning reserves"; + } if (!include.thermal.minStablePower) + { logs.info() << " :: ignoring min stable power for thermal clusters"; + } if (!include.thermal.minUPTime) + { logs.info() << " :: ignoring min up/down time for thermal clusters"; + } if (include.exportMPS == mpsExportStatus::NO_EXPORT) + { logs.info() << " :: ignoring export mps"; + } if (!adqPatchParams.enabled) + { logs.info() << " :: ignoring adequacy patch"; + } if (!include.exportStructure) + { logs.info() << " :: ignoring export structure"; + } if (!include.hurdleCosts) + { logs.info() << " :: ignoring hurdle costs"; + } // Indicate ortools solver used if (ortoolsUsed) @@ -1565,7 +1834,9 @@ void Parameters::saveToINI(IniFile& ini) const section->add("thematic-trimming", thematicTrimming); section->add("geographic-trimming", geographicTrimming); if (not activeRulesScenario.empty()) + { section->add("active-rules-scenario", activeRulesScenario); + } // Time series ParametersSaveTimeSeries(section, "generate", timeSeriesToGenerate); @@ -1602,7 +1873,9 @@ void Parameters::saveToINI(IniFile& ini) const section->add("synthesis", synthesis); section->add("storeNewSet", storeTimeseriesNumbers); if (hydroDebug) + { section->add("hydro-debug", hydroDebug); + } ParametersSaveTimeSeries(section, "archives", timeSeriesToArchive); ParametersSaveResultFormat(section, resultFormat); } @@ -1666,8 +1939,9 @@ void Parameters::saveToINI(IniFile& ini) const { auto* section = ini.addSection("advanced parameters"); // Accuracy on correlation - ParametersSaveTimeSeries( - section, "accuracy-on-correlation", timeSeriesAccuracyOnCorrelation); + ParametersSaveTimeSeries(section, + "accuracy-on-correlation", + timeSeriesAccuracyOnCorrelation); } // User's playlist @@ -1678,7 +1952,9 @@ void Parameters::saveToINI(IniFile& ini) const for (uint i = 0; i != nbYears; ++i) { if (yearsFilter[i]) + { ++effNbYears; + } weightEnabled |= yearsWeight[i] != 1.f; } @@ -1697,7 +1973,9 @@ void Parameters::saveToINI(IniFile& ini) const for (uint i = 0; i != nbYears; ++i) { if (yearsFilter[i]) + { section->add("playlist_year +", i); + } } } else @@ -1705,7 +1983,9 @@ void Parameters::saveToINI(IniFile& ini) const for (uint i = 0; i != nbYears; ++i) { if (!yearsFilter[i]) + { section->add("playlist_year -", i); + } } } @@ -1733,13 +2013,17 @@ void Parameters::saveToINI(IniFile& ini) const if (nb_selected_vars <= (nb_tot_vars / 2)) { section->add("selected_vars_reset", "false"); - for (auto& name : variablesPrintInfo.namesOfEnabledVariables()) + for (auto& name: variablesPrintInfo.namesOfEnabledVariables()) + { section->add("select_var +", name); + } } else { - for (auto& name : variablesPrintInfo.namesOfDisabledVariables()) + for (auto& name: variablesPrintInfo.namesOfDisabledVariables()) + { section->add("select_var -", name); + } } } } @@ -1748,7 +2032,9 @@ void Parameters::saveToINI(IniFile& ini) const { auto* section = ini.addSection("seeds - Mersenne Twister"); for (uint sd = 0; sd != (uint)seedMax; ++sd) + { section->add(SeedToID((SeedIndex)sd), seed[sd]); + } } } @@ -1759,7 +2045,9 @@ bool Parameters::loadFromFile(const AnyString& filename, // Loading the INI file IniFile ini; if (ini.open(filename)) + { return loadFromINI(ini, version, options); + } // Error otherwise reset(); diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index e026d92b59..f6030e3945 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -19,19 +19,22 @@ ** along with Antares_Simulator. If not, see . */ -#include +#include "antares/study/parts/thermal/cluster.h" + #include +#include +#include + +#include #include #include -#include -#include -#include "antares/study/study.h" -#include "antares/study/parts/thermal/cluster.h" -#include + #include #include +#include #include +#include "antares/study/study.h" using namespace Yuni; using namespace Antares; @@ -46,7 +49,9 @@ bool Into::Perform(AnyString string, TargetType& { string.trim(); if (string.empty()) + { return false; + } if (string.equalsInsensitive("uniform")) { @@ -65,7 +70,9 @@ bool Into::Perform(AnyString string, TargetType& { string.trim(); if (string.empty()) + { return false; + } if (string.equalsInsensitive("setManually")) { @@ -84,7 +91,9 @@ bool Into::Perform(AnyString string, T { string.trim(); if (string.empty()) + { return false; + } if (string.equalsInsensitive("use global")) { @@ -110,8 +119,10 @@ namespace Antares { namespace Data { -Data::ThermalCluster::ThermalCluster(Area* parent) : - Cluster(parent), PthetaInf(HOURS_PER_YEAR, 0), costsTimeSeries(1, CostsTimeSeries()) +Data::ThermalCluster::ThermalCluster(Area* parent): + Cluster(parent), + PthetaInf(HOURS_PER_YEAR, 0), + costsTimeSeries(1, CostsTimeSeries()) { // assert assert(parent && "A parent for a thermal dispatchable cluster can not be null"); @@ -189,7 +200,9 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster) // Making sure that the data related to the prepro and timeseries are present // prepro if (!prepro) + { prepro = new PreproAvailability(id(), unitCount); + } prepro->copyFrom(*cluster.prepro); ecoInput.copyFrom(cluster.ecoInput); @@ -202,24 +215,26 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster) // The parent must be invalidated to make sure that the clusters are really // re-written at the next 'Save' from the user interface. if (parentArea) + { parentArea->forceReload(); + } } static Data::ThermalCluster::ThermalDispatchableGroup stringToGroup(Data::ClusterName& newgrp) { using namespace Antares::Data; - const static std::map mapping - = {{"nuclear", ThermalCluster::thermalDispatchGrpNuclear}, - {"lignite", ThermalCluster::thermalDispatchGrpLignite}, - {"hard coal", ThermalCluster::thermalDispatchGrpHardCoal}, - {"gas", ThermalCluster::thermalDispatchGrpGas}, - {"oil", ThermalCluster::thermalDispatchGrpOil}, - {"mixed fuel", ThermalCluster::thermalDispatchGrpMixedFuel}, - {"other", ThermalCluster::thermalDispatchGrpOther1}, - {"other 1", ThermalCluster::thermalDispatchGrpOther1}, - {"other 2", ThermalCluster::thermalDispatchGrpOther2}, - {"other 3", ThermalCluster::thermalDispatchGrpOther3}, - {"other 4", ThermalCluster::thermalDispatchGrpOther4}}; + const static std::map mapping = { + {"nuclear", ThermalCluster::thermalDispatchGrpNuclear}, + {"lignite", ThermalCluster::thermalDispatchGrpLignite}, + {"hard coal", ThermalCluster::thermalDispatchGrpHardCoal}, + {"gas", ThermalCluster::thermalDispatchGrpGas}, + {"oil", ThermalCluster::thermalDispatchGrpOil}, + {"mixed fuel", ThermalCluster::thermalDispatchGrpMixedFuel}, + {"other", ThermalCluster::thermalDispatchGrpOther1}, + {"other 1", ThermalCluster::thermalDispatchGrpOther1}, + {"other 2", ThermalCluster::thermalDispatchGrpOther2}, + {"other 3", ThermalCluster::thermalDispatchGrpOther3}, + {"other 4", ThermalCluster::thermalDispatchGrpOther4}}; boost::to_lower(newgrp); if (auto res = mapping.find(newgrp); res != mapping.end()) @@ -248,7 +263,9 @@ bool Data::ThermalCluster::forceReload(bool reload) const ret = modulation.forceReload(reload) && ret; ret = series.forceReload(reload) && ret; if (prepro) + { ret = prepro->forceReload(reload) && ret; + } ret = ecoInput.forceReload(reload) && ret; return ret; } @@ -258,7 +275,9 @@ void Data::ThermalCluster::markAsModified() const modulation.markAsModified(); series.markAsModified(); if (prepro) + { prepro->markAsModified(); + } ecoInput.markAsModified(); } @@ -351,7 +370,7 @@ void ThermalCluster::ComputeMarketBidTS() void ThermalCluster::MarginalCostEqualsMarketBid() { - for (auto& timeSeries : costsTimeSeries) + for (auto& timeSeries: costsTimeSeries) { auto& source = timeSeries.marketBidCostTS; auto& destination = timeSeries.marginalCostTS; @@ -362,9 +381,11 @@ void ThermalCluster::MarginalCostEqualsMarketBid() void ThermalCluster::ComputeProductionCostTS() { if (modulation.width == 0) + { return; + } - for (auto& timeSeries : costsTimeSeries) + for (auto& timeSeries: costsTimeSeries) { auto& productionCostTS = timeSeries.productionCostTs; auto& marginalCostTS = timeSeries.marginalCostTS; @@ -454,7 +475,9 @@ void Data::ThermalCluster::reset() // since the interface may still have a pointer to them. // we must simply reset their content. if (!prepro) + { prepro = new PreproAvailability(id(), unitCount); + } prepro->reset(); ecoInput.reset(); } @@ -512,9 +535,13 @@ bool Data::ThermalCluster::integrityCheck() if (spinning < 0. or spinning > 100.) { if (spinning < 0.) + { spinning = 0; + } else + { spinning = 100.; + } logs.error() << "Thermal cluster: " << parentArea->name << '/' << pName << ": The spinning must be within the range [0,+100] (rounded to " << spinning << ')'; @@ -610,7 +637,9 @@ uint64_t ThermalCluster::memoryUsage() const { uint64_t amount = sizeof(ThermalCluster) + modulation.memoryUsage(); if (prepro) + { amount += prepro->memoryUsage(); + } amount += series.memoryUsage(); amount += ecoInput.memoryUsage(); return amount; @@ -639,7 +668,9 @@ void ThermalCluster::calculatMinDivModulation() bool ThermalCluster::checkMinStablePower() { if (!minDivModulation.isCalculated) // not has been initialized + { calculatMinDivModulation(); + } if (minDivModulation.value < 0) { @@ -651,10 +682,14 @@ bool ThermalCluster::checkMinStablePower() double nomCapacityWithSpinning = nominalCapacity * (1 - spinning / 101); if (Utils::isZero(1 - spinning / 101)) + { minDivModulation.border = .0; + } else - minDivModulation.border - = std::min(nomCapacityWithSpinning, minStablePower) / nomCapacityWithSpinning; + { + minDivModulation.border = std::min(nomCapacityWithSpinning, minStablePower) + / nomCapacityWithSpinning; + } if (minDivModulation.value < minDivModulation.border) { @@ -669,7 +704,9 @@ bool ThermalCluster::checkMinStablePower() bool ThermalCluster::checkMinStablePowerWithNewModulation(uint idx, double value) { if (!minDivModulation.isCalculated || idx == minDivModulation.index) + { calculatMinDivModulation(); + } else { double div = value / ceil(value); @@ -776,8 +813,10 @@ void ThermalCluster::checkAndCorrectAvailability() } if (report) + { logs.warning() << "Area : " << parentArea->name << " cluster name : " << name() << " available power lifted to match Pmin and Pnom requirements"; + } } bool ThermalCluster::isActive() const diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 6efb5376ab..fff1cd2d8c 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -20,10 +20,12 @@ */ #include "antares/study/parts/thermal/cluster_list.h" + +#include + +#include #include "antares/study/parts/common/cluster.h" #include "antares/study/study.h" -#include -#include namespace // anonymous { @@ -62,7 +64,8 @@ std::string ThermalClusterList::typeID() const uint64_t ThermalClusterList::memoryUsage() const { uint64_t ret = sizeof(ThermalClusterList) + (2 * sizeof(void*)) * enabledAndMustRunCount(); - std::ranges::for_each(each_enabled_and_not_mustrun(), [&ret](const auto c) { ret += c->memoryUsage(); }); + std::ranges::for_each(each_enabled_and_not_mustrun(), + [&ret](const auto c) { ret += c->memoryUsage(); }); return ret; } @@ -73,18 +76,22 @@ static bool ThermalClusterLoadFromSection(const AnyString& filename, void ThermalClusterList::rebuildIndex() const { uint indx = 0; - for (auto& c : each_enabled_and_not_mustrun()) + for (auto& c: each_enabled_and_not_mustrun()) + { c->index = indx++; + } } unsigned int ThermalClusterList::enabledAndNotMustRunCount() const { - return std::ranges::count_if(allClusters_, [](auto c) { return c->isEnabled() && !c->isMustRun(); }); + return std::ranges::count_if(allClusters_, + [](auto c) { return c->isEnabled() && !c->isMustRun(); }); } unsigned int ThermalClusterList::enabledAndMustRunCount() const { - return std::ranges::count_if(allClusters_, [](auto c) { return c->isEnabled() && c->isMustRun(); }); + return std::ranges::count_if(allClusters_, + [](auto c) { return c->isEnabled() && c->isMustRun(); }); } bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, Area* area) @@ -98,19 +105,25 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A study.buffer.clear() << folder << SEP << "list.ini"; IniFile ini; if (!ini.open(study.buffer)) + { return false; + } bool ret = true; if (!ini.firstSection) + { return ret; + } String modulationFile; for (auto* section = ini.firstSection; section; section = section->next) { if (section->name.empty()) + { continue; + } auto cluster = std::make_shared(area); @@ -137,17 +150,19 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A // allow startup cost between [-5 000 000 ;-5 000 000] (was [-50 000;50 000]) // Modulation - modulationFile.clear() << folder << SEP << ".." << SEP << ".." << SEP << "prepro" - << SEP << cluster->parentArea->id << SEP << cluster->id() - << SEP << "modulation." << study.inputExtension; - + modulationFile.clear() << folder << SEP << ".." << SEP << ".." << SEP << "prepro" << SEP + << cluster->parentArea->id << SEP << cluster->id() << SEP + << "modulation." << study.inputExtension; enum { options = Matrix<>::optFixedSize, }; - bool r = cluster->modulation.loadFromCSVFile( - modulationFile, thermalModulationMax, HOURS_PER_YEAR, options); + + bool r = cluster->modulation.loadFromCSVFile(modulationFile, + thermalModulationMax, + HOURS_PER_YEAR, + options); if (!r && study.usedByTheSolver) { cluster->modulation.reset(thermalModulationMax, HOURS_PER_YEAR); @@ -160,7 +175,9 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A if (study.usedByTheSolver) { if (!study.parameters.include.thermal.minStablePower) + { cluster->minStablePower = 0.; + } if (!study.parameters.include.thermal.minUPTime) { cluster->minUpDownTime = 1; @@ -168,11 +185,14 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A cluster->minDownTime = 1; } else - cluster->minUpDownTime - = std::max(cluster->minUpTime, cluster->minDownTime); + { + cluster->minUpDownTime = std::max(cluster->minUpTime, cluster->minDownTime); + } if (!study.parameters.include.reserve.spinning) + { cluster->spinning = 0; + } cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; } @@ -191,15 +211,25 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A static bool ThermalClusterLoadFromProperty(ThermalCluster& cluster, const IniFile::Property* p) { if (p->key.empty()) + { return false; + } if (p->key == "costgeneration") + { return p->value.to(cluster.costgeneration); + } if (p->key == "enabled") + { return p->value.to(cluster.enabled); + } if (p->key == "efficiency") + { return p->value.to(cluster.fuelEfficiency); + } if (p->key == "fixed-cost") + { return p->value.to(cluster.fixedCost); + } if (p->key == "group") { @@ -211,27 +241,43 @@ static bool ThermalClusterLoadFromProperty(ThermalCluster& cluster, const IniFil return p->value.to(cluster.tsGenBehavior); } if (p->key == "law.planned") + { return p->value.to(cluster.plannedLaw); + } if (p->key == "law.forced") + { return p->value.to(cluster.forcedLaw); + } if (p->key == "market-bid-cost") + { return p->value.to(cluster.marketBidCost); + } if (p->key == "marginal-cost") + { return p->value.to(cluster.marginalCost); + } if (p->key == "must-run") + { // mustrunOrigin will be initialized later, after LoadFromSection return p->value.to(cluster.mustrun); + } if (p->key == "min-stable-power") + { return p->value.to(cluster.minStablePower); + } if (p->key == "min-up-time") { if (p->value.to(cluster.minUpTime)) { if (cluster.minUpTime < 1) + { cluster.minUpTime = 1; + } if (cluster.minUpTime > 168) + { cluster.minUpTime = 168; + } return true; } return false; @@ -241,37 +287,61 @@ static bool ThermalClusterLoadFromProperty(ThermalCluster& cluster, const IniFil if (p->value.to(cluster.minDownTime)) { if (cluster.minDownTime < 1) + { cluster.minDownTime = 1; + } if (cluster.minDownTime > 168) + { cluster.minDownTime = 168; + } return true; } return false; } if (p->key == "name") + { return true; // silently ignore it + } if (p->key == "nominalcapacity") + { return p->value.to(cluster.nominalCapacity); + } if (p->key == "spread-cost") + { return p->value.to(cluster.spreadCost); + } if (p->key == "spinning") + { return p->value.to(cluster.spinning); + } if (p->key == "startup-cost") + { return p->value.to(cluster.startupCost); + } if (p->key == "unitcount") + { return p->value.to(cluster.unitCount); + } if (p->key == "volatility.planned") + { return p->value.to(cluster.plannedVolatility); + } if (p->key == "volatility.forced") + { return p->value.to(cluster.forcedVolatility); + } if (p->key == "variableomcost") + { return p->value.to(cluster.variableomcost); + } - //pollutant + // pollutant if (auto it = Pollutant::namesToEnum.find(p->key.c_str()); it != Pollutant::namesToEnum.end()) - return p->value.to (cluster.emissions.factors[it->second]); + { + return p->value.to(cluster.emissions.factors[it->second]); + } // The property is unknown return false; @@ -282,7 +352,9 @@ bool ThermalClusterLoadFromSection(const AnyString& filename, const IniFile::Section& section) { if (section.name.empty()) + { return false; + } cluster.setName(section.name); @@ -311,27 +383,37 @@ bool ThermalClusterLoadFromSection(const AnyString& filename, void ThermalClusterList::calculationOfSpinning() { - for (auto& cluster : each_enabled()) + for (auto& cluster: each_enabled()) + { cluster->calculationOfSpinning(); + } } void ThermalClusterList::reverseCalculationOfSpinning() { - for (auto& cluster : each_enabled()) + for (auto& cluster: each_enabled()) + { cluster->reverseCalculationOfSpinning(); + } } void ThermalClusterList::enableMustrunForEveryone() { - for (auto& c : allClusters_) + for (auto& c: allClusters_) + { c->mustrun = true; + } } void ThermalClusterList::ensureDataPrepro() { - for (const auto& c : all()) + for (const auto& c: all()) + { if (!c->prepro) + { c->prepro = new PreproAvailability(c->id(), c->unitCount); + } + } } bool ThermalClusterList::saveToFolder(const AnyString& folder) const @@ -348,7 +430,7 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const // Allocate the inifile structure IniFile ini; - for (auto& c : allClusters_) + for (auto& c: allClusters_) { // Adding a section to the inifile IniFile::Section* s = ini.addSection(c->name()); @@ -358,13 +440,21 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const s->add("name", c->name()); if (!c->group().empty()) + { s->add("group", c->group()); + } if (!c->enabled) + { s->add("enabled", "false"); + } if (!Utils::isZero(c->unitCount)) + { s->add("unitCount", c->unitCount); + } if (!Utils::isZero(c->nominalCapacity)) + { s->add("nominalCapacity", c->nominalCapacity); + } // TS generation if (c->tsGenBehavior != LocalTSGenerationBehavior::useGlobalParameter) { @@ -372,72 +462,107 @@ bool ThermalClusterList::saveToFolder(const AnyString& folder) const } // Min. Stable Power if (!Utils::isZero(c->minStablePower)) + { s->add("min-stable-power", c->minStablePower); + } // Min up and min down time if (c->minUpTime != 1) + { s->add("min-up-time", c->minUpTime); + } if (c->minDownTime != 1) + { s->add("min-down-time", c->minDownTime); + } // must-run if (c->mustrun) + { s->add("must-run", "true"); + } // spinning if (!Utils::isZero(c->spinning)) + { s->add("spinning", c->spinning); + } // efficiency if (c->fuelEfficiency != 100.0) + { s->add("efficiency", c->fuelEfficiency); + } // volatility if (!Utils::isZero(c->forcedVolatility)) + { s->add("volatility.forced", Utils::round(c->forcedVolatility, 3)); + } if (!Utils::isZero(c->plannedVolatility)) + { s->add("volatility.planned", Utils::round(c->plannedVolatility, 3)); + } // laws if (c->forcedLaw != LawUniform) + { s->add("law.forced", c->forcedLaw); + } if (c->plannedLaw != LawUniform) + { s->add("law.planned", c->plannedLaw); + } // costs if (c->costgeneration != setManually) + { s->add("costgeneration", c->costgeneration); + } if (!Utils::isZero(c->marginalCost)) + { s->add("marginal-cost", Utils::round(c->marginalCost, 3)); + } if (!Utils::isZero(c->spreadCost)) + { s->add("spread-cost", c->spreadCost); + } if (!Utils::isZero(c->fixedCost)) + { s->add("fixed-cost", Utils::round(c->fixedCost, 3)); + } if (!Utils::isZero(c->startupCost)) + { s->add("startup-cost", Utils::round(c->startupCost, 3)); + } if (!Utils::isZero(c->marketBidCost)) + { s->add("market-bid-cost", Utils::round(c->marketBidCost, 3)); + } if (!Utils::isZero(c->variableomcost)) + { s->add("variableomcost", Utils::round(c->variableomcost, 3)); + } - - //pollutant factor - for (auto const& [key, val] : Pollutant::namesToEnum) + // pollutant factor + for (const auto& [key, val]: Pollutant::namesToEnum) + { s->add(key, c->emissions.factors[val]); - + } buffer.clear() << folder << SEP << ".." << SEP << ".." << SEP << "prepro" << SEP - << c->parentArea->id << SEP << c->id(); + << c->parentArea->id << SEP << c->id(); if (IO::Directory::Create(buffer)) { buffer.clear() << folder << SEP << ".." << SEP << ".." << SEP << "prepro" << SEP - << c->parentArea->id << SEP << c->id() << SEP << "modulation.txt"; + << c->parentArea->id << SEP << c->id() << SEP << "modulation.txt"; ret = c->modulation.saveToCSVFile(buffer) && ret; } else + { ret = false; - + } // Write the ini file buffer.clear() << folder << SEP << "list.ini"; @@ -452,7 +577,7 @@ bool ThermalClusterList::savePreproToFolder(const AnyString& folder) const Clob buffer; bool ret = true; - for (auto& c : allClusters_) + for (auto& c: allClusters_) { if (c->prepro) { @@ -469,7 +594,7 @@ bool ThermalClusterList::saveEconomicCosts(const AnyString& folder) const Clob buffer; bool ret = true; - for (auto& c : allClusters_) + for (auto& c: allClusters_) { assert(c->parentArea && "cluster: invalid parent area"); buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); @@ -480,8 +605,8 @@ bool ThermalClusterList::saveEconomicCosts(const AnyString& folder) const bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& folder) { - const bool globalThermalTSgeneration - = study.parameters.timeSeriesToGenerate & timeSeriesThermal; + const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate + & timeSeriesThermal; Clob buffer; auto hasPrepro = [](auto c) { return (bool)c->prepro; }; @@ -505,22 +630,23 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, const AnyString& fol return result; }; - return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), - loadAndCheckPrepro); + return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadAndCheckPrepro); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) { - return std::ranges::all_of(allClusters_, [&study, folder](const auto& c) - { - assert(c->parentArea && "cluster: invalid parent area"); - Clob buffer; - buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); - - bool result = c->ecoInput.loadFromFolder(study, buffer); - c->ComputeCostTimeSeries(); - return result; - }); + return std::ranges::all_of(allClusters_, + [&study, folder](const auto& c) + { + assert(c->parentArea && "cluster: invalid parent area"); + Clob buffer; + buffer.clear() + << folder << SEP << c->parentArea->id << SEP << c->id(); + + bool result = c->ecoInput.loadFromFolder(study, buffer); + c->ComputeCostTimeSeries(); + return result; + }); } } // namespace Data diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index c536302581..a53d9870e6 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -21,24 +21,23 @@ #ifndef __SOLVER_SIMULATION_SOLVER_HXX__ #define __SOLVER_SIMULATION_SOLVER_HXX__ -#include "antares/solver//variable/constants.h" -#include -#include +#include +#include +#include + +#include #include +#include #include +#include +#include "antares/concurrency/concurrency.h" +#include "antares/solver//variable/constants.h" #include "antares/solver//variable/print.h" -#include -#include "antares/solver/simulation/timeseries-numbers.h" +#include "antares/solver/hydro/management/management.h" // Added for use of randomReservoirLevel(...) #include "antares/solver/simulation/apply-scenario.h" -#include -#include "antares/solver/ts-generator/generator.h" #include "antares/solver/simulation/opt_time_writer.h" -#include "antares/solver/hydro/management/management.h" // Added for use of randomReservoirLevel(...) - -#include -#include - -#include "antares/concurrency/concurrency.h" +#include "antares/solver/simulation/timeseries-numbers.h" +#include "antares/solver/ts-generator/generator.h" namespace Antares::Solver::Simulation { @@ -59,32 +58,32 @@ public: std::vector& pState, bool pYearByYear, Benchmarking::IDurationCollector& durationCollector, - IResultWriter& resultWriter) : - simulation_(simulation), - y(pY), - yearFailed(pYearFailed), - isFirstPerformedYearOfASet(pIsFirstPerformedYearOfASet), - firstSetParallelWithAPerformedYearWasRun(pFirstSetParallelWithAPerformedYearWasRun), - numSpace(pNumSpace), - randomForParallelYears(pRandomForParallelYears), - performCalculations(pPerformCalculations), - study(pStudy), - state(pState), - yearByYear(pYearByYear), - pDurationCollector(durationCollector), - pResultWriter(resultWriter), - hydroManagement(study.areas, - study.parameters, - study.calendar, - study.maxNbYearsInParallel, - resultWriter) + IResultWriter& resultWriter): + simulation_(simulation), + y(pY), + yearFailed(pYearFailed), + isFirstPerformedYearOfASet(pIsFirstPerformedYearOfASet), + firstSetParallelWithAPerformedYearWasRun(pFirstSetParallelWithAPerformedYearWasRun), + numSpace(pNumSpace), + randomForParallelYears(pRandomForParallelYears), + performCalculations(pPerformCalculations), + study(pStudy), + state(pState), + yearByYear(pYearByYear), + pDurationCollector(durationCollector), + pResultWriter(resultWriter), + hydroManagement(study.areas, + study.parameters, + study.calendar, + study.maxNbYearsInParallel, + resultWriter) { hydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); scratchmap = study.areas.buildScratchMap(numSpace); } yearJob(const yearJob&) = delete; - yearJob& operator =(const yearJob&) = delete; + yearJob& operator=(const yearJob&) = delete; ~yearJob() = default; private: @@ -104,6 +103,7 @@ private: IResultWriter& pResultWriter; HydroManagement hydroManagement; Antares::Data::Area::ScratchMap scratchmap; + private: /* ** \brief Log failed week @@ -124,8 +124,8 @@ private: std::string s = failedWeekStr.str(); s = s.substr(0, s.length() - 1); // get rid of the trailing space - std::string failedStr - = failedWeekList.size() != 1 ? " failed at weeks " : " failed at week "; + std::string failedStr = failedWeekList.size() != 1 ? " failed at weeks " + : " failed at week "; logs.info(); // empty line @@ -156,9 +156,14 @@ public: // 1 - Applying random levels for current year if (hydroHotStart && firstSetParallelWithAPerformedYearWasRun) - randomReservoirLevel = state[numSpace].problemeHebdo->previousYearFinalLevels.data(); + { + randomReservoirLevel = state[numSpace] + .problemeHebdo->previousYearFinalLevels.data(); + } else + { randomReservoirLevel = randomForCurrentYear.pReservoirLevels; + } // 2 - Preparing the Time-series numbers // removed @@ -179,8 +184,8 @@ public: simulation_->variables.yearBegin(y, numSpace); // 6 - The Solver itself - bool isFirstPerformedYearOfSimulation - = isFirstPerformedYearOfASet[y] && not firstSetParallelWithAPerformedYearWasRun; + bool isFirstPerformedYearOfSimulation = isFirstPerformedYearOfASet[y] + && not firstSetParallelWithAPerformedYearWasRun; std::list failedWeekList; OptimizationStatisticsWriter optWriter(pResultWriter, y); @@ -234,12 +239,12 @@ public: } // End of onExecute() method }; - template -inline ISimulation::ISimulation(Data::Study& study, - const ::Settings& settings, - Benchmarking::IDurationCollector& duration_collector, - IResultWriter& resultWriter) : +inline ISimulation::ISimulation( + Data::Study& study, + const ::Settings& settings, + Benchmarking::IDurationCollector& duration_collector, + IResultWriter& resultWriter): ImplementationType(study, resultWriter), study(study), settings(settings), @@ -260,7 +265,9 @@ inline ISimulation::ISimulation(Data::Study& study, logs.info() << "Allocating resources..."; if (pYearByYear && (settings.noOutput || settings.tsGeneratorsOnly)) + { pYearByYear = false; + } pHydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); } @@ -327,7 +334,9 @@ void ISimulation::run() else { if (not ImplementationType::simulationBegin()) + { return; + } // Allocating the memory ImplementationType::variables.simulationBegin(); @@ -346,7 +355,9 @@ void ISimulation::run() } if (study.parameters.useCustomScenario) + { ApplyCustomScenario(study); + } // Launching the simulation for all years logs.info() << "MC-Years : [" << (study.runtime->rangeLimits.year[Data::rangeBegin] + 1) @@ -357,7 +368,9 @@ void ISimulation::run() std::vector state(pNbMaxPerformedYearsInParallel, Variable::State(study)); // Initializing states for parallel actually performed years for (uint numSpace = 0; numSpace != pNbMaxPerformedYearsInParallel; ++numSpace) + { ImplementationType::initializeState(state[numSpace], numSpace); + } logs.info() << " Starting the simulation"; uint finalYear = 1 + study.runtime->rangeLimits.year[Data::rangeEnd]; @@ -426,7 +439,9 @@ void ISimulation::writeResults(bool synthesis, uint year, ui String newPath; newPath << ImplementationType::Name() << IO::Separator; if (synthesis) + { newPath << "mc-all"; + } else { CString<10, false> tmp; @@ -436,8 +451,10 @@ void ISimulation::writeResults(bool synthesis, uint year, ui } // Dumping - ImplementationType::variables.exportSurveyResults( - synthesis, newPath, numSpace, pResultWriter); + ImplementationType::variables.exportSurveyResults(synthesis, + newPath, + numSpace, + pResultWriter); } } @@ -490,14 +507,16 @@ void ISimulation::regenerateTimeSeries(uint year) { auto clusters = getAllClustersToGen(study.areas, pData.haveToRefreshTSThermal); #define SEP Yuni::IO::Separator - const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + - "mc-" + std::to_string(year); + const std::string savePath = std::string("ts-generator") + SEP + "thermal" + SEP + "mc-" + + std::to_string(year); #undef SEP generateThermalTimeSeries(study, clusters, pResultWriter, savePath); // apply the spinning if we generated some in memory clusters - for (auto* cluster : clusters) + for (auto* cluster: clusters) + { cluster->calculationOfSpinning(); + } } timer.stop(); @@ -530,19 +549,19 @@ uint ISimulation::buildSetsOfParallelYears( // created bool refreshing = false; refreshing = pData.haveToRefreshTSLoad && (y % pData.refreshIntervalLoad == 0); - refreshing - = refreshing || (pData.haveToRefreshTSSolar && (y % pData.refreshIntervalSolar == 0)); - refreshing - = refreshing || (pData.haveToRefreshTSWind && (y % pData.refreshIntervalWind == 0)); - refreshing - = refreshing || (pData.haveToRefreshTSHydro && (y % pData.refreshIntervalHydro == 0)); + refreshing = refreshing + || (pData.haveToRefreshTSSolar && (y % pData.refreshIntervalSolar == 0)); + refreshing = refreshing + || (pData.haveToRefreshTSWind && (y % pData.refreshIntervalWind == 0)); + refreshing = refreshing + || (pData.haveToRefreshTSHydro && (y % pData.refreshIntervalHydro == 0)); // Some thermal clusters may override the global parameter. // Therefore, we may want to refresh TS even if pData.haveToRefreshTSThermal == false - bool haveToRefreshTSThermal - = pData.haveToRefreshTSThermal || study.runtime->thermalTSRefresh; - refreshing - = refreshing || (haveToRefreshTSThermal && (y % pData.refreshIntervalThermal == 0)); + bool haveToRefreshTSThermal = pData.haveToRefreshTSThermal + || study.runtime->thermalTSRefresh; + refreshing = refreshing + || (haveToRefreshTSThermal && (y % pData.refreshIntervalThermal == 0)); // We build a new set of parallel years if one of these conditions is fulfilled : // - We have to refresh (or regenerate) some or all time series before running the @@ -609,10 +628,14 @@ uint ISimulation::buildSetsOfParallelYears( buildNewSet = true; foundFirstPerformedYearOfCurrentSet = false; if (set->nbPerformedYears > maxNbYearsPerformed) + { maxNbYearsPerformed = set->nbPerformedYears; + } } else + { buildNewSet = false; + } } // End of loop over years @@ -620,7 +643,8 @@ uint ISimulation::buildSetsOfParallelYears( } template -void ISimulation::allocateMemoryForRandomNumbers(randomNumbers& randomForParallelYears) +void ISimulation::allocateMemoryForRandomNumbers( + randomNumbers& randomForParallelYears) { uint maxNbPerformedYears = randomForParallelYears.pMaxNbPerformedYears; uint nbAreas = study.areas.size(); @@ -657,7 +681,9 @@ void ISimulation::allocateMemoryForRandomNumbers(randomNumbe { randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod = new double*[nbAreas]; for (uint a = 0; a != nbAreas; ++a) + { randomForParallelYears.pYears[y].pHydroCostsByArea_freeMod[a] = new double[8784]; + } break; } case Data::lssMinimizeRamping: @@ -676,10 +702,11 @@ void ISimulation::allocateMemoryForRandomNumbers(randomNumbe } template -void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, - std::vector& years, - std::map& isYearPerformed, - MersenneTwister& randomHydroGenerator) +void ISimulation::computeRandomNumbers( + randomNumbers& randomForYears, + std::vector& years, + std::map& isYearPerformed, + MersenneTwister& randomHydroGenerator) { auto& runtime = *study.runtime; @@ -691,7 +718,9 @@ void ISimulation::computeRandomNumbers(randomNumbers& random uint y = *ity; bool isPerformed = isYearPerformed[y]; if (isPerformed) + { randomForYears.yearNumberToIndex[y] = indexYear; + } // General const unsigned int nbAreas = study.areas.size(); @@ -702,74 +731,86 @@ void ISimulation::computeRandomNumbers(randomNumbers& random // logs.info() << " area : " << a << " :"; const auto& area = *(study.areas.byIndex[a]); - for (auto& cluster : area.thermal.list.all()) + for (auto& cluster: area.thermal.list.all()) { uint clusterIndex = cluster->areaWideIndex; double thermalNoise = runtime.random[Data::seedThermalCosts].next(); if (isPerformed) - randomForYears.pYears[indexYear].pThermalNoisesByArea[a][clusterIndex] = thermalNoise; + { + randomForYears.pYears[indexYear].pThermalNoisesByArea[a][clusterIndex] + = thermalNoise; + } } } // ... Reservoir levels ... uint areaIndex = 0; - study.areas.each([&](Data::Area& area) { - // looking for the initial reservoir level (begining of the year) - auto& min = area.hydro.reservoirLevel[Data::PartHydro::minimum]; - auto& avg = area.hydro.reservoirLevel[Data::PartHydro::average]; - auto& max = area.hydro.reservoirLevel[Data::PartHydro::maximum]; - - // Month the reservoir level is initialized according to. - // This month number is given in the civil calendar, from january to december (0 is - // january). - int initResLevelOnMonth = area.hydro.initializeReservoirLevelDate; - - // Conversion of the previous month into simulation calendar - int initResLevelOnSimMonth = study.calendar.mapping.months[initResLevelOnMonth]; - - // Previous month's first day in the year - int firstDayOfMonth = study.calendar.months[initResLevelOnSimMonth].daysYear.first; - - double randomLevel = randomReservoirLevel(min[firstDayOfMonth], - avg[firstDayOfMonth], - max[firstDayOfMonth], - randomHydroGenerator); - - // Possibly update the intial level from scenario builder - if (study.parameters.useCustomScenario) - { - double levelFromScenarioBuilder = study.scenarioHydroLevels[areaIndex][y]; - if (levelFromScenarioBuilder >= 0.) - randomLevel = levelFromScenarioBuilder; - } - - if (pHydroHotStart) - { - if (!isPerformed || !area.hydro.reservoirManagement) - { - // This initial level should be unused, so -1, as impossible value, is suitable. - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = -1.; - areaIndex++; - return; // Skipping the current area - } - - if (!pFirstSetParallelWithAPerformedYearWasRun) - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; - // Else : means the start levels (multiple areas are affected) of a year are - // retrieved from a previous year and - // these levels are updated inside the year job (see year job). - } - else - { - // Current area's hydro starting (or initial) level computation - // (no matter if the year is performed or not, we always draw a random initial - // reservoir level to ensure the same results) - if (isPerformed) - randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; - } - - areaIndex++; - }); // each area + study.areas.each( + [&](Data::Area& area) + { + // looking for the initial reservoir level (begining of the year) + auto& min = area.hydro.reservoirLevel[Data::PartHydro::minimum]; + auto& avg = area.hydro.reservoirLevel[Data::PartHydro::average]; + auto& max = area.hydro.reservoirLevel[Data::PartHydro::maximum]; + + // Month the reservoir level is initialized according to. + // This month number is given in the civil calendar, from january to december (0 is + // january). + int initResLevelOnMonth = area.hydro.initializeReservoirLevelDate; + + // Conversion of the previous month into simulation calendar + int initResLevelOnSimMonth = study.calendar.mapping.months[initResLevelOnMonth]; + + // Previous month's first day in the year + int firstDayOfMonth = study.calendar.months[initResLevelOnSimMonth].daysYear.first; + + double randomLevel = randomReservoirLevel(min[firstDayOfMonth], + avg[firstDayOfMonth], + max[firstDayOfMonth], + randomHydroGenerator); + + // Possibly update the intial level from scenario builder + if (study.parameters.useCustomScenario) + { + double levelFromScenarioBuilder = study.scenarioHydroLevels[areaIndex][y]; + if (levelFromScenarioBuilder >= 0.) + { + randomLevel = levelFromScenarioBuilder; + } + } + + if (pHydroHotStart) + { + if (!isPerformed || !area.hydro.reservoirManagement) + { + // This initial level should be unused, so -1, as impossible value, is + // suitable. + randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = -1.; + areaIndex++; + return; // Skipping the current area + } + + if (!pFirstSetParallelWithAPerformedYearWasRun) + { + randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; + } + // Else : means the start levels (multiple areas are affected) of a year are + // retrieved from a previous year and + // these levels are updated inside the year job (see year job). + } + else + { + // Current area's hydro starting (or initial) level computation + // (no matter if the year is performed or not, we always draw a random initial + // reservoir level to ensure the same results) + if (isPerformed) + { + randomForYears.pYears[indexYear].pReservoirLevels[areaIndex] = randomLevel; + } + } + + areaIndex++; + }); // each area // ... Unsupplied and spilled energy costs noises (french : bruits sur la defaillance // positive et negatives) ... references to the random number generators @@ -781,25 +822,31 @@ void ISimulation::computeRandomNumbers(randomNumbers& random + Data::seedSpilledEnergyCosts * Data::antaresSeedIncrement; bool SpilledEnergySeedIsDefault = (currentSpilledEnergySeed == defaultSpilledEnergySeed); areaIndex = 0; - study.areas.each([&](Data::Area& area) { - (void)area; // Avoiding warnings at compilation (unused variable) on linux - if (isPerformed) - { - double randomNumber = randomUnsupplied(); - randomForYears.pYears[indexYear].pUnsuppliedEnergy[areaIndex] = randomNumber; - randomForYears.pYears[indexYear].pSpilledEnergy[areaIndex] = randomNumber; - if (!SpilledEnergySeedIsDefault) - randomForYears.pYears[indexYear].pSpilledEnergy[areaIndex] = randomSpilled(); - } - else - { - randomUnsupplied(); - if (!SpilledEnergySeedIsDefault) - randomSpilled(); - } - - areaIndex++; - }); // each area + study.areas.each( + [&](Data::Area& area) + { + (void)area; // Avoiding warnings at compilation (unused variable) on linux + if (isPerformed) + { + double randomNumber = randomUnsupplied(); + randomForYears.pYears[indexYear].pUnsuppliedEnergy[areaIndex] = randomNumber; + randomForYears.pYears[indexYear].pSpilledEnergy[areaIndex] = randomNumber; + if (!SpilledEnergySeedIsDefault) + { + randomForYears.pYears[indexYear].pSpilledEnergy[areaIndex] = randomSpilled(); + } + } + else + { + randomUnsupplied(); + if (!SpilledEnergySeedIsDefault) + { + randomSpilled(); + } + } + + areaIndex++; + }); // each area // ... Hydro costs noises ... auto& randomHydro = study.runtime->random[Data::seedHydroCosts]; @@ -818,8 +865,8 @@ void ISimulation::computeRandomNumbers(randomNumbers& random { for (auto i = study.areas.begin(); i != end; ++i) { - double* noise - = randomForYears.pYears[indexYear].pHydroCostsByArea_freeMod[areaIndex]; + double* noise = randomForYears.pYears[indexYear] + .pHydroCostsByArea_freeMod[areaIndex]; std::set setHydroCostsNoises; for (uint j = 0; j != 8784; ++j) { @@ -839,9 +886,13 @@ void ISimulation::computeRandomNumbers(randomNumbers& random double value = it->getValue(); if (value < 0.) + { noise[index] = -5 * 1.e-4 * (1 + rank / 8784.); + } else + { noise[index] = 5 * 1.e-4 * (1 + rank / 8784.); + } rank++; } @@ -850,9 +901,15 @@ void ISimulation::computeRandomNumbers(randomNumbers& random } } else + { for (auto i = study.areas.begin(); i != end; ++i) + { for (uint j = 0; j != 8784; ++j) + { randomHydro(); + } + } + } break; } @@ -865,10 +922,14 @@ void ISimulation::computeRandomNumbers(randomNumbers& random for (auto i = study.areas.begin(); i != end; ++i) { if (isPerformed) + { randomForYears.pYears[indexYear].pHydroCosts_rampingOrExcursion[areaIndex] = randomHydro(); + } else + { randomHydro(); + } areaIndex++; } @@ -884,7 +945,9 @@ void ISimulation::computeRandomNumbers(randomNumbers& random } // end of switch if (isPerformed) + { indexYear++; + } } // End loop over years } // End function @@ -921,18 +984,23 @@ static inline void logPerformedYearsInAset(setOfParallelYears& set) << " perfomed)"; std::string performedYearsToLog = ""; - std::for_each(std::begin(set.yearsIndices), std::end(set.yearsIndices), [&](uint const& y) { - if (set.isYearPerformed[y]) - performedYearsToLog += std::to_string(y + 1) + " "; - }); + std::for_each(std::begin(set.yearsIndices), + std::end(set.yearsIndices), + [&](const uint& y) + { + if (set.isYearPerformed[y]) + { + performedYearsToLog += std::to_string(y + 1) + " "; + } + }); logs.info() << "Year(s) " << performedYearsToLog; } template void ISimulation::loopThroughYears(uint firstYear, - uint endYear, - std::vector& state) + uint endYear, + std::vector& state) { assert(endYear <= study.parameters.nbYears); @@ -947,8 +1015,9 @@ void ISimulation::loopThroughYears(uint firstYear, // in a set The variable "maxNbYearsPerformedInAset" is the maximum numbers of years to be // actually executed in a set. A set contains some years to be actually executed (at most // "pNbMaxPerformedYearsInParallel" years) and some others to skip. - uint maxNbYearsPerformedInAset - = buildSetsOfParallelYears(firstYear, endYear, setsOfParallelYears); + uint maxNbYearsPerformedInAset = buildSetsOfParallelYears(firstYear, + endYear, + setsOfParallelYears); // Related to annual costs statistics (printed in output into separate files) pAnnualStatistics.setNbPerformedYears(pNbYearsReallyPerformed); @@ -970,9 +1039,13 @@ void ISimulation::loopThroughYears(uint firstYear, // This is the case when the preprocessors are enabled from the // interface and/or the refresh is enabled. if (set_it->regenerateTS) + { regenerateTimeSeries(set_it->yearForTSgeneration); + } - computeRandomNumbers(randomForParallelYears, set_it->yearsIndices, set_it->isYearPerformed, + computeRandomNumbers(randomForParallelYears, + set_it->yearsIndices, + set_it->isYearPerformed, randomHydroGenerator); std::vector::iterator year_it; @@ -998,19 +1071,20 @@ void ISimulation::loopThroughYears(uint firstYear, // have to be rerun (meaning : they must be run once). if(!set_it->yearFailed[y]) // continue; - auto task = std::make_shared>(this, - y, - set_it->yearFailed, - set_it->isFirstPerformedYearOfASet, - pFirstSetParallelWithAPerformedYearWasRun, - numSpace, - randomForParallelYears, - performCalculations, - study, - state, - pYearByYear, - pDurationCollector, - pResultWriter); + auto task = std::make_shared>( + this, + y, + set_it->yearFailed, + set_it->isFirstPerformedYearOfASet, + pFirstSetParallelWithAPerformedYearWasRun, + numSpace, + randomForParallelYears, + performCalculations, + study, + state, + pYearByYear, + pDurationCollector, + pResultWriter); results.add(Concurrency::AddTask(*pQueueService, task)); } // End loop over years of the current set of parallel years @@ -1025,10 +1099,12 @@ void ISimulation::loopThroughYears(uint firstYear, // At this point, the first set of parallel year(s) was run with at least one year performed if (!pFirstSetParallelWithAPerformedYearWasRun && yearPerformed) + { pFirstSetParallelWithAPerformedYearWasRun = true; + } // On regarde si au moins une année du lot n'a pas trouvé de solution - for (auto& [year, failed] : set_it->yearFailed) + for (auto& [year, failed]: set_it->yearFailed) { // Si une année du lot d'années n'a pas trouvé de solution, on arrête tout if (failed) @@ -1044,8 +1120,9 @@ void ISimulation::loopThroughYears(uint firstYear, set_it->nbPerformedYears); // Computing summary of spatial aggregations - ImplementationType::variables.computeSpatialAggregatesSummary( - ImplementationType::variables, set_it->spaceToPerformedYear, set_it->nbPerformedYears); + ImplementationType::variables.computeSpatialAggregatesSummary(ImplementationType::variables, + set_it->spaceToPerformedYear, + set_it->nbPerformedYears); // Computes statistics on annual (system and solution) costs, to be printed in output into // separate files diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index f0dc2cd324..4af0573f04 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -19,16 +19,15 @@ ** along with Antares_Simulator. If not, see . */ +#include #include #include -#include -#include #include -#include - #include #include +#include +#include #include "antares/study/simulation.h" #define SEP Yuni::IO::Separator @@ -37,33 +36,33 @@ constexpr double FAILURE_RATE_EQ_1 = 0.999; namespace Antares::TSGenerator { -AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* source) : - unitCount(source->unitCount), - nominalCapacity(source->nominalCapacity), - forcedVolatility(source->forcedVolatility), - plannedVolatility(source->plannedVolatility), - forcedLaw(source->forcedLaw), - plannedLaw(source->plannedLaw), - prepro(source->prepro), - series(source->series.timeSeries), - modulationCapacity(source->modulation[Data::thermalModulationCapacity]), - name(source->name()) +AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* source): + unitCount(source->unitCount), + nominalCapacity(source->nominalCapacity), + forcedVolatility(source->forcedVolatility), + plannedVolatility(source->plannedVolatility), + forcedLaw(source->forcedLaw), + plannedLaw(source->plannedLaw), + prepro(source->prepro), + series(source->series.timeSeries), + modulationCapacity(source->modulation[Data::thermalModulationCapacity]), + name(source->name()) { } AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, Data::TimeSeries& capacity, - const std::string& areaDestName) : - unitCount(source.unitCount), - nominalCapacity(source.nominalCapacity), - forcedVolatility(source.forcedVolatility), - plannedVolatility(source.plannedVolatility), - forcedLaw(source.forcedLaw), - plannedLaw(source.plannedLaw), - prepro(source.prepro.get()), - series(capacity.timeSeries), - modulationCapacity(source.modulationCapacity[0]), - name(areaDestName) + const std::string& areaDestName): + unitCount(source.unitCount), + nominalCapacity(source.nominalCapacity), + forcedVolatility(source.forcedVolatility), + plannedVolatility(source.plannedVolatility), + forcedLaw(source.forcedLaw), + plannedLaw(source.plannedLaw), + prepro(source.prepro.get()), + series(capacity.timeSeries), + modulationCapacity(source.modulationCapacity[0]), + name(areaDestName) { } @@ -85,7 +84,11 @@ class GeneratorTempData final static constexpr int Log_size = 4000; - int durationGenerator(Data::StatisticalLaw law, int expec, double volat, double a, double b) const; + int durationGenerator(Data::StatisticalLaw law, + int expec, + double volat, + double a, + double b) const; template void prepareIndispoFromLaw(Data::StatisticalLaw law, @@ -95,11 +98,12 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen) : - derated(study.parameters.derated), - nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]) -{} +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen): + derated(study.parameters.derated), + nbOfSeriesToGen_(nbOfSeriesToGen), + rndgenerator(study.runtime->random[Data::seedTsGenThermal]) +{ +} template void GeneratorTempData::prepareIndispoFromLaw(Data::StatisticalLaw law, @@ -154,7 +158,9 @@ int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, double b) const { if (volat == 0 || expec == 1) + { return expec; + } double rndnumber = rndgenerator.next(); switch (law) @@ -176,7 +182,8 @@ int GeneratorTempData::durationGenerator(Data::StatisticalLaw law, return 0; } -void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const +void GeneratorTempData::generateTS(const Data::Area& area, + AvailabilityTSGeneratorData& cluster) const { if (!cluster.prepro) { @@ -190,7 +197,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat assert(cluster.prepro); if (0 == cluster.unitCount || 0 == cluster.nominalCapacity) + { return; + } const auto& preproData = *(cluster.prepro); @@ -246,10 +255,14 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat lp[d] = POR[d] / (POR[d] + (PODOfTheDay) * (1. - POR[d])); if (0. < lf[d] && lf[d] < lp[d]) + { lf[d] *= (1. - lp[d]) / (1. - lf[d]); + } if (0. < lp[d] && lp[d] < lf[d]) + { lp[d] *= (1. - lf[d]) / (1. - lp[d]); + } double a = 0.; double b = 0.; @@ -307,7 +320,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat uint hour = 0; if (tsIndex > 1) + { dstSeries = cluster.series[tsIndex - 2]; + } for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) { @@ -333,7 +348,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat for (int index = 1; index < Log_size; ++index) { if (cumul_retour == cible_retour) + { break; + } if (LOGP[(NOW + index) % Log_size] + cumul_retour >= cible_retour) { @@ -378,7 +395,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat cumul += last; FOC = d; if (A <= cumul) + { break; + } } } } @@ -391,9 +410,13 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat { int AUN_app = AUN; if (stock >= 0 && stock <= AUN) + { AUN_app -= stock; + } if (stock > AUN) + { AUN_app = 0; + } last = PPOW[dayInTheYear][AUN_app]; A = rndgenerator.next(); @@ -403,12 +426,14 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat cumul = last; for (int d = 1; d < AUN_app + 1; ++d) { - last - = ((last * pp[dayInTheYear]) * ((double)(AUN_app + 1. - d))) / (double)d; + last = ((last * pp[dayInTheYear]) * ((double)(AUN_app + 1. - d))) + / (double)d; cumul += last; POC = d; if (A <= cumul) + { break; + } } } } @@ -505,11 +530,21 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat AUN = AUN - (PPO + PFO + MXO); if (PFO != 0 || MXO != 0) - FOD_reel = durationGenerator( - f_law, FODOfTheDay, f_volatility, af[dayInTheYear], bf[dayInTheYear]); + { + FOD_reel = durationGenerator(f_law, + FODOfTheDay, + f_volatility, + af[dayInTheYear], + bf[dayInTheYear]); + } if (PPO != 0 || MXO != 0) - POD_reel = durationGenerator( - p_law, PODOfTheDay, p_volatility, ap[dayInTheYear], bp[dayInTheYear]); + { + POD_reel = durationGenerator(p_law, + PODOfTheDay, + p_volatility, + ap[dayInTheYear], + bp[dayInTheYear]); + } assert(FUT < Log_size); if (PFO != 0) @@ -546,7 +581,9 @@ void GeneratorTempData::generateTS(const Data::Area& area, AvailabilityTSGenerat } if (derated) + { cluster.series.averageTimeseries(); + } } } // namespace @@ -555,11 +592,17 @@ std::vector getAllClustersToGen(const Data::AreaList& are { std::vector clusters; - areas.each([&clusters, &globalThermalTSgeneration](const Data::Area& area) { - for (const auto& cluster : area.thermal.list.all()) - if (cluster->doWeGenerateTS(globalThermalTSgeneration)) - clusters.push_back(cluster.get()); - }); + areas.each( + [&clusters, &globalThermalTSgeneration](const Data::Area& area) + { + for (const auto& cluster: area.thermal.list.all()) + { + if (cluster->doWeGenerateTS(globalThermalTSgeneration)) + { + clusters.push_back(cluster.get()); + } + } + }); return clusters; } @@ -568,12 +611,16 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) { listOfLinks links; - areas.each([&links](const Data::Area& area) { - std::ranges::for_each(area.links, [&links](auto& l) { - links.emplace_back(l.second, linkDirection::direct); - links.emplace_back(l.second, linkDirection::indirect); - }); - }); + areas.each( + [&links](const Data::Area& area) + { + std::ranges::for_each(area.links, + [&links](auto& l) + { + links.emplace_back(l.second, linkDirection::direct); + links.emplace_back(l.second, linkDirection::indirect); + }); + }); return links; } @@ -584,7 +631,9 @@ void writeResultsToDisk(const Data::Study& study, const std::string& savePath) { if (study.parameters.noOutput) + { return; + } std::string buffer; series.saveToBuffer(buffer, 0); @@ -604,15 +653,15 @@ bool generateThermalTimeSeries(Data::Study& study, auto generator = GeneratorTempData(study, study.parameters.nbTimeSeriesThermal); // TODO VP: parallel - for (auto* cluster : clusters) + for (auto* cluster: clusters) { AvailabilityTSGeneratorData tsConfigData(cluster); generator.generateTS(*cluster->parentArea, tsConfigData); if (archive) // compatibilty with in memory { - std::string filePath - = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + ".txt"; + std::string filePath = savePath + SEP + cluster->parentArea->id + SEP + cluster->id() + + ".txt"; writeResultsToDisk(study, writer, cluster->series.timeSeries, filePath); } } @@ -630,7 +679,7 @@ bool generateLinkTimeSeries(Data::Study& study, auto generator = GeneratorTempData(study, study.parameters.nbLinkTStoGenerate); - for (const auto& [link, direction] : links) + for (const auto& [link, direction]: links) { Data::TimeSeries ts(link->timeseriesNumbers); ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); @@ -647,8 +696,8 @@ bool generateLinkTimeSeries(Data::Study& study, generator.generateTS(*link->from, tsConfigData); std::string capacityType = direction == linkDirection::direct ? "_direct" : "_indirect"; - std::string filePath - = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + capacityType + ".txt"; + std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + capacityType + ".txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 7446ef2bc0..1b533525f3 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -22,13 +22,15 @@ #define __ANTARES_SOLVER_timeSeries_GENERATOR_H__ #include + +#include +#include #include #include -#include #include -#include -#include +#include #include + #include "xcast/xcast.h" namespace Antares::TSGenerator @@ -37,7 +39,9 @@ class AvailabilityTSGeneratorData { public: explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); - AvailabilityTSGeneratorData(Data::LinkTsGeneration&, Data::TimeSeries&, const std::string& name); + AvailabilityTSGeneratorData(Data::LinkTsGeneration&, + Data::TimeSeries&, + const std::string& name); const unsigned& unitCount; const double& nominalCapacity; diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/law.h b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h index 5dfb2a2014..429ca02f15 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/law.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/law.h @@ -7,4 +7,4 @@ enum StatisticalLaw LawUniform, LawGeometric }; -} +} // namespace Antares::Data diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index 03d354f51a..f35d99c3d2 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -21,11 +21,12 @@ #ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_H__ #define __ANTARES_LIBS_STUDY_PARTS_THERMAL_PREPRO_H__ +#include + #include +#include #include #include -#include -#include namespace Antares::Data { diff --git a/src/solver/ts-generator/prepro.cpp b/src/solver/ts-generator/prepro.cpp index 920e9f4a2b..b093d4b837 100644 --- a/src/solver/ts-generator/prepro.cpp +++ b/src/solver/ts-generator/prepro.cpp @@ -20,12 +20,13 @@ */ #include -#include -#include #include -#include "antares/study/study.h" -#include +#include +#include + #include +#include +#include "antares/study/study.h" using namespace Yuni; @@ -33,8 +34,9 @@ using namespace Yuni; namespace Antares::Data { -PreproAvailability::PreproAvailability(const YString& id, unsigned int unitCount) : - id(id), unitCount(unitCount) +PreproAvailability::PreproAvailability(const YString& id, unsigned int unitCount): + id(id), + unitCount(unitCount) { } @@ -64,8 +66,11 @@ bool PreproAvailability::loadFromFolder(Study& study, const AnyString& folder) buffer.clear() << folder << SEP << "data.txt"; // standard loading - return data.loadFromCSVFile( - buffer, preproAvailabilityMax, DAYS_PER_YEAR, Matrix<>::optFixedSize, &study.dataBuffer); + return data.loadFromCSVFile(buffer, + preproAvailabilityMax, + DAYS_PER_YEAR, + Matrix<>::optFixedSize, + &study.dataBuffer); } bool PreproAvailability::validate() const @@ -201,10 +206,14 @@ bool PreproAvailability::normalizeAndCheckNPO() } if (errors >= maxErrors) + { logs.error() << id << ": too many errors. skipping (total: " << errors << ')'; + } if (normalized) + { logs.info() << " NPO max for entity '" << id << "' has been normalized"; + } data.markAsModified(); return (0 == errors); diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index ba13258a55..1b35b293a6 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -22,18 +22,18 @@ #include #include -#include +#include + +#include +#include #include +#include +#include #include #include -#include #include -#include - -#include -#include #include -#include +#include using namespace Antares; @@ -57,11 +57,22 @@ std::unique_ptr createTsGeneratorParser(Settings& settings auto parser = std::make_unique(); parser->addParagraph("Antares Time Series generator\n"); - parser->addFlag(settings.allThermal, ' ', "all-thermal", "Generate TS for all thermal clusters"); - parser->addFlag(settings.thermalListToGen, ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); + parser->addFlag(settings.allThermal, + ' ', + "all-thermal", + "Generate TS for all thermal clusters"); + parser->addFlag(settings.thermalListToGen, + ' ', + "thermal", + "Generate TS for a list of area IDs and thermal clusters IDs, " + "usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); - parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of 2 area IDs, usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); + parser->addFlag(settings.linksListToGen, + ' ', + "links", + "Generate TS capacities for a list of 2 area IDs, " + "usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); parser->remainingArguments(settings.studyFolder); @@ -74,7 +85,7 @@ std::vector getClustersToGen(Data::AreaList& areas, std::vector clusters; const auto ids = splitStringIntoPairs(clustersToGen, ';', '.'); - for (const auto& [areaID, clusterID] : ids) + for (const auto& [areaID, clusterID]: ids) { logs.info() << "Searching for area: " << areaID << " and cluster: " << clusterID; @@ -98,13 +109,12 @@ std::vector getClustersToGen(Data::AreaList& areas, return clusters; } -TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, - const std::string& linksToGen) +TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& linksToGen) { TSGenerator::listOfLinks links; const auto ids = splitStringIntoPairs(linksToGen, ';', '.'); - for (const auto& [areaFromID, areaWithID] : ids) + for (const auto& [areaFromID, areaWithID]: ids) { logs.info() << "Searching for link: " << areaFromID << "/" << areaWithID; @@ -114,8 +124,8 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; continue; } - auto direction = (link->from->id == areaFromID) ? TSGenerator::linkDirection::direct : - TSGenerator::linkDirection::indirect; + auto direction = (link->from->id == areaFromID) ? TSGenerator::linkDirection::direct + : TSGenerator::linkDirection::indirect; links.emplace_back(link, direction); } @@ -123,7 +133,7 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, return links; } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { Settings settings; @@ -162,16 +172,21 @@ int main(int argc, char *argv[]) // Force the writing of generated TS into output/YYYYMMDD-HHSSeco/ts-generator/thermal study->parameters.timeSeriesToArchive |= Antares::Data::timeSeriesThermal; - try { + try + { Antares::Check::checkMinStablePower(true, study->areas); - } catch(Error::InvalidParametersForThermalClusters& ex) { + } + catch (Error::InvalidParametersForThermalClusters& ex) + { Antares::logs.error() << ex.what(); } Benchmarking::NullDurationCollector nullDurationCollector; - auto resultWriter = Solver::resultWriterFactory( - Data::ResultFormat::legacyFilesDirectories, study->folderOutput, nullptr, nullDurationCollector); + auto resultWriter = Solver::resultWriterFactory(Data::ResultFormat::legacyFilesDirectories, + study->folderOutput, + nullptr, + nullDurationCollector); const auto thermalSavePath = std::filesystem::path("ts-generator") / "thermal"; const auto linksSavePath = std::filesystem::path("ts-generator") / "links"; @@ -179,25 +194,41 @@ int main(int argc, char *argv[]) // THERMAL std::vector clusters; if (settings.allThermal) + { clusters = TSGenerator::getAllClustersToGen(study->areas, true); + } else if (!settings.thermalListToGen.empty()) + { clusters = getClustersToGen(study->areas, settings.thermalListToGen); + } - for (auto& c : clusters) + for (auto& c: clusters) + { logs.debug() << c->id(); + } // LINKS TSGenerator::listOfLinks links; if (settings.allLinks) + { links = TSGenerator::getAllLinksToGen(study->areas); + } else if (!settings.linksListToGen.empty()) + { links = getLinksToGen(study->areas, settings.linksListToGen); + } - for (auto& l : links) + for (auto& l: links) + { logs.debug() << l.first->getName(); + } - bool ret = TSGenerator::generateThermalTimeSeries(*study, clusters, *resultWriter, thermalSavePath.string()); - ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath.string()) && ret; + bool ret = TSGenerator::generateThermalTimeSeries(*study, + clusters, + *resultWriter, + thermalSavePath.string()); + ret = TSGenerator::generateLinkTimeSeries(*study, links, *resultWriter, linksSavePath.string()) + && ret; return !ret; // return 0 for success } From 213603ab3f65ae0e375a154f614bb9e094d2265c Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 13 May 2024 16:29:13 +0200 Subject: [PATCH 085/101] add app name --- src/tools/ts-generator/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 2e2f9f9b92..7763a3889c 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -135,6 +135,8 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& int main(int argc, char* argv[]) { + logs.applicationName("ts-generator"); + Settings settings; auto parser = createTsGeneratorParser(settings); From 2e62287bc9dfac8ee8b148a2f33e20391879f704 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 11:38:18 +0200 Subject: [PATCH 086/101] use std fs --- src/libs/antares/study/area/links.cpp | 4 ++-- src/libs/antares/study/include/antares/study/area/links.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index f38732fd3e..5118c56bb9 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -139,7 +139,7 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol // This function is "lazy", it only loads files if they exist // and set a `valid` flag -bool AreaLink::loadTSGenTimeSeries(const AnyString& folder) +bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); tsGenerationDirect.prepro = std::make_unique( @@ -728,7 +728,7 @@ bool AreaLinksLoadFromFolder(Study& study, AreaList* l, Area* area, const fs::pa if (loadTSGen) { - ret = link.loadTSGenTimeSeries(folder.string()) && ret; + ret = link.loadTSGenTimeSeries(folder) && ret; } // From the solver only diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index 7ba922fe35..e387d5ba0c 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -71,7 +71,7 @@ class AreaLink final: public Yuni::NonCopyable bool loadTimeSeries(const StudyVersion& version, const AnyString& folder); - bool loadTSGenTimeSeries(const AnyString& folder); + bool loadTSGenTimeSeries(const std::filesystem::path& folder); void storeTimeseriesNumbers(Solver::IResultWriter& writer) const; From aa3a794a3fad2e345ddf3e89e88c8658362d637a Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 14:28:43 +0200 Subject: [PATCH 087/101] use fs path --- src/libs/antares/study/area/links.cpp | 33 +++++++++++++++------------ 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 5118c56bb9..59eed2ee1d 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -151,49 +151,52 @@ bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) id_indirect, tsGenerationIndirect.unitCount); - String preproFolder; - preproFolder << folder << SEP << "prepro"; + fs::path preproFile = folder / "prepro" / with->id.c_str(); // file name without suffix // Prepro - String filename; - filename.clear() << preproFolder << SEP << with->id << "_direct.txt"; + fs::path filepath = preproFile; + filepath += "_direct.txt"; + bool anyFileWasLoaded = false; - if (std::filesystem::exists(filename.to())) + if (fs::exists(filepath)) { anyFileWasLoaded = true; tsGenerationDirect.valid = tsGenerationDirect.prepro->data.loadFromCSVFile( - filename, + filepath.string(), Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) && tsGenerationDirect.prepro->validate(); } - filename.clear() << preproFolder << SEP << with->id << "_indirect.txt"; - if (std::filesystem::exists(filename.to())) + filepath = preproFile; + filepath += "_indirect.txt"; + if (fs::exists(filepath)) { anyFileWasLoaded = true; tsGenerationIndirect.valid = tsGenerationIndirect.prepro->data.loadFromCSVFile( - filename, + filepath.string(), Antares::Data::PreproAvailability::preproAvailabilityMax, DAYS_PER_YEAR) && tsGenerationIndirect.prepro->validate(); } // Modulation - filename.clear() << preproFolder << SEP << with->id << "_mod_direct.txt"; - if (std::filesystem::exists(filename.to())) + filepath = preproFile; + filepath += "_mod_direct.txt"; + if (fs::exists(filepath)) { anyFileWasLoaded = true; tsGenerationDirect.valid &= tsGenerationDirect.modulationCapacity - .loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } - filename.clear() << preproFolder << SEP << with->id << "_mod_indirect.txt"; - if (std::filesystem::exists(filename.to())) + filepath = preproFile; + filepath += "_mod_indirect.txt"; + if (fs::exists(filepath)) { anyFileWasLoaded = true; tsGenerationIndirect.valid &= tsGenerationIndirect.modulationCapacity - .loadFromCSVFile(filename, 1, HOURS_PER_YEAR); + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); } if (anyFileWasLoaded) { From bda7e7837d6ba5620f4228686f9d0b5fe4bc9cc2 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 15:23:49 +0200 Subject: [PATCH 088/101] fs path in tool --- src/tools/ts-generator/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 7763a3889c..d739e35111 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -37,6 +37,8 @@ using namespace Antares; +namespace fs = std::filesystem; + struct Settings { std::string studyFolder; @@ -190,8 +192,8 @@ int main(int argc, char* argv[]) nullptr, durationCollector); - const auto thermalSavePath = std::filesystem::path("ts-generator") / "thermal"; - const auto linksSavePath = std::filesystem::path("ts-generator") / "links"; + const auto thermalSavePath = fs::path("ts-generator") / "thermal"; + const auto linksSavePath = fs::path("ts-generator") / "links"; // THERMAL std::vector clusters; From abf50a06d399fabab5c062f33d2bbedb38eac162 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 16:21:05 +0200 Subject: [PATCH 089/101] first implem for generation direct --- src/libs/antares/study/area/links.cpp | 139 +++++++++--------- .../study/include/antares/study/area/links.h | 3 +- src/solver/ts-generator/availability.cpp | 23 ++- .../antares/solver/ts-generator/generator.h | 9 +- .../antares/solver/ts-generator/prepro.h | 3 +- 5 files changed, 86 insertions(+), 91 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 59eed2ee1d..4017404dd4 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -141,67 +141,68 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol // and set a `valid` flag bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { - const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); - tsGenerationDirect.prepro = std::make_unique( - id_direct, - tsGenerationDirect.unitCount); - - const std::string id_indirect = std::string(with->id) + "/" + std::string(from->id); - tsGenerationIndirect.prepro = std::make_unique( - id_indirect, - tsGenerationIndirect.unitCount); - - fs::path preproFile = folder / "prepro" / with->id.c_str(); // file name without suffix - - // Prepro - fs::path filepath = preproFile; - filepath += "_direct.txt"; - - bool anyFileWasLoaded = false; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGenerationDirect.valid = tsGenerationDirect.prepro->data.loadFromCSVFile( - filepath.string(), - Antares::Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && tsGenerationDirect.prepro->validate(); - } - - filepath = preproFile; - filepath += "_indirect.txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGenerationIndirect.valid = tsGenerationIndirect.prepro->data.loadFromCSVFile( - filepath.string(), - Antares::Data::PreproAvailability::preproAvailabilityMax, - DAYS_PER_YEAR) - && tsGenerationIndirect.prepro->validate(); - } - - // Modulation - filepath = preproFile; - filepath += "_mod_direct.txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGenerationDirect.valid &= tsGenerationDirect.modulationCapacity - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); - } - - filepath = preproFile; - filepath += "_mod_indirect.txt"; - if (fs::exists(filepath)) - { - anyFileWasLoaded = true; - tsGenerationIndirect.valid &= tsGenerationIndirect.modulationCapacity - .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); - } - if (anyFileWasLoaded) - { - return tsGenerationDirect.valid && tsGenerationIndirect.valid; - } + /* const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); */ + /* tsGenerationDirect.prepro = std::make_unique( */ + /* id_direct, */ + /* tsGenerationDirect.unitCount); */ + + /* const std::string id_indirect = std::string(with->id) + "/" + std::string(from->id); */ + /* tsGenerationIndirect.prepro = std::make_unique( */ + /* id_indirect, */ + /* tsGenerationIndirect.unitCount); */ + + /* // file name without suffix, .txt for general infos and mod_direct/indirect.txt */ + /* fs::path preproFile = folder / "prepro" / with->id.c_str(); */ + + /* // Prepro */ + /* fs::path filepath = preproFile; */ + /* filepath += ".txt"; */ + + /* bool anyFileWasLoaded = false; */ + /* if (fs::exists(filepath)) */ + /* { */ + /* anyFileWasLoaded = true; */ + /* tsGenerationDirect.valid = tsGenerationDirect.prepro->data.loadFromCSVFile( */ + /* filepath.string(), */ + /* Antares::Data::PreproAvailability::preproAvailabilityMax, */ + /* DAYS_PER_YEAR) */ + /* && tsGenerationDirect.prepro->validate(); */ + /* } */ + + /* filepath = preproFile; */ + /* filepath += "_indirect.txt"; */ + /* if (fs::exists(filepath)) */ + /* { */ + /* anyFileWasLoaded = true; */ + /* tsGenerationIndirect.valid = tsGenerationIndirect.prepro->data.loadFromCSVFile( */ + /* filepath.string(), */ + /* Antares::Data::PreproAvailability::preproAvailabilityMax, */ + /* DAYS_PER_YEAR) */ + /* && tsGenerationIndirect.prepro->validate(); */ + /* } */ + + /* // Modulation */ + /* filepath = preproFile; */ + /* filepath += "_mod_direct.txt"; */ + /* if (fs::exists(filepath)) */ + /* { */ + /* anyFileWasLoaded = true; */ + /* tsGenerationDirect.valid &= tsGenerationDirect.modulationCapacity */ + /* .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); */ + /* } */ + + /* filepath = preproFile; */ + /* filepath += "_mod_indirect.txt"; */ + /* if (fs::exists(filepath)) */ + /* { */ + /* anyFileWasLoaded = true; */ + /* tsGenerationIndirect.valid &= tsGenerationIndirect.modulationCapacity */ + /* .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); */ + /* } */ + /* if (anyFileWasLoaded) */ + /* { */ + /* return tsGenerationDirect.valid && tsGenerationIndirect.valid; */ + /* } */ return true; } @@ -569,14 +570,14 @@ bool handleTSGenKey_internal(const std::string& key, bool handleTSGenKey(Data::AreaLink& link, const std::string& key, const String& value) { - if (key.starts_with("tsgen_direct")) - { - return handleTSGenKey_internal(key, value, "tsgen_direct", link.tsGenerationDirect); - } - else if (key.starts_with("tsgen_indirect")) - { - return handleTSGenKey_internal(key, value, "tsgen_indirect", link.tsGenerationIndirect); - } + /* if (key.starts_with("tsgen_direct")) */ + /* { */ + /* return handleTSGenKey_internal(key, value, "tsgen_direct", link.tsGenerationDirect); */ + /* } */ + /* else if (key.starts_with("tsgen_indirect")) */ + /* { */ + /* return handleTSGenKey_internal(key, value, "tsgen_indirect", link.tsGenerationIndirect); */ + /* } */ return false; } diff --git a/src/libs/antares/study/include/antares/study/area/links.h b/src/libs/antares/study/include/antares/study/area/links.h index e387d5ba0c..5b01ba3efd 100644 --- a/src/libs/antares/study/include/antares/study/area/links.h +++ b/src/libs/antares/study/include/antares/study/area/links.h @@ -209,8 +209,7 @@ class AreaLink final: public Yuni::NonCopyable friend struct CompareLinkName; - LinkTsGeneration tsGenerationDirect; - LinkTsGeneration tsGenerationIndirect; + LinkTsGeneration tsGeneration; }; // class AreaLink diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 628cde2fd8..4d6897ca66 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -52,6 +52,7 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::ThermalCluster* s AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& source, Data::TimeSeries& capacity, + Matrix<>& modulation, const std::string& areaDestName): unitCount(source.unitCount), nominalCapacity(source.nominalCapacity), @@ -61,7 +62,7 @@ AvailabilityTSGeneratorData::AvailabilityTSGeneratorData(Data::LinkTsGeneration& plannedLaw(source.plannedLaw), prepro(source.prepro.get()), series(capacity.timeSeries), - modulationCapacity(source.modulationCapacity[0]), + modulationCapacity(modulation[0]), name(areaDestName) { } @@ -615,11 +616,9 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) areas.each( [&links](const Data::Area& area) { - std::ranges::for_each(area.links, - [&links](auto& l) + std::ranges::for_each(area.links, [&links](auto& l) { - links.emplace_back(l.second, linkDirection::direct); - links.emplace_back(l.second, linkDirection::indirect); + links.push_back(l.second); }); }); @@ -680,25 +679,25 @@ bool generateLinkTimeSeries(Data::Study& study, auto generator = GeneratorTempData(study, study.parameters.nbLinkTStoGenerate); - for (const auto& [link, direction]: links) + for (const auto& link: links) { Data::TimeSeries ts(link->timeseriesNumbers); ts.resize(study.parameters.nbLinkTStoGenerate, HOURS_PER_YEAR); - auto& tsGenStruct = direction == linkDirection::direct ? link->tsGenerationDirect - : link->tsGenerationIndirect; + auto& tsGenStruct = link->tsGeneration; + if (!tsGenStruct.valid) { logs.error() << "Missing data for link " << link->from->id << "/" << link->with->id; return false; } - AvailabilityTSGeneratorData tsConfigData(tsGenStruct, ts, link->with->name); - generator.generateTS(*link->from, tsConfigData); + AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); + + generator.generateTS(*link->from, tsConfigDataDirect); - std::string capacityType = direction == linkDirection::direct ? "_direct" : "_indirect"; std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() - + capacityType + ".txt"; + + "_direct.txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h index 1b533525f3..1c32e67bdd 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/generator.h @@ -41,6 +41,7 @@ class AvailabilityTSGeneratorData explicit AvailabilityTSGeneratorData(Data::ThermalCluster*); AvailabilityTSGeneratorData(Data::LinkTsGeneration&, Data::TimeSeries&, + Matrix<>& modulation, const std::string& name); const unsigned& unitCount; @@ -61,13 +62,7 @@ class AvailabilityTSGeneratorData const std::string& name; }; -enum class linkDirection -{ - direct, - indirect -}; - -using listOfLinks = std::vector>; +using listOfLinks = std::vector; void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index 657712988d..8c1cdb4fb4 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -128,7 +128,8 @@ struct LinkTsGeneration std::unique_ptr prepro; - Matrix<> modulationCapacity; + Matrix<> modulationCapacityDirect; + Matrix<> modulationCapacityIndirect; bool valid = false; }; From 2edaee16859020a1889c3898614f56034f1d71ed Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 16:32:03 +0200 Subject: [PATCH 090/101] fix compile --- src/solver/ts-generator/availability.cpp | 9 +++++++++ src/tools/ts-generator/main.cpp | 6 ++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 4d6897ca66..2e287731f0 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -692,13 +692,22 @@ bool generateLinkTimeSeries(Data::Study& study, return false; } + // DIRECT AvailabilityTSGeneratorData tsConfigDataDirect(tsGenStruct, ts, tsGenStruct.modulationCapacityDirect, link->with->name); generator.generateTS(*link->from, tsConfigDataDirect); std::string filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + "_direct.txt"; + writeResultsToDisk(study, writer, ts.timeSeries, filePath); + + // INDIRECT + AvailabilityTSGeneratorData tsConfigDataIndirect(tsGenStruct, ts, tsGenStruct.modulationCapacityIndirect, link->with->name); + + generator.generateTS(*link->from, tsConfigDataIndirect); + filePath = savePath + SEP + link->from->id + SEP + link->with->id.c_str() + + "_indirect.txt"; writeResultsToDisk(study, writer, ts.timeSeries, filePath); } diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index d739e35111..39689123f3 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -126,10 +126,8 @@ TSGenerator::listOfLinks getLinksToGen(Data::AreaList& areas, const std::string& logs.warning() << "Link not found: " << areaFromID << "/" << areaWithID; continue; } - auto direction = (link->from->id == areaFromID) ? TSGenerator::linkDirection::direct - : TSGenerator::linkDirection::indirect; - links.emplace_back(link, direction); + links.emplace_back(link); } return links; @@ -224,7 +222,7 @@ int main(int argc, char* argv[]) for (auto& l: links) { - logs.debug() << l.first->getName(); + logs.debug() << l->getName(); } bool ret = TSGenerator::generateThermalTimeSeries(*study, From ba0363b95cd3a666665c671ffabcda41ec6d1416 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 16:39:58 +0200 Subject: [PATCH 091/101] key handling --- src/libs/antares/study/area/links.cpp | 40 +++++++-------------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index 4017404dd4..a809ecb04a 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -523,44 +523,37 @@ bool handleKey(Data::AreaLink& link, const String& key, const String& value) return false; } -bool handleTSGenKey_internal(const std::string& key, - const String& value, - const std::string& prefix, - Data::LinkTsGeneration& out) +bool handleTSGenKey(Data::LinkTsGeneration& out, + const std::string& key, + const String& value) { - const auto checkPrefixed = [&prefix, &key](const std::string& s) - { - auto key_lowercase(key); - boost::to_lower(key_lowercase); - return key_lowercase == prefix + "_" + s; - }; - if (checkPrefixed("unitcount")) + if (key == "unitcount") { return value.to(out.unitCount); } - if (checkPrefixed("nominalcapacity")) + if (key == "nominalcapacity") { return value.to(out.nominalCapacity); } - if (checkPrefixed("law.planned")) + if (key == "law.planned") { return value.to(out.plannedLaw); } - if (checkPrefixed("law.forced")) + if (key == "law.forced") { return value.to(out.forcedLaw); } - if (checkPrefixed("volatility.planned")) + if (key == "volatility.planned") { return value.to(out.plannedVolatility); } - if (checkPrefixed("volatility.forced")) + if (key == "volatility.forced") { return value.to(out.forcedVolatility); } @@ -568,22 +561,9 @@ bool handleTSGenKey_internal(const std::string& key, return false; } -bool handleTSGenKey(Data::AreaLink& link, const std::string& key, const String& value) -{ - /* if (key.starts_with("tsgen_direct")) */ - /* { */ - /* return handleTSGenKey_internal(key, value, "tsgen_direct", link.tsGenerationDirect); */ - /* } */ - /* else if (key.starts_with("tsgen_indirect")) */ - /* { */ - /* return handleTSGenKey_internal(key, value, "tsgen_indirect", link.tsGenerationIndirect); */ - /* } */ - return false; -} - bool AreaLinksInternalLoadFromProperty(AreaLink& link, const String& key, const String& value) { - return handleKey(link, key, value) || handleTSGenKey(link, key, value); + return handleKey(link, key, value) || handleTSGenKey(link.tsGeneration, key, value); } [[noreturn]] void logLinkDataCheckError(const AreaLink& link, const String& msg, int hour) From 6f6242508fe575969acdf87a354784737c03a2b8 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 29 May 2024 16:51:42 +0200 Subject: [PATCH 092/101] file loading --- src/libs/antares/study/area/links.cpp | 107 +++++++++++--------------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index a809ecb04a..e1b48e3aa9 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -141,68 +141,51 @@ bool AreaLink::linkLoadTimeSeries_for_version_820_and_later(const AnyString& fol // and set a `valid` flag bool AreaLink::loadTSGenTimeSeries(const fs::path& folder) { - /* const std::string id_direct = std::string(from->id) + "/" + std::string(with->id); */ - /* tsGenerationDirect.prepro = std::make_unique( */ - /* id_direct, */ - /* tsGenerationDirect.unitCount); */ - - /* const std::string id_indirect = std::string(with->id) + "/" + std::string(from->id); */ - /* tsGenerationIndirect.prepro = std::make_unique( */ - /* id_indirect, */ - /* tsGenerationIndirect.unitCount); */ - - /* // file name without suffix, .txt for general infos and mod_direct/indirect.txt */ - /* fs::path preproFile = folder / "prepro" / with->id.c_str(); */ - - /* // Prepro */ - /* fs::path filepath = preproFile; */ - /* filepath += ".txt"; */ - - /* bool anyFileWasLoaded = false; */ - /* if (fs::exists(filepath)) */ - /* { */ - /* anyFileWasLoaded = true; */ - /* tsGenerationDirect.valid = tsGenerationDirect.prepro->data.loadFromCSVFile( */ - /* filepath.string(), */ - /* Antares::Data::PreproAvailability::preproAvailabilityMax, */ - /* DAYS_PER_YEAR) */ - /* && tsGenerationDirect.prepro->validate(); */ - /* } */ - - /* filepath = preproFile; */ - /* filepath += "_indirect.txt"; */ - /* if (fs::exists(filepath)) */ - /* { */ - /* anyFileWasLoaded = true; */ - /* tsGenerationIndirect.valid = tsGenerationIndirect.prepro->data.loadFromCSVFile( */ - /* filepath.string(), */ - /* Antares::Data::PreproAvailability::preproAvailabilityMax, */ - /* DAYS_PER_YEAR) */ - /* && tsGenerationIndirect.prepro->validate(); */ - /* } */ - - /* // Modulation */ - /* filepath = preproFile; */ - /* filepath += "_mod_direct.txt"; */ - /* if (fs::exists(filepath)) */ - /* { */ - /* anyFileWasLoaded = true; */ - /* tsGenerationDirect.valid &= tsGenerationDirect.modulationCapacity */ - /* .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); */ - /* } */ - - /* filepath = preproFile; */ - /* filepath += "_mod_indirect.txt"; */ - /* if (fs::exists(filepath)) */ - /* { */ - /* anyFileWasLoaded = true; */ - /* tsGenerationIndirect.valid &= tsGenerationIndirect.modulationCapacity */ - /* .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); */ - /* } */ - /* if (anyFileWasLoaded) */ - /* { */ - /* return tsGenerationDirect.valid && tsGenerationIndirect.valid; */ - /* } */ + const std::string idprepro = std::string(from->id) + "/" + std::string(with->id); + tsGeneration.prepro = + std::make_unique(idprepro, tsGeneration.unitCount); + + bool anyFileWasLoaded = false; + + // file name without suffix, .txt for general infos and mod_direct/indirect.txt + fs::path preproFile = folder / "prepro" / with->id.c_str(); + + // Prepro + fs::path filepath = preproFile; + filepath += ".txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid = tsGeneration.prepro->data.loadFromCSVFile( + filepath.string(), + Antares::Data::PreproAvailability::preproAvailabilityMax, + DAYS_PER_YEAR) + && tsGeneration.prepro->validate(); + } + + // Modulation + filepath = preproFile; + filepath += "_mod_direct.txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid &= tsGeneration.modulationCapacityDirect + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + } + + filepath = preproFile; + filepath += "_mod_indirect.txt"; + if (fs::exists(filepath)) + { + anyFileWasLoaded = true; + tsGeneration.valid &= tsGeneration.modulationCapacityIndirect + .loadFromCSVFile(filepath.string(), 1, HOURS_PER_YEAR); + } + + if (anyFileWasLoaded) + { + return tsGeneration.valid; + } return true; } From 2522ca6f177b84a9e40fe47828d006cd0acb9f5b Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 4 Jun 2024 11:17:56 +0200 Subject: [PATCH 093/101] Use correct rnd generator for each type --- src/solver/ts-generator/availability.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 2e287731f0..2334b0d952 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -72,7 +72,7 @@ namespace class GeneratorTempData final { public: - explicit GeneratorTempData(Data::Study&, unsigned); + explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister); void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const; @@ -99,10 +99,10 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen): +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]) + rndgenerator(rndGenerator) { } @@ -650,7 +650,9 @@ bool generateThermalTimeSeries(Data::Study& study, bool archive = study.parameters.timeSeriesToArchive & Data::timeSeriesThermal; - auto generator = GeneratorTempData(study, study.parameters.nbTimeSeriesThermal); + auto generator = GeneratorTempData(study, + study.parameters.nbTimeSeriesThermal, + study.runtime->random[Data::seedTsGenThermal]); // TODO VP: parallel for (auto* cluster: clusters) @@ -677,7 +679,9 @@ bool generateLinkTimeSeries(Data::Study& study, logs.info(); logs.info() << "Generating the links time-series"; - auto generator = GeneratorTempData(study, study.parameters.nbLinkTStoGenerate); + auto generator = GeneratorTempData(study, + study.parameters.nbLinkTStoGenerate, + study.runtime->random[Data::seedTsGenLinks]); for (const auto& link: links) { From 38a4207c18d4be0d91c386430121a6825b260dc5 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 5 Jun 2024 11:26:46 +0200 Subject: [PATCH 094/101] Add force-no-generation parameter --- src/libs/antares/study/area/links.cpp | 5 +++++ src/solver/ts-generator/availability.cpp | 3 ++- .../include/antares/solver/ts-generator/prepro.h | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libs/antares/study/area/links.cpp b/src/libs/antares/study/area/links.cpp index e1b48e3aa9..40da9df149 100644 --- a/src/libs/antares/study/area/links.cpp +++ b/src/libs/antares/study/area/links.cpp @@ -541,6 +541,11 @@ bool handleTSGenKey(Data::LinkTsGeneration& out, return value.to(out.forcedVolatility); } + if (key == "force-no-generation") + { + return value.to(out.forceNoGeneration); + } + return false; } diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index 2334b0d952..dd0716d51a 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -618,7 +618,8 @@ listOfLinks getAllLinksToGen(Data::AreaList& areas) { std::ranges::for_each(area.links, [&links](auto& l) { - links.push_back(l.second); + if (!l.second->tsGeneration.forceNoGeneration) + links.push_back(l.second); }); }); diff --git a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h index 8c1cdb4fb4..ac36a826ea 100644 --- a/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h +++ b/src/solver/ts-generator/include/antares/solver/ts-generator/prepro.h @@ -132,6 +132,8 @@ struct LinkTsGeneration Matrix<> modulationCapacityIndirect; bool valid = false; + + bool forceNoGeneration = false; }; } // namespace Antares::Data From bfeead93ebc2f0a70a616f04a68e688a8b0d8a14 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 6 Jun 2024 10:36:34 +0200 Subject: [PATCH 095/101] reference for mersenne gen --- src/solver/ts-generator/availability.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solver/ts-generator/availability.cpp b/src/solver/ts-generator/availability.cpp index dd0716d51a..69f62a10a1 100644 --- a/src/solver/ts-generator/availability.cpp +++ b/src/solver/ts-generator/availability.cpp @@ -72,7 +72,7 @@ namespace class GeneratorTempData final { public: - explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister); + explicit GeneratorTempData(Data::Study&, unsigned, MersenneTwister&); void generateTS(const Data::Area& area, AvailabilityTSGeneratorData& cluster) const; @@ -99,7 +99,7 @@ class GeneratorTempData final const T& duration) const; }; -GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister rndGenerator): +GeneratorTempData::GeneratorTempData(Data::Study& study, unsigned nbOfSeriesToGen, MersenneTwister& rndGenerator): derated(study.parameters.derated), nbOfSeriesToGen_(nbOfSeriesToGen), rndgenerator(rndGenerator) From ba2b84a43e7e6d2753a32dbd85c8ca97a3fae556 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 6 Jun 2024 14:31:26 +0200 Subject: [PATCH 096/101] change help formatting for the exe cmd line --- src/tools/ts-generator/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 39689123f3..641d25902b 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -67,14 +67,14 @@ std::unique_ptr createTsGeneratorParser(Settings& settings ' ', "thermal", "Generate TS for a list of area IDs and thermal clusters IDs, " - "usage:\n\t--thermal=\"areaID.clusterID;area2ID.clusterID\""); + "\nusage: --thermal=\"areaID.clusterID;area2ID.clusterID\""); parser->addFlag(settings.allLinks, ' ', "all-links", "Generate TS capacities for all links"); parser->addFlag(settings.linksListToGen, ' ', "links", "Generate TS capacities for a list of 2 area IDs, " - "usage:\n\t--links=\"areaID.area2ID;area3ID.area1ID\""); + "usage: --links=\"areaID.area2ID;area3ID.area1ID\""); parser->remainingArguments(settings.studyFolder); From 73b80074196ea9a3fb3f42d3974703bc568a9ed0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 6 Jun 2024 14:33:45 +0200 Subject: [PATCH 097/101] conflict link options for cmd line --- src/tools/ts-generator/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 641d25902b..c33471942e 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -159,6 +159,12 @@ int main(int argc, char* argv[]) return 1; } + if (settings.allLinks && !settings.linksToGen.empty() + { + logs.error() << "Conflicting options, either choose all links or a list"; + return 1; + } + auto study = std::make_shared(true); Data::StudyLoadOptions studyOptions; studyOptions.prepareOutput = true; From 3a8929eb5ee9ee50469958cdc28b6f9005f56362 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 6 Jun 2024 14:49:12 +0200 Subject: [PATCH 098/101] fix compile --- src/tools/ts-generator/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index c33471942e..0bbc6b7ca0 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -159,7 +159,7 @@ int main(int argc, char* argv[]) return 1; } - if (settings.allLinks && !settings.linksToGen.empty() + if (settings.allLinks && !settings.linksListToGen.empty() { logs.error() << "Conflicting options, either choose all links or a list"; return 1; From 8c5ba5c21c5d0d54d55da3241658ccaa10ebabd5 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 6 Jun 2024 14:52:30 +0200 Subject: [PATCH 099/101] fix compile --- src/tools/ts-generator/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/ts-generator/main.cpp b/src/tools/ts-generator/main.cpp index 0bbc6b7ca0..8f23f60619 100644 --- a/src/tools/ts-generator/main.cpp +++ b/src/tools/ts-generator/main.cpp @@ -159,7 +159,7 @@ int main(int argc, char* argv[]) return 1; } - if (settings.allLinks && !settings.linksListToGen.empty() + if (settings.allLinks && !settings.linksListToGen.empty()) { logs.error() << "Conflicting options, either choose all links or a list"; return 1; From bcb91f314036721d2566a5aba6c1e9fd9273f6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 21 Jun 2024 11:31:20 +0200 Subject: [PATCH 100/101] Update docs/user-guide/04-migration-guides.md --- docs/user-guide/04-migration-guides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 2dd412413c..7f8df4cfdf 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -2,7 +2,7 @@ This is a list of all recent changes that came with new Antares Simulator features. The main goal of this document is to lower the costs of changing existing interfaces, both GUI and scripts. ## v9.2.0 -### (TS-generator only) TS generation for links +### (TS-generator only) TS generation for link capacities In files input/links//properties.ini, add the following properties - tsgen_direct_XXX, - tsgen_indirect_XXX From 41fd3c87cc9b56e66d44948aba4cf4f79c26c8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Fri, 21 Jun 2024 11:32:11 +0200 Subject: [PATCH 101/101] Update docs/user-guide/04-migration-guides.md --- docs/user-guide/04-migration-guides.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/user-guide/04-migration-guides.md b/docs/user-guide/04-migration-guides.md index 7f8df4cfdf..5dbc3f8885 100644 --- a/docs/user-guide/04-migration-guides.md +++ b/docs/user-guide/04-migration-guides.md @@ -18,7 +18,6 @@ with XXX in - "modulation" timeseries => input/links//prepro/_mod_{direct, indirect}.txt, 8760x1 values each in [0, 1] - number of TS to generate => generaldata.ini/General/nbtimeserieslinks (unsigned int, default value 1) -Add bool argument to optionally load time-series. This bool is false (default value) in antares-solver, and true in antares-ts-generator. Parameters are loaded in any case.- ## v9.1.0