From 356ef42e5f6982821f684c76fe7a36d1a627a5d2 Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:23:09 +0200 Subject: [PATCH] Refactor hydro series (#1705) * [DEV] Removed hydro/series.hxx * [DEV] Use a ref for TSNumbers * [DEV] Use a ref for TSNumbers (#1706) * [DEV] Use TimeSeries for ror * [DEV] Modify operator[] behavior * [DEV] storage * [CI] Upgrade python to 3.12 * [DEV] mingen * [DEV] replace tsindex with year in hydro/management * [DEV] Remove getIndex from hydro series * [DEV] code smells * Make hydro ts count a private member (#1712) * Refactor max power TS checks : internalize count of generation time series (ror, storage, mingen) We should not be able to change a TS count without resizing the TS. This was allowed when because this count was a public data member. So we make it a private data member, and change it only when resizing the associated data. * Make hydro time series cont a private member --------- Co-authored-by: guilpier-code <62292552+guilpier-code@users.noreply.github.com> --- .github/workflows/windows-vcpkg.yml | 4 +- src/libs/antares/study/CMakeLists.txt | 1 - src/libs/antares/study/area/list.cpp | 7 +- src/libs/antares/study/area/scratchpad.cpp | 2 +- .../antares/study/parts/common/cluster.cpp | 3 +- src/libs/antares/study/parts/common/cluster.h | 2 + src/libs/antares/study/parts/hydro/series.cpp | 92 ++++++++++++------- src/libs/antares/study/parts/hydro/series.h | 31 ++++--- src/libs/antares/study/parts/hydro/series.hxx | 39 -------- .../antares/study/parts/load/container.cpp | 2 +- src/libs/antares/study/parts/load/container.h | 2 + .../series/include/antares/series/series.h | 10 +- .../antares/study/parts/series/series.cpp | 38 +++++++- .../antares/study/parts/solar/container.cpp | 2 +- .../antares/study/parts/solar/container.h | 2 + .../antares/study/parts/wind/container.cpp | 2 +- src/libs/antares/study/parts/wind/container.h | 2 + .../study/scenario-builder/applyToMatrix.hxx | 2 +- src/solver/hydro/management/daily.cpp | 10 +- src/solver/hydro/management/management.cpp | 50 ++++------ src/solver/hydro/management/management.h | 4 +- .../simulation/sim_calcul_economique.cpp | 14 +-- src/solver/simulation/timeseries-numbers.cpp | 8 +- src/solver/ts-generator/hydro.cpp | 14 +-- src/solver/variable/commons/hydro.h | 5 +- .../test-sc-builder-file-read-line.cpp | 6 +- .../test-sc-builder-file-save.cpp | 9 +- .../handler/antares-study/area/timeseries.cpp | 11 +-- .../datagrid/renderer/area/timeseries.h | 6 +- 29 files changed, 190 insertions(+), 190 deletions(-) delete mode 100644 src/libs/antares/study/parts/hydro/series.hxx diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 3a9bc71d65..e54c221cdb 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -85,11 +85,11 @@ jobs: ortools-url: ${{env.ORTOOLS_URL}} ortools-dir: ${{env.ORTOOLS_DIR}} - - name: Setup Python 3.11 + - name: Setup Python 3.12 uses: actions/setup-python@v4 with: architecture: 'x64' - python-version: '3.11' + python-version: '3.12' - name: Install pip dependencies if necessary run: pip install -r src/tests/examples/requirements.txt diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index fa64c37077..1649aa8279 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -140,7 +140,6 @@ set(SRC_STUDY_PART_HYDRO parts/hydro/container.h parts/hydro/container.cpp parts/hydro/series.h - parts/hydro/series.hxx parts/hydro/series.cpp parts/hydro/prepro.h parts/hydro/prepro.cpp diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index e3afa3414c..3835ea7b9b 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1556,11 +1556,8 @@ void AreaList::removeLoadTimeseries() void AreaList::removeHydroTimeseries() { - each([](Data::Area& area) { - area.hydro.series->ror.reset(1, HOURS_PER_YEAR); - area.hydro.series->storage.reset(1, DAYS_PER_YEAR); - area.hydro.series->mingen.reset(1, HOURS_PER_YEAR); - area.hydro.series->count = 1; + each([&](Data::Area& area) { + area.hydro.series->reset(); }); } diff --git a/src/libs/antares/study/area/scratchpad.cpp b/src/libs/antares/study/area/scratchpad.cpp index 6c63ebf9ac..26595ae28d 100644 --- a/src/libs/antares/study/area/scratchpad.cpp +++ b/src/libs/antares/study/area/scratchpad.cpp @@ -111,7 +111,7 @@ AreaScratchpad::AreaScratchpad(const StudyRuntimeInfos& rinfos, Area& area) if (!area.hydro.prepro) // not in prepro mode { assert(area.hydro.series); - hydroHasInflows = MatrixTestForAtLeastOnePositiveValue(area.hydro.series->storage); + hydroHasInflows = MatrixTestForAtLeastOnePositiveValue(area.hydro.series->storage.timeSeries); } else { diff --git a/src/libs/antares/study/parts/common/cluster.cpp b/src/libs/antares/study/parts/common/cluster.cpp index 21c5488f59..64e925f8a5 100644 --- a/src/libs/antares/study/parts/common/cluster.cpp +++ b/src/libs/antares/study/parts/common/cluster.cpp @@ -14,7 +14,8 @@ Cluster::Cluster(Area* parent) : parentArea(parent), index(0), nominalCapacity(0.), - areaWideIndex((uint)-1) + areaWideIndex((uint)-1), + series(tsNumbers) { } diff --git a/src/libs/antares/study/parts/common/cluster.h b/src/libs/antares/study/parts/common/cluster.h index 9f46fabb3f..40a5d5dd7a 100644 --- a/src/libs/antares/study/parts/common/cluster.h +++ b/src/libs/antares/study/parts/common/cluster.h @@ -120,6 +120,8 @@ class Cluster //! Series TimeSeries series; + TimeSeries::TSNumbers tsNumbers; + /*! ** \brief Modulation matrix ** diff --git a/src/libs/antares/study/parts/hydro/series.cpp b/src/libs/antares/study/parts/hydro/series.cpp index d9b1c488b8..d3ec73d9ae 100644 --- a/src/libs/antares/study/parts/hydro/series.cpp +++ b/src/libs/antares/study/parts/hydro/series.cpp @@ -41,13 +41,29 @@ namespace Antares { namespace Data { -DataSeriesHydro::DataSeriesHydro() : count(0) +DataSeriesHydro::DataSeriesHydro() : + ror(timeseriesNumbers), + storage(timeseriesNumbers), + mingen(timeseriesNumbers) { // Pmin was introduced in v8.6 // The previous behavior was Pmin=0 // For compatibility reasons with existing studies, mingen is set to one column of zeros // by default - mingen.reset(1, HOURS_PER_YEAR); + mingen.reset(); +} + +void DataSeriesHydro::copyGenerationTS(DataSeriesHydro& source) +{ + ror.timeSeries = source.ror.timeSeries; + storage.timeSeries = source.storage.timeSeries; + mingen.timeSeries = source.mingen.timeSeries; + + count = source.count; + + source.ror.unloadFromMemory(); + source.storage.unloadFromMemory(); + source.mingen.unloadFromMemory(); } bool DataSeriesHydro::saveToFolder(const AreaName& areaID, const AnyString& folder) const @@ -61,11 +77,11 @@ bool DataSeriesHydro::saveToFolder(const AreaName& areaID, const AnyString& fold // Saving data buffer.clear() << folder << SEP << areaID << SEP << "ror.txt"; - ret = ror.saveToCSVFile(buffer, 0) && ret; + ret = ror.timeSeries.saveToCSVFile(buffer, 0) && ret; buffer.clear() << folder << SEP << areaID << SEP << "mod.txt"; - ret = storage.saveToCSVFile(buffer, 0) && ret; + ret = storage.timeSeries.saveToCSVFile(buffer, 0) && ret; buffer.clear() << folder << SEP << areaID << SEP << "mingen.txt"; - ret = mingen.saveToCSVFile(buffer, 0) && ret; + ret = mingen.timeSeries.saveToCSVFile(buffer, 0) && ret; return ret; } return false; @@ -78,21 +94,21 @@ bool DataSeriesHydro::loadFromFolder(Study& study, const AreaName& areaID, const buffer.clear() << folder << SEP << areaID << SEP << "ror." << study.inputExtension; - ret = ror.loadFromCSVFile(buffer, 1, HOURS_PER_YEAR, &study.dataBuffer) && ret; + ret = ror.timeSeries.loadFromCSVFile(buffer, 1, HOURS_PER_YEAR, &study.dataBuffer) && ret; buffer.clear() << folder << SEP << areaID << SEP << "mod." << study.inputExtension; - ret = storage.loadFromCSVFile(buffer, 1, DAYS_PER_YEAR, &study.dataBuffer) && ret; + ret = storage.timeSeries.loadFromCSVFile(buffer, 1, DAYS_PER_YEAR, &study.dataBuffer) && ret; // The number of time-series - count = storage.width; + count = storage.timeSeries.width; - if (ror.width > count) - count = ror.width; + if (ror.timeSeries.width > count) + count = ror.timeSeries.width; if (study.header.version >= 860) { buffer.clear() << folder << SEP << areaID << SEP << "mingen." << study.inputExtension; - ret = mingen.loadFromCSVFile(buffer, 1, HOURS_PER_YEAR, &study.dataBuffer) && ret; + ret = mingen.timeSeries.loadFromCSVFile(buffer, 1, HOURS_PER_YEAR, &study.dataBuffer) && ret; } if (study.usedByTheSolver) @@ -101,15 +117,15 @@ bool DataSeriesHydro::loadFromFolder(Study& study, const AreaName& areaID, const { logs.error() << "Hydro: `" << areaID << "`: empty matrix detected. Fixing it with default values"; - ror.reset(1, HOURS_PER_YEAR); - storage.reset(1, DAYS_PER_YEAR); - mingen.reset(1, HOURS_PER_YEAR); + ror.reset(); + storage.reset(); + mingen.reset(); } else { - if (count > 1 && storage.width != ror.width) + if (count > 1 && storage.timeSeries.width != ror.timeSeries.width) { - if (ror.width != 1 && storage.width != 1) + if (ror.timeSeries.width != 1 && storage.timeSeries.width != 1) { logs.fatal() << "Hydro: `" << areaID << "`: The matrices ROR (run-of-the-river) and hydro-storage must " @@ -118,19 +134,19 @@ bool DataSeriesHydro::loadFromFolder(Study& study, const AreaName& areaID, const } else { - if (ror.width == 1) + if (ror.timeSeries.width == 1) { - ror.resizeWithoutDataLost(count, ror.height); + ror.timeSeries.resizeWithoutDataLost(count, ror.timeSeries.height); for (uint x = 1; x < count; ++x) - ror.pasteToColumn(x, ror[0]); + ror.timeSeries.pasteToColumn(x, ror[0]); } else { - if (storage.width == 1) + if (storage.timeSeries.width == 1) { - storage.resizeWithoutDataLost(count, storage.height); + storage.timeSeries.resizeWithoutDataLost(count, storage.timeSeries.height); for (uint x = 1; x < count; ++x) - storage.pasteToColumn(x, storage[0]); + storage.timeSeries.pasteToColumn(x, storage[0]); } } Area* areaToInvalidate = study.areas.find(areaID); @@ -165,9 +181,9 @@ bool DataSeriesHydro::loadFromFolder(Study& study, const AreaName& areaID, const void DataSeriesHydro::checkMinGenTsNumber(Study& study, const AreaName& areaID) { - if (mingen.width != storage.width) + if (mingen.timeSeries.width != storage.timeSeries.width) { - if (mingen.width > 1) + if (mingen.timeSeries.width > 1) { logs.fatal() << "Hydro: `" << areaID << "`: The matrices Minimum Generation must " @@ -176,9 +192,9 @@ void DataSeriesHydro::checkMinGenTsNumber(Study& study, const AreaName& areaID) } else { - mingen.resizeWithoutDataLost(count, mingen.height); + mingen.timeSeries.resizeWithoutDataLost(count, mingen.timeSeries.height); for (uint x = 1; x < count; ++x) - mingen.pasteToColumn(x, mingen[0]); + mingen.timeSeries.pasteToColumn(x, mingen[0]); Area* areaToInvalidate = study.areas.find(areaID); if (areaToInvalidate) { @@ -211,20 +227,30 @@ void DataSeriesHydro::markAsModified() const void DataSeriesHydro::reset() { - ror.reset(1, HOURS_PER_YEAR); - storage.reset(1, DAYS_PER_YEAR); - mingen.reset(1, HOURS_PER_YEAR); + ror.reset(); + storage.reset(); + mingen.reset(); count = 1; } -uint64_t DataSeriesHydro::memoryUsage() const +void DataSeriesHydro::resizeRORandSTORAGE(unsigned int width) { - return sizeof(double) + ror.memoryUsage() + storage.memoryUsage() + mingen.memoryUsage(); + ror.resize(width, HOURS_PER_YEAR); + storage.resize(width, DAYS_PER_YEAR); + count = width; +} + +void DataSeriesHydro::resizeGenerationTS(unsigned int w, unsigned int h) +{ + ror.resize(w, h); + storage.resize(w, h); + mingen.resize(w, h); + count = w; } -unsigned int DataSeriesHydro::getIndex(unsigned int year) const +uint64_t DataSeriesHydro::memoryUsage() const { - return (count != 1) ? timeseriesNumbers[0][year] : 0; + return sizeof(double) + ror.memoryUsage() + storage.memoryUsage() + mingen.memoryUsage(); } } // namespace Data diff --git a/src/libs/antares/study/parts/hydro/series.h b/src/libs/antares/study/parts/hydro/series.h index eb13004820..f65ce1d001 100644 --- a/src/libs/antares/study/parts/hydro/series.h +++ b/src/libs/antares/study/parts/hydro/series.h @@ -27,6 +27,7 @@ #ifndef __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_H__ #define __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_H__ +#include #include #include "../../fwd.h" @@ -48,6 +49,8 @@ class DataSeriesHydro DataSeriesHydro(); //@} + void copyGenerationTS(DataSeriesHydro& source); + //! \name Data //@{ /*! @@ -55,6 +58,9 @@ class DataSeriesHydro */ void reset(); + void resizeRORandSTORAGE(unsigned int width); + void resizeGenerationTS(unsigned int w, unsigned int h); + /*! ** \brief Load all data not already loaded ** @@ -105,8 +111,6 @@ class DataSeriesHydro */ void checkMinGenTsNumber(Study& s, const AreaName& areaID); - unsigned int getIndex(unsigned int year) const; - public: /*! ** \brief Run-of-the-river - ROR (MW) @@ -114,7 +118,7 @@ class DataSeriesHydro ** (it was DAYS_PER_YEAR before 3.9) */ - Matrix ror; + TimeSeries ror; /*! ** \brief Mod (MW) @@ -122,14 +126,21 @@ class DataSeriesHydro ** Merely a matrix of TimeSeriesCount * 365 values ** This matrix is not used in `adequation` mode. */ - Matrix storage; + TimeSeries storage; /*! ** \brief Minimum Generation (MW) ** ** Merely a matrix of TimeSeriesCount * HOURS_PER_YEAR values */ - Matrix mingen; + TimeSeries mingen; + + unsigned int TScount() const { return count; }; + + /*! + ** \brief Monte-Carlo + */ + Matrix timeseriesNumbers; /*! ** \brief The number of time-series @@ -139,18 +150,12 @@ class DataSeriesHydro ** (for example using `fatal.width` and `mod.width` in the same routine, it might ** indicate that the two values are not strictly equal) */ - uint count; - - /*! - ** \brief Monte-Carlo - */ - Matrix timeseriesNumbers; +private: + uint count = 0; }; // class DataSeriesHydro } // namespace Data } // namespace Antares -#include "series.hxx" - #endif /* __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_H__ */ diff --git a/src/libs/antares/study/parts/hydro/series.hxx b/src/libs/antares/study/parts/hydro/series.hxx deleted file mode 100644 index 6be220a868..0000000000 --- a/src/libs/antares/study/parts/hydro/series.hxx +++ /dev/null @@ -1,39 +0,0 @@ -/* -** Copyright 2007-2023 RTE -** Authors: Antares_Simulator Team -** -** This file is part of Antares_Simulator. -** -** Antares_Simulator is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** There are special exceptions to the terms and conditions of the -** license as they are applied to this software. View the full text of -** the exceptions in file COPYING.txt in the directory of this software -** distribution -** -** 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 -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with Antares_Simulator. If not, see . -** -** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions -*/ -#ifndef __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_HXX__ -#define __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_HXX__ - -namespace Antares -{ -namespace Data -{ -// gp : whole file to be removed - -} // namespace Data -} // namespace Antares - -#endif // __ANTARES_LIBS_STUDY_PARTS_HYDRO_TIMESERIES_HXX__ diff --git a/src/libs/antares/study/parts/load/container.cpp b/src/libs/antares/study/parts/load/container.cpp index bfc6a29ec2..37193181ad 100644 --- a/src/libs/antares/study/parts/load/container.cpp +++ b/src/libs/antares/study/parts/load/container.cpp @@ -34,7 +34,7 @@ using namespace Yuni; namespace Antares::Data::Load { -Container::Container() : prepro(nullptr) +Container::Container() : prepro(nullptr), series(tsNumbers) { } diff --git a/src/libs/antares/study/parts/load/container.h b/src/libs/antares/study/parts/load/container.h index dbe3846f6a..379d9d9483 100644 --- a/src/libs/antares/study/parts/load/container.h +++ b/src/libs/antares/study/parts/load/container.h @@ -77,6 +77,8 @@ class Container final : private Yuni::NonCopyable /*! Data for time-series */ TimeSeries series; + TimeSeries::TSNumbers tsNumbers; + }; // class Container } // namespace Load diff --git a/src/libs/antares/study/parts/series/include/antares/series/series.h b/src/libs/antares/study/parts/series/include/antares/series/series.h index 2c7668c0e3..7dd51e51a8 100644 --- a/src/libs/antares/study/parts/series/include/antares/series/series.h +++ b/src/libs/antares/study/parts/series/include/antares/series/series.h @@ -38,6 +38,7 @@ class TimeSeries using TSNumbers = Matrix; using TS = Matrix; + explicit TimeSeries(TSNumbers& tsNumbers); /*! ** \brief Load series from a file ** @@ -62,18 +63,25 @@ class TimeSeries int timeSeriesSaveToFolder(const AreaName& areaID, const std::string& folder, const std::string& prefix) const; + bool setCoefficient(double value, uint32_t year, uint32_t hourInYear); double getCoefficient(uint32_t year, uint32_t hourInYear) const; const double* getColumn(uint32_t year) const; uint32_t getSeriesIndex(uint32_t year) const; + double* operator[](uint32_t year); + void reset(); + void unloadFromMemory() const; + void roundAllEntries(); + void resize(uint32_t year, uint32_t hour); + void averageTimeseries(); bool forceReload(bool reload = false) const; void markAsModified() const; uint64_t memoryUsage() const; TS timeSeries; - TSNumbers timeseriesNumbers; + TSNumbers& timeseriesNumbers; static const double emptyColumn[HOURS_PER_YEAR]; }; diff --git a/src/libs/antares/study/parts/series/series.cpp b/src/libs/antares/study/parts/series/series.cpp index afcea1df91..5ffeaa1e6e 100644 --- a/src/libs/antares/study/parts/series/series.cpp +++ b/src/libs/antares/study/parts/series/series.cpp @@ -40,6 +40,9 @@ namespace Antares::Data const double TimeSeries::emptyColumn[] = {0}; +TimeSeries::TimeSeries(TSNumbers& tsNumbers) : timeseriesNumbers(tsNumbers) +{} + bool TimeSeries::timeSeriesLoadFromFolder(const std::string& path, Matrix<>::BufferType dataBuffer, const bool average) @@ -63,10 +66,7 @@ int TimeSeries::timeSeriesSaveToFolder(const AreaName& areaID, const std::string return timeSeries.saveToCSVFile(buffer, 0); } -void TimeSeries::reset() -{ - timeSeries.reset(1, HOURS_PER_YEAR); -} + double TimeSeries::getCoefficient(uint32_t year, uint32_t hourInYear) const { @@ -90,6 +90,36 @@ uint32_t TimeSeries::getSeriesIndex(uint32_t year) const return timeseriesNumbers[0][year]; } +double* TimeSeries::operator[](uint32_t year) +{ + return timeSeries[year]; +} + +void TimeSeries::reset() +{ + timeSeries.reset(1, HOURS_PER_YEAR); +} + +void TimeSeries::resize(uint32_t year, uint32_t hour) +{ + timeSeries.resize(year, hour); +} + +void TimeSeries::roundAllEntries() +{ + timeSeries.roundAllEntries(); +} + +void TimeSeries::averageTimeseries() +{ + timeSeries.averageTimeseries(); +} + +void TimeSeries::unloadFromMemory() const +{ + timeSeries.unloadFromMemory(); +} + bool TimeSeries::forceReload(bool reload) const { return timeSeries.forceReload(reload); diff --git a/src/libs/antares/study/parts/solar/container.cpp b/src/libs/antares/study/parts/solar/container.cpp index 66d6879cde..033a26b4c7 100644 --- a/src/libs/antares/study/parts/solar/container.cpp +++ b/src/libs/antares/study/parts/solar/container.cpp @@ -38,7 +38,7 @@ namespace Data { namespace Solar { -Container::Container() : prepro(nullptr) +Container::Container() : prepro(nullptr), series(tsNumbers) {} Container::~Container() diff --git a/src/libs/antares/study/parts/solar/container.h b/src/libs/antares/study/parts/solar/container.h index 4cac7e147b..4d7831ce44 100644 --- a/src/libs/antares/study/parts/solar/container.h +++ b/src/libs/antares/study/parts/solar/container.h @@ -75,6 +75,8 @@ class Container /*! Data for time-series */ TimeSeries series; + TimeSeries::TSNumbers tsNumbers; + }; // class Container } // namespace Solar diff --git a/src/libs/antares/study/parts/wind/container.cpp b/src/libs/antares/study/parts/wind/container.cpp index a73dedf3b4..c6d7adfbac 100644 --- a/src/libs/antares/study/parts/wind/container.cpp +++ b/src/libs/antares/study/parts/wind/container.cpp @@ -37,7 +37,7 @@ namespace Data { namespace Wind { -Container::Container() : prepro(nullptr) +Container::Container() : prepro(nullptr), series(tsNumbers) { } diff --git a/src/libs/antares/study/parts/wind/container.h b/src/libs/antares/study/parts/wind/container.h index b60e9584cf..a01701f11e 100644 --- a/src/libs/antares/study/parts/wind/container.h +++ b/src/libs/antares/study/parts/wind/container.h @@ -75,6 +75,8 @@ class Container /*! Data for time-series */ TimeSeries series; + TimeSeries::TSNumbers tsNumbers; + }; // class Container } // namespace Wind diff --git a/src/libs/antares/study/scenario-builder/applyToMatrix.hxx b/src/libs/antares/study/scenario-builder/applyToMatrix.hxx index c2990af51d..2937c57a76 100644 --- a/src/libs/antares/study/scenario-builder/applyToMatrix.hxx +++ b/src/libs/antares/study/scenario-builder/applyToMatrix.hxx @@ -25,7 +25,7 @@ inline bool CheckValidity(uint value, uint tsGenMax) { // When the TS-Generators are not used - return (!tsGenMax) ? (value < data.count) : (value < tsGenMax); + return (!tsGenMax) ? (value < data.TScount()) : (value < tsGenMax); } template<> diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index e2648e37b7..f28b9600ac 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -81,7 +81,6 @@ enum struct DebugData { - using InflowsType = Matrix::ColumnType; using MaxPowerType = Matrix::ColumnType; using ReservoirLevelType = Matrix::ColumnType; @@ -100,7 +99,7 @@ struct DebugData Solver::IResultWriter& pWriter; const TmpDataByArea& data; const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults; - const InflowsType& srcinflows; + const double* srcinflows; const MaxPowerType& maxP; const MaxPowerType& maxE; const double* dailyTargetGen; @@ -110,7 +109,7 @@ struct DebugData DebugData(Solver::IResultWriter& writer, const TmpDataByArea& data, const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults, - const InflowsType& srcinflows, + const double* srcinflows, const MaxPowerType& maxP, const MaxPowerType& maxE, const double* dailyTargetGen, @@ -230,10 +229,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St uint z = area.index; assert(z < areas_.size()); - auto& inflowsmatrix = area.hydro.series->storage; - - auto tsIndex = area.hydro.series->getIndex(y); - auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; + auto const srcinflows = area.hydro.series->storage.getColumn(y); auto& data = tmpDataByArea_[numSpace][z]; diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 71ea8203b8..1794b17bd5 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -130,10 +130,7 @@ void HydroManagement::prepareInflowsScaling(uint numSpace, uint year) { uint z = area.index; - auto& inflowsmatrix = area.hydro.series->storage; - assert(inflowsmatrix.width && inflowsmatrix.height); - auto tsIndex = area.hydro.series->getIndex(year); - auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; + auto const& srcinflows = area.hydro.series->storage.getColumn(year); auto& data = tmpDataByArea_[numSpace][z]; double totalYearInflows = 0.0; @@ -179,12 +176,9 @@ void HydroManagement::minGenerationScaling(uint numSpace, uint year) const { areas_.each([this, &numSpace, &year](Data::Area& area) { - uint z = area.index; - - auto& mingenmatrix = area.hydro.series->mingen; - auto tsIndex = area.hydro.series->getIndex(year); - auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; + auto const& srcmingen = area.hydro.series->mingen.getColumn(year); + uint z = area.index; auto& data = tmpDataByArea_[numSpace][z]; double totalYearMingen = 0.0; @@ -234,7 +228,7 @@ void HydroManagement::minGenerationScaling(uint numSpace, uint year) const }); } -bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint tsIndex, const Data::Area& area) const +bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const { const auto& data = tmpDataByArea_[numSpace][area.index]; for (uint month = 0; month != 12; ++month) @@ -245,7 +239,7 @@ bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint tsIndex, con { logs.error() << "In Area " << area.name << " the minimum generation of " << data.totalMonthMingen[realmonth] << " MW in month " << month + 1 - << " of TS-" << tsIndex + 1 << " is incompatible with the inflows of " + << " of TS-" << year + 1 << " is incompatible with the inflows of " << data.totalMonthInflows[realmonth] << " MW."; return false; } @@ -253,26 +247,24 @@ bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint tsIndex, con return true; } -bool HydroManagement::checkYearlyMinGeneration(uint numSpace, uint tsIndex, const Data::Area& area) const +bool HydroManagement::checkYearlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const { const auto& data = tmpDataByArea_[numSpace][area.index]; if (data.totalYearMingen > data.totalYearInflows) { // Yearly minimum generation <= Yearly inflows logs.error() << "In Area " << area.name << " the minimum generation of " - << data.totalYearMingen << " MW of TS-" << tsIndex + 1 + << data.totalYearMingen << " MW of TS-" << year + 1 << " is incompatible with the inflows of " << data.totalYearInflows << " MW."; return false; } return true; } -bool HydroManagement::checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) const +bool HydroManagement::checkWeeklyMinGeneration(uint year, const Data::Area& area) const { - auto& inflowsmatrix = area.hydro.series->storage; - auto& mingenmatrix = area.hydro.series->mingen; - auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; - auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; + auto const& srcinflows = area.hydro.series->storage.getColumn(year); + auto const& srcmingen = area.hydro.series->mingen.getColumn(year); // Weekly minimum generation <= Weekly inflows for each week for (uint week = 0; week < calendar_.maxWeeksInYear - 1; ++week) { @@ -295,7 +287,7 @@ bool HydroManagement::checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) c { logs.error() << "In Area " << area.name << " the minimum generation of " << totalWeekMingen << " MW in week " << week + 1 << " of TS-" - << tsIndex + 1 << " is incompatible with the inflows of " + << year + 1 << " is incompatible with the inflows of " << totalWeekInflows << " MW."; return false; } @@ -303,11 +295,10 @@ bool HydroManagement::checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) c return true; } -bool HydroManagement::checkHourlyMinGeneration(uint tsIndex, Data::Area& area) const +bool HydroManagement::checkHourlyMinGeneration(uint year, const Data::Area& area) const { // Hourly minimum generation <= hourly inflows for each hour - auto& mingenmatrix = area.hydro.series->mingen; - auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; + auto const& srcmingen = area.hydro.series->mingen.getColumn(year); auto const& maxPower = area.hydro.maxPower; auto const& maxP = maxPower[Data::PartHydro::genMaxP]; @@ -328,7 +319,7 @@ bool HydroManagement::checkHourlyMinGeneration(uint tsIndex, Data::Area& area) c logs.error() << "In area: " << area.name << " [hourly] minimum generation of " << srcmingen[day * 24 + h] << " MW in timestep " << day * 24 + h + 1 - << " of TS-" << tsIndex + 1 + << " of TS-" << year + 1 << " is incompatible with the maximum generation of " << maxP[day] << " MW."; return false; @@ -344,28 +335,26 @@ bool HydroManagement::checkMinGeneration(uint numSpace, uint year) const bool ret = true; areas_.each([this, &numSpace, &ret, &year](Data::Area& area) { - auto tsIndex = area.hydro.series->getIndex(year); - bool useHeuristicTarget = area.hydro.useHeuristicTarget; bool followLoadModulations = area.hydro.followLoadModulations; bool reservoirManagement = area.hydro.reservoirManagement; if (!reservoirManagement) - ret = checkHourlyMinGeneration(tsIndex, area) && ret; + ret = checkHourlyMinGeneration(year, area) && ret; if (!useHeuristicTarget) return; if (!followLoadModulations) { - ret = checkWeeklyMinGeneration(tsIndex, area) && ret; + ret = checkWeeklyMinGeneration(year, area) && ret; return; } if (reservoirManagement) - ret = checkYearlyMinGeneration(numSpace, tsIndex, area) && ret; + ret = checkYearlyMinGeneration(numSpace, year, area) && ret; else - ret = checkMonthlyMinGeneration(numSpace, tsIndex, area) && ret; + ret = checkMonthlyMinGeneration(numSpace, year, area) && ret; }); return ret; } @@ -379,8 +368,7 @@ void HydroManagement::prepareNetDemand(uint numSpace, uint year) auto& scratchpad = area.scratchpad[numSpace]; auto& rormatrix = area.hydro.series->ror; - auto tsIndex = area.hydro.series->getIndex(year); - auto& ror = rormatrix[tsIndex < rormatrix.width ? tsIndex : 0]; + const auto* ror = rormatrix.getColumn(year); auto& data = tmpDataByArea_[numSpace][z]; const double* loadSeries = area.load.series.getColumn(year); diff --git a/src/solver/hydro/management/management.h b/src/solver/hydro/management/management.h index 67d52f57ad..34f4136948 100644 --- a/src/solver/hydro/management/management.h +++ b/src/solver/hydro/management/management.h @@ -129,9 +129,9 @@ class HydroManagement final //! check Yearly minimum generation is lower than available inflows bool checkYearlyMinGeneration(uint numSpace, uint tsIndex, const Data::Area& area) const; //! check Weekly minimum generation is lower than available inflows - bool checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) const; + bool checkWeeklyMinGeneration(uint tsIndex, const Data::Area& area) const; //! check Hourly minimum generation is lower than available inflows - bool checkHourlyMinGeneration(uint tsIndex, Data::Area& area) const; + bool checkHourlyMinGeneration(uint tsIndex, const Data::Area& area) const; //! check minimum generation is lower than available inflows bool checkMinGeneration(uint numSpace, uint year) const; //! Prepare the net demand for each area diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 5b584b1ff0..3b950219af 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -573,24 +573,23 @@ void SIM_RenseignementProblemeHebdo(const Study& study, auto loadSeries = area.load.series.getCoefficient(year, hourInYear); auto windSeries = area.wind.series.getCoefficient(year, hourInYear); auto solarSeries = area.solar.series.getCoefficient(year, hourInYear); - auto hydroSeriesIndex = area.hydro.series->getIndex(year); + auto rorSeriesIndex = area.hydro.series->ror.getSeriesIndex(year); assert(&scratchpad); - uint tsFatalIndex = hydroSeriesIndex < ror.width ? hydroSeriesIndex : 0; double& mustRunGen = problem.AllMustRunGeneration[hourInWeek].AllMustRunGenerationOfArea[k]; if (parameters.renewableGeneration.isAggregated()) { mustRunGen = windSeries + solarSeries - + scratchpad.miscGenSum[hourInYear] + ror[tsFatalIndex][hourInYear] + + scratchpad.miscGenSum[hourInYear] + ror[rorSeriesIndex][hourInYear] + scratchpad.mustrunSum[hourInYear]; } // Renewable if (parameters.renewableGeneration.isClusters()) { - mustRunGen = scratchpad.miscGenSum[hourInYear] + ror[tsFatalIndex][hourInYear] + mustRunGen = scratchpad.miscGenSum[hourInYear] + ror[rorSeriesIndex][hourInYear] + scratchpad.mustrunSum[hourInYear]; area.renewable.list.each([&](const RenewableCluster& cluster) { @@ -633,12 +632,9 @@ void SIM_RenseignementProblemeHebdo(const Study& study, { auto& area = *study.areas.byIndex[k]; auto& hydroSeries = area.hydro.series; - uint tsIndex = hydroSeries->getIndex(year); - auto& inflowsmatrix = hydroSeries->storage; - auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; - auto& mingenmatrix = hydroSeries->mingen; - auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; + auto const& srcinflows = hydroSeries->storage.getColumn(year); + auto const& srcmingen = hydroSeries->mingen.getColumn(year); for (uint j = 0; j < problem.NombreDePasDeTemps; ++j) { problem.CaracteristiquesHydrauliques[k].MingenHoraire[j] diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index 2793710bd8..a85da87f83 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -148,7 +148,7 @@ class hydroAreaNumberOfTSretriever : public areaNumberOfTSretriever } std::vector getAreaTimeSeriesNumber(const Area& area) { - std::vector to_return = {area.hydro.series->count}; + std::vector to_return = {area.hydro.series->TScount()}; return to_return; } uint getGeneratedTimeSeriesNumber() @@ -420,7 +420,7 @@ bool checkInterModalConsistencyForArea(Area& area, if (isTSintermodal[indexTS]) { uint nbTimeSeries - = isTSgenerated[indexTS] ? parameters.nbTimeSeriesHydro : area.hydro.series->count; + = isTSgenerated[indexTS] ? parameters.nbTimeSeriesHydro : area.hydro.series->TScount(); listNumberTsOverArea.push_back(nbTimeSeries); } @@ -635,7 +635,7 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i if (!isTSintramodal[indexTS]) { uint nbTimeSeries - = isTSgenerated[indexTS] ? nbTimeseriesByMode[indexTS] : area.hydro.series->ror.width; + = isTSgenerated[indexTS] ? nbTimeseriesByMode[indexTS] : area.hydro.series->ror.timeSeries.width; area.hydro.series->timeseriesNumbers[0][year] = (uint32_t)(floor(study.runtime->random[seedTimeseriesNumbers].next() * nbTimeSeries)); } @@ -832,7 +832,7 @@ static void fixTSNumbersWhenWidthIsOne(Study& study) area.wind.series.timeseriesNumbers, area.wind.series.timeSeries.width, years); // Hydro fixTSNumbersSingleAreaSingleMode( - area.hydro.series->timeseriesNumbers, area.hydro.series->count, years); + area.hydro.series->timeseriesNumbers, area.hydro.series->TScount(), years); // Thermal std::for_each(area.thermal.clusters.cbegin(), diff --git a/src/solver/ts-generator/hydro.cpp b/src/solver/ts-generator/hydro.cpp index c554de8852..f8a3909c7d 100644 --- a/src/solver/ts-generator/hydro.cpp +++ b/src/solver/ts-generator/hydro.cpp @@ -50,11 +50,7 @@ namespace TSGenerator static void PreproHydroInitMatrices(Data::Study& study, uint tsCount) { study.areas.each([&](Data::Area& area) { - auto& hydroseries = *(area.hydro.series); - - hydroseries.ror.resize(tsCount, HOURS_PER_YEAR); - hydroseries.storage.resize(tsCount, DAYS_PER_YEAR); - hydroseries.count = tsCount; + area.hydro.series->resizeRORandSTORAGE(tsCount); }); } @@ -184,7 +180,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, IResultWriter auto& area = *(study.areas.byIndex[i / 12]); auto& prepro = *area.hydro.prepro; auto& series = *area.hydro.series; - auto& ror = series.ror[l]; + auto ror = series.ror[l]; auto& colExpectation = prepro.data[Data::PreproHydro::expectation]; auto& colStdDeviation = prepro.data[Data::PreproHydro::stdDeviation]; @@ -196,7 +192,7 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, IResultWriter uint realmonth = calendar.months[month].realmonth; uint daysPerMonth = calendar.months[month].days; - assert(l < series.ror.width); + assert(l < series.ror.timeSeries.width); assert(not Math::NaN(colPOW[realmonth])); if (month == 0) @@ -300,14 +296,14 @@ bool GenerateHydroTimeSeries(Data::Study& study, uint currentYear, IResultWriter { std::string buffer; - area.hydro.series->ror.saveToBuffer(buffer, precision); + area.hydro.series->ror.timeSeries.saveToBuffer(buffer, precision); output.clear() << study.buffer << SEP << "ror.txt"; writer.addEntryFromBuffer(output.c_str(), buffer); } { std::string buffer; - area.hydro.series->storage.saveToBuffer(buffer, precision); + area.hydro.series->storage.timeSeries.saveToBuffer(buffer, precision); output.clear() << study.buffer << SEP << "storage.txt"; writer.addEntryFromBuffer(output.c_str(), buffer); } diff --git a/src/solver/variable/commons/hydro.h b/src/solver/variable/commons/hydro.h index c1b446b8a3..56a4d78fae 100644 --- a/src/solver/variable/commons/hydro.h +++ b/src/solver/variable/commons/hydro.h @@ -199,9 +199,8 @@ class TimeSeriesValuesHydro { // The current time-series auto& ror = pArea->hydro.series->ror; - const unsigned int nbchro - = pArea->hydro.series->getIndex(year); - pFatalValues[numSpace] = &(ror.entry[(nbchro < ror.width ? nbchro : 0)]); + const unsigned int nbchro = ror.getSeriesIndex(year); + pFatalValues[numSpace] = &(ror.timeSeries.entry[nbchro]); // Next variable NextType::yearBegin(year, numSpace); diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp index 985a036bdc..ad39460e08 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-read-line.cpp @@ -82,9 +82,9 @@ struct Fixture // Hydro : set the nb of ready made TS nbReadyMadeTS = 12; - area_1->hydro.series->count = nbReadyMadeTS; - area_2->hydro.series->count = nbReadyMadeTS; - area_3->hydro.series->count = nbReadyMadeTS; + area_1->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); + area_2->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); + area_3->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); // Links link_12 = AreaAddLinkBetweenAreas(area_1, area_2, false); diff --git a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp index 3c6c4a0f37..0fef661c93 100644 --- a/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp +++ b/src/tests/src/libs/antares/study/scenario-builder/test-sc-builder-file-save.cpp @@ -95,8 +95,7 @@ struct commonFixture study = std::make_shared(); // Set study parameters study->parameters.nbYears = 20; - study->parameters.timeSeriesToGenerate - = 0; // No generated time-series, only ready made time-series + study->parameters.timeSeriesToGenerate = 0; // No generated time-series, only ready made time-series // Add areas area_1 = study->areaAdd("Area 1"); @@ -124,9 +123,9 @@ struct commonFixture // Hydro : set the nb of ready made TS nbReadyMadeTS = 12; - area_1->hydro.series->count = nbReadyMadeTS; - area_2->hydro.series->count = nbReadyMadeTS; - area_3->hydro.series->count = nbReadyMadeTS; + area_1->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); + area_2->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); + area_3->hydro.series->resizeGenerationTS(nbReadyMadeTS, 1); // Links link_12 = AreaAddLinkBetweenAreas(area_1, area_2, false); diff --git a/src/ui/action/handler/antares-study/area/timeseries.cpp b/src/ui/action/handler/antares-study/area/timeseries.cpp index cafff3392b..eebedab74a 100644 --- a/src/ui/action/handler/antares-study/area/timeseries.cpp +++ b/src/ui/action/handler/antares-study/area/timeseries.cpp @@ -155,16 +155,7 @@ bool DataTimeseries::performWL(Context& ctx) } case Data::timeSeriesHydro: { - ctx.area->hydro.series->ror = source->hydro.series->ror; - ctx.area->hydro.series->storage = source->hydro.series->storage; - ctx.area->hydro.series->mingen = source->hydro.series->mingen; - - ctx.area->hydro.series->count = source->hydro.series->count; - - source->hydro.series->ror.unloadFromMemory(); - source->hydro.series->storage.unloadFromMemory(); - source->hydro.series->mingen.unloadFromMemory(); - + ctx.area->hydro.series->copyGenerationTS(*source->hydro.series); break; } case Data::timeSeriesThermal: diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.h index cdd41aaccc..17e0e62d2a 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/timeseries.h @@ -256,7 +256,7 @@ class TimeSeriesHydroFatal final : public ATimeSeries protected: virtual void internalAreaChanged(Antares::Data::Area* area) { - matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->ror) : NULL); + matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->ror.timeSeries) : NULL); Renderer::ARendererArea::internalAreaChanged(area); } }; @@ -294,7 +294,7 @@ class TimeSeriesHydroMod final : public ATimeSeries protected: virtual void internalAreaChanged(Antares::Data::Area* area) { - matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->storage) : NULL); + matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->storage.timeSeries) : NULL); Renderer::ARendererArea::internalAreaChanged(area); } }; @@ -327,7 +327,7 @@ class TimeSeriesHydroMinGen final : public ATimeSeries private: void internalAreaChanged(Antares::Data::Area* area) override { - matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->mingen) : NULL); + matrix((area && CurrentStudyIsValid()) ? &(area->hydro.series->mingen.timeSeries) : NULL); Renderer::ARendererArea::internalAreaChanged(area); } };