diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 7978abc23f..c5cba3e87e 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -6,7 +6,8 @@ on: - main - develop - release/* - pull_request: + - fix/* + - feature/* jobs: sonarcloud: diff --git a/.gitignore b/.gitignore index 1afaf89c00..e9566a3906 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ Makefile src/.vs src/config.h +src/config/include # Yuni src/ext/yuni/src/ProfileBuild.cmake diff --git a/src/libs/antares/InfoCollection/StudyInfoCollector.cpp b/src/libs/antares/InfoCollection/StudyInfoCollector.cpp index f4bdfa50b7..20a1672b74 100644 --- a/src/libs/antares/InfoCollection/StudyInfoCollector.cpp +++ b/src/libs/antares/InfoCollection/StudyInfoCollector.cpp @@ -78,9 +78,8 @@ void StudyInfoCollector::enabledThermalClustersCountToFileContent(FileContent& f auto end = study_.areas.end(); for (auto i = study_.areas.begin(); i != end; ++i) { - Area& area = *(i->second); - nbEnabledThermalClusters += - std::ranges::count_if(area.thermal.list, [](const auto& c) { return c->enabled; }); + const Area& area = *(i->second); + nbEnabledThermalClusters += area.thermal.list.enabledAndNotMustRunCount(); } // Adding an item related to number of enabled thermal clusters to the file content diff --git a/src/libs/antares/checks/checkLoadedInputData.cpp b/src/libs/antares/checks/checkLoadedInputData.cpp index 0dce719811..f13c8f2011 100644 --- a/src/libs/antares/checks/checkLoadedInputData.cpp +++ b/src/libs/antares/checks/checkLoadedInputData.cpp @@ -143,7 +143,7 @@ void checkMinStablePower(bool tsGenThermal, const Antares::Data::AreaList& areas } else { - areas.each([](Antares::Data::Area& area) { area.thermal.checkAndCorrectAvailability(); }); + areas.each([](const auto& area) { area.thermal.checkAndCorrectAvailability(); }); } } @@ -158,16 +158,15 @@ static void checkThermalColumnNumber(const Antares::Data::AreaList& areas, for (uint areaIndex = 0; areaIndex < areas.size(); ++areaIndex) { const auto& area = *(areas.byIndex[areaIndex]); - for (uint clusterIndex = 0; clusterIndex != area.thermal.clusterCount(); ++clusterIndex) + for (auto cluster : area.thermal.list.each_enabled()) { - const auto& cluster = *(area.thermal.clusters[clusterIndex]); - if (cluster.costgeneration == Antares::Data::setManually) + if (cluster->costgeneration == Antares::Data::setManually) continue; - const uint otherMatrixWidth = (cluster.ecoInput.*matrix).width; - uint tsWidth = cluster.series.timeSeries.width; + const uint otherMatrixWidth = (cluster->ecoInput.*matrix).width; + uint tsWidth = cluster->series.timeSeries.width; if (otherMatrixWidth != 1 && otherMatrixWidth != tsWidth) { - logs.warning() << "Area: " << area.name << ". Cluster name: " << cluster.name() + logs.warning() << "Area: " << area.name << ". Cluster name: " << cluster->name() << ". " << exception.what(); error = true; } diff --git a/src/libs/antares/study/CMakeLists.txt b/src/libs/antares/study/CMakeLists.txt index 507197fa71..2f61b665d2 100644 --- a/src/libs/antares/study/CMakeLists.txt +++ b/src/libs/antares/study/CMakeLists.txt @@ -67,7 +67,6 @@ source_group("study\\part\\common" FILES ${SRC_STUDY_PART_COMMON}) set(SRC_STUDY_PART_THERMAL include/antares/study/parts/thermal/container.h - include/antares/study/parts/thermal/container.hxx parts/thermal/container.cpp include/antares/study/parts/thermal/prepro.h include/antares/study/parts/thermal/prepro.hxx @@ -318,4 +317,4 @@ target_include_directories(study install(DIRECTORY include/antares DESTINATION "include" -) \ No newline at end of file +) diff --git a/src/libs/antares/study/area/area.cpp b/src/libs/antares/study/area/area.cpp index 06cc79c4b6..a8deec80a2 100644 --- a/src/libs/antares/study/area/area.cpp +++ b/src/libs/antares/study/area/area.cpp @@ -271,9 +271,8 @@ void Area::resizeAllTimeseriesNumbers(uint nbYears) bool Area::thermalClustersMinStablePowerValidity(std::vector& output) const { bool noErrorMinStabPow = true; - for (uint l = 0; l != thermal.clusterCount(); ++l) + for (auto cluster : thermal.list.each_enabled()) { - auto& cluster = thermal.clusters[l]; logs.debug() << "cluster : " << cluster->name(); if ((not cluster->checkMinStablePower()) || (cluster->minStablePower diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index d14c13232c..8b25d0fe60 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -769,14 +769,6 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, StringT& buffer, const StudyLoadOptions& options) { - // Progression - options.progressTicks = 0; - options.progressTickCount - = area.thermal.list.size() * (options.loadOnlyNeeded ? 1 : 2) // prepro+series - + 1 // links - + 4 // load,solar,wind,hydro - + 1; // DSM,misc... - // Reset area.filterSynthesis = filterAll; area.filterYearByYear = filterAll; @@ -815,15 +807,10 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, MatrixTestForPositiveValues_LimitWidth(buffer.c_str(), &area.miscGen, fhhPSP); } - ++options.progressTicks; - options.pushProgressLogs(); - // Links { buffer.clear() << study.folderInput << SEP << "links" << SEP << area.id; ret = AreaLinksLoadFromFolder(study, list, &area, buffer) && ret; - ++options.progressTicks; - options.pushProgressLogs(); } // UI @@ -853,9 +840,6 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = area.load.series.loadFromFile(buffer.c_str(), averageTs) && ret; } - - ++options.progressTicks; - options.pushProgressLogs(); } // Solar @@ -875,9 +859,6 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, && ret; } - - ++options.progressTicks; - options.pushProgressLogs(); } // Hydro @@ -898,9 +879,6 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "series"; ret = area.hydro.series->loadFromFolder(study, area.id, buffer) && ret; } - - ++options.progressTicks; - options.pushProgressLogs(); } // Wind @@ -919,17 +897,14 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, ret = area.wind.series.loadFromFile(buffer.c_str(), averageTs) && ret; } - - ++options.progressTicks; - options.pushProgressLogs(); } // Thermal cluster list { buffer.clear() << study.folderInput << SEP << "thermal" << SEP << "prepro"; - ret = area.thermal.list.loadPreproFromFolder(study, options, buffer) && ret; + ret = area.thermal.list.loadPreproFromFolder(study, buffer) && ret; buffer.clear() << study.folderInput << SEP << "thermal" << SEP << "series"; - ret = area.thermal.list.loadDataSeriesFromFolder(study, options, buffer) && ret; + ret = area.thermal.list.loadDataSeriesFromFolder(study, buffer) && ret; ret = area.thermal.list.loadEconomicCosts(study, buffer) && ret; // In adequacy mode, all thermal clusters must be in 'mustrun' mode @@ -951,7 +926,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, if (study.header.version >= StudyVersion(8, 1)) { buffer.clear() << study.folderInput << SEP << "renewables" << SEP << "series"; - ret = area.renewable.list.loadDataSeriesFromFolder(study, options, buffer) && ret; + ret = area.renewable.list.loadDataSeriesFromFolder(study, buffer) && ret; } // Adequacy patch @@ -1096,7 +1071,6 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) Area& area = *(i->second); buffer.clear() << pStudy.folderInput << thermalPlant << area.id; ret = area.thermal.list.loadFromFolder(pStudy, buffer.c_str(), &area) && ret; - area.thermal.prepareAreaWideIndexes(); } } @@ -1136,7 +1110,6 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) Area& area = *(i->second); buffer.clear() << pStudy.folderInput << renewablePlant << area.id; ret = area.renewable.list.loadFromFolder(buffer.c_str(), &area) && ret; - area.renewable.prepareAreaWideIndexes(); } } @@ -1291,7 +1264,6 @@ void AreaListEnsureDataHydroPrepro(AreaList* l) void AreaListEnsureDataThermalPrepro(AreaList* l) { - assert(l && "The area list must not be nullptr"); l->each([&](Data::Area& area) { area.thermal.list.ensureDataPrepro(); }); } @@ -1529,8 +1501,7 @@ ThermalCluster* AreaList::findClusterFromINIKey(const AnyString& key) Area* parentArea = findFromName(parentName); if (parentArea == nullptr) return nullptr; - return parentArea->thermal.list.find(id); - + return parentArea->thermal.list.findInAll(id); } void AreaList::updateNameIDSet() const @@ -1569,8 +1540,8 @@ void AreaList::removeWindTimeseries() void AreaList::removeThermalTimeseries() { each([](Data::Area& area) { - area.thermal.list.each( - [](Data::ThermalCluster& cluster) { cluster.series.reset(); }); + for (auto c : area.thermal.list.all()) + c->series.reset(); }); } diff --git a/src/libs/antares/study/area/store-timeseries-numbers.cpp b/src/libs/antares/study/area/store-timeseries-numbers.cpp index 0bd06d1ce7..e35ca9b184 100644 --- a/src/libs/antares/study/area/store-timeseries-numbers.cpp +++ b/src/libs/antares/study/area/store-timeseries-numbers.cpp @@ -84,7 +84,6 @@ void storeTimeseriesNumbersForWind(Solver::IResultWriter& writer, const Area& ar void storeTimeseriesNumbersForThermal(Solver::IResultWriter& writer, const Area& area) { area.thermal.list.storeTimeseriesNumbers(writer); - area.thermal.mustrunList.storeTimeseriesNumbers(writer); } void storeTimeseriesNumbersForRenewable(Solver::IResultWriter& writer, const Area& area) diff --git a/src/libs/antares/study/binding_constraint/BindingConstraint.cpp b/src/libs/antares/study/binding_constraint/BindingConstraint.cpp index a91b6bde65..8e2e15ff29 100644 --- a/src/libs/antares/study/binding_constraint/BindingConstraint.cpp +++ b/src/libs/antares/study/binding_constraint/BindingConstraint.cpp @@ -268,7 +268,7 @@ void BindingConstraint::copyWeights(const Study &study, if (localParent) { const ThermalCluster *localTC - = localParent->thermal.list.find(thermalCluster->id()); + = localParent->thermal.list.findInAll(thermalCluster->id()); if (localTC) pClusterWeights[localTC] = weight; } @@ -329,7 +329,7 @@ void BindingConstraint::copyOffsets(const Study &study, if (localParent) { const ThermalCluster *localTC - = localParent->thermal.list.find(thermalCluster->id()); + = localParent->thermal.list.findInAll(thermalCluster->id()); if (localTC) pClusterOffsets[localTC] = offset; } diff --git a/src/libs/antares/study/cleaner/cleaner-v20.cpp b/src/libs/antares/study/cleaner/cleaner-v20.cpp index 1f5e7b0b89..e089cce58f 100644 --- a/src/libs/antares/study/cleaner/cleaner-v20.cpp +++ b/src/libs/antares/study/cleaner/cleaner-v20.cpp @@ -127,7 +127,7 @@ static void listOfFilesAnDirectoriesToKeepForArea(PathList& e, PathList& p, cons buffer.clear() << "input/thermal/clusters/" << id << "/list.ini"; e.add(buffer); - for (const auto& cluster : area->thermal.list) + for (auto cluster : area->thermal.list.all()) { buffer.clear() << "input/thermal/prepro/" << id << '/' << cluster->id(); p.add(buffer); @@ -156,7 +156,7 @@ static void listOfFilesAnDirectoriesToKeepForArea(PathList& e, PathList& p, cons buffer.clear() << "input/renewables/clusters/" << id << "/list.ini"; e.add(buffer); - for (const auto& cluster : area->renewable.list) + for (const auto cluster : area->renewable.list.all()) { buffer.clear() << "input/renewables/series/" << id << '/' << cluster->id(); p.add(buffer); @@ -345,7 +345,7 @@ bool listOfFilesAnDirectoriesToKeep(StudyCleaningInfos* infos) // Exclude listOfFilesAnDirectoriesToKeepForArea(e, p, area, buffer); // Clear the memory used by the thermal clusters of the area - area->thermal.list.clear(); + area->thermal.list.clearAll(); // Interconnections { 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 b4a8d4c0c0..aa751fbb07 100644 --- a/src/libs/antares/study/include/antares/study/load-options.h +++ b/src/libs/antares/study/include/antares/study/load-options.h @@ -38,9 +38,6 @@ class StudyLoadOptions StudyLoadOptions(); //@} - //! Push a new log entry according to the local progress data - void pushProgressLogs() const; - void checkForceSimulationMode(); public: @@ -89,10 +86,6 @@ class StudyLoadOptions //! Temporary string for passing log message mutable Yuni::String logMessage; - //! Porgression, tick count - mutable uint progressTickCount; - //! The current number of ticks - mutable uint progressTicks; //! Display version number and exit bool displayVersion = false; diff --git a/src/libs/antares/study/include/antares/study/parts/common/cluster.h b/src/libs/antares/study/include/antares/study/parts/common/cluster.h index 4f86b85405..1752a44706 100644 --- a/src/libs/antares/study/include/antares/study/parts/common/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/common/cluster.h @@ -44,37 +44,21 @@ struct CompareClusterName final class Cluster { public: - //! Map of renewable clusters - using Map = std::map; + using Set = std::set; public: Cluster(Area* parent); virtual ~Cluster() = default; - //! Get the cluster ID const ClusterName& id() const; - - //! \name Group - //@{ - //! Get the group of the cluster const ClusterName& group() const; - - //! Get the renewable cluster name const ClusterName& name() const; - - //! Set the name/ID void setName(const AnyString& newname); - //@} - - //! Get the full cluster name Yuni::String getFullName() const; virtual uint groupId() const = 0; - - //! Set the group virtual void setGroup(Data::ClusterName newgrp) = 0; - //@} /*! ** \brief Check and fix all values of a renewable cluster @@ -84,13 +68,13 @@ class Cluster virtual bool integrityCheck() = 0; /*! - ** \brief Get the memory consummed by the renewable cluster (in bytes) + ** \brief Get the memory consummed by the cluster (in bytes) */ virtual uint64_t memoryUsage() const = 0; //@} /*! - ** \brief Invalidate all data associated to the renewable cluster + ** \brief Invalidate all data associated to the cluster */ virtual bool forceReload(bool reload) const = 0; @@ -100,7 +84,7 @@ class Cluster void invalidateArea(); /*! - ** \brief Mark the renewable cluster as modified + ** \brief Mark the cluster as modified */ virtual void markAsModified() const = 0; @@ -117,25 +101,24 @@ class Cluster */ virtual void reset(); - //! Count of unit - uint unitCount; + bool saveDataSeriesToFolder(const AnyString& folder) const; + bool loadDataSeriesFromFolder(Study& s, const AnyString& folder); + + uint unitCount = 0; - //! Enabled - bool enabled; + bool isEnabled() const { return enabled; } + bool enabled = true; //! The associate area (alias) Area* parentArea; - //! The index of the cluster (within a list) - uint index; - //! Capacity of reference per unit (MW) (pMax) - double nominalCapacity; + double nominalCapacity = 0.; //! The index of the cluster from the area's point of view //! \warning this variable is only valid when used by the solver // (initialized in the same time that the runtime data) - uint areaWideIndex; + uint areaWideIndex = (uint)-1; //! Series TimeSeries series; @@ -151,20 +134,10 @@ class Cluster Matrix<> modulation; protected: - //! Name Data::ClusterName pName; - //! ID Data::ClusterName pID; - //! Group Data::ClusterName pGroup; -public: - //! Set of clusters - using Set = std::set; - - bool saveDataSeriesToFolder(const AnyString& folder) const; - bool loadDataSeriesFromFolder(Study& s, const AnyString& folder); - private: virtual unsigned int precision() const = 0; }; diff --git a/src/libs/antares/study/include/antares/study/parts/common/cluster_list.h b/src/libs/antares/study/include/antares/study/parts/common/cluster_list.h index 99c215fc7e..40a083be83 100644 --- a/src/libs/antares/study/include/antares/study/parts/common/cluster_list.h +++ b/src/libs/antares/study/include/antares/study/parts/common/cluster_list.h @@ -29,8 +29,7 @@ #include #include #include - - +#include namespace Antares @@ -48,41 +47,17 @@ class ClusterList { public: using SharedPtr = typename std::shared_ptr; - using Vect = typename std::vector; - using iterator = typename Vect::iterator; - using const_iterator = typename Vect::const_iterator; - /*! - ** \brief Iterate through all clusters (const) - */ - template - void each(const PredicateT& predicate) const - { - std::ranges::for_each(clusters, [&predicate](SharedPtr c) { predicate(*c); }); - } - - //! \name clusters management - //@{ - /*! - ** \brief Destroy all clusters - */ - void clear(); - - /*! - ** \brief Add a cluster in the list - ** - ** \param t The cluster to add - ** \return True if the cluster has been added, false otherwise - */ - SharedPtr add(const SharedPtr clusters); + void clearAll(); + bool empty() const; /*! - ** \brief Try to find a cluster from its id (const) + ** \brief Try to find a cluster from its id (const) in the complete cluster list ** ** \param id ID of the cluster to find ** \return A pointer to a cluster. nullptr if not found */ - ClusterT* find(const Data::ClusterName& id) const; + ClusterT* findInAll(std::string_view id) const; /*! ** \brief Get if a cluster exists @@ -92,6 +67,10 @@ class ClusterList */ bool exists(const Data::ClusterName& id) const; + auto each_enabled() const { return allClusters_ | std::views::filter(&ClusterT::isEnabled); } + + std::vector> all() const; + /*! ** \brief Rename a cluster ** @@ -109,27 +88,18 @@ class ClusterList */ virtual bool remove(const Data::ClusterName& id); - //! Get the number of items in the list - uint size() const; - - //! Return true if the list is empty - bool empty() const; //@} - iterator begin(); - const_iterator begin() const; - - iterator end(); - const_iterator end() const; + SharedPtr operator[](std::size_t idx) { return allClusters_[idx]; } + SharedPtr operator[](std::size_t idx) const { return allClusters_[idx]; } - SharedPtr operator[](std::size_t idx) { return clusters[idx]; } - const SharedPtr operator[](std::size_t idx) const { return clusters[idx]; } + SharedPtr enabledClusterAt(unsigned int index) const; /*! ** \brief Resize all matrices dedicated to the sampled timeseries numbers ** ** \param n A number of years */ - void resizeAllTimeseriesNumbers(uint n); + void resizeAllTimeseriesNumbers(uint n) const; void storeTimeseriesNumbers(Solver::IResultWriter& writer) const; @@ -150,18 +120,15 @@ class ClusterList ** \brief Get the size (bytes) occupied in memory by a `ClusterList` structure ** \return A size (in bytes) */ - uint64_t memoryUsage() const; + virtual uint64_t memoryUsage() const = 0; /// \name IO functions /// @{ bool loadDataSeriesFromFolder(Study& study, - const StudyLoadOptions& options, const AnyString& folder); bool saveDataSeriesToFolder(const AnyString& folder) const; - bool saveDataSeriesToFolder(const AnyString& folder, const YString& msg) const; - virtual bool saveToFolder(const AnyString& folder) const = 0; ///@} @@ -177,28 +144,21 @@ class ClusterList */ void retrieveTotalCapacityAndUnitCount(double& total, uint& unitCount) const; - /*! - ** \brief Removes disabled clusters - ** - ** All clusters with the flag 'enabled' turned to false will be removed from 'list'. - ** As a consequence, they will no longer be seen as thermal clusters - ** from the solver's point of view. - ** \warning This method should only be used from the solver - ** - ** \return The number of disabled clusters found - */ - uint removeDisabledClusters(); + unsigned int enabledCount() const; + unsigned int allClustersCount() const; + void addToCompleteList(std::shared_ptr cluster); + void sortCompleteList(); protected: - /// The vector containing the clusters - Vect clusters; + std::vector> allClusters_; - /// thermal, renewable, etc. virtual std::string typeID() const = 0; + // Give a special index to enabled clusters (thermal / renewable) + void rebuildIndexes(); + private: - /// Sort the vector, set index value for each cluster - void rebuildIndex(); + bool alreadyInAllClusters(std::string clusterName); }; // class ClusterList } // namespace Data diff --git a/src/libs/antares/study/include/antares/study/parts/renewable/cluster.h b/src/libs/antares/study/include/antares/study/parts/renewable/cluster.h index ff69fcd79d..f06a9e3a5d 100644 --- a/src/libs/antares/study/include/antares/study/parts/renewable/cluster.h +++ b/src/libs/antares/study/include/antares/study/parts/renewable/cluster.h @@ -32,15 +32,6 @@ namespace Antares { namespace Data { -/* gp : useless in v8.1, could be useful in a further version -enum RenewableModulation -{ - renewableModulationCost = 0, - renewableModulationCapacity, - renewableMinGenModulation, - renewableModulationMax -}; -*/ /* ** \brief A single renewable cluster @@ -156,9 +147,9 @@ class RenewableCluster final : public Cluster ** This value is computed from the field 'group' in 'group() ** \see group() */ - enum RenewableGroup groupID; + enum RenewableGroup groupID = renewableOther1; - enum TimeSeriesMode tsMode; + enum TimeSeriesMode tsMode = powerGeneration; friend class RenewableClusterList; diff --git a/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h b/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h index bdbaab971c..de45a30811 100644 --- a/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h +++ b/src/libs/antares/study/include/antares/study/parts/renewable/cluster_list.h @@ -38,6 +38,7 @@ class RenewableClusterList : public ClusterList { public: std::string typeID() const override; + uint64_t memoryUsage() const override; bool loadFromFolder(const AnyString& folder, Area* area); bool saveToFolder(const AnyString& folder) const override; }; // class RenewableClusterList diff --git a/src/libs/antares/study/include/antares/study/parts/renewable/container.h b/src/libs/antares/study/include/antares/study/parts/renewable/container.h index 0aa873bd1e..4c6fe83e40 100644 --- a/src/libs/antares/study/include/antares/study/parts/renewable/container.h +++ b/src/libs/antares/study/include/antares/study/parts/renewable/container.h @@ -55,16 +55,6 @@ class PartRenewable */ void resizeAllTimeseriesNumbers(uint n); - - - /*! - ** \brief Create and initialize the list of all clusters (with the mustrun flag or not) - ** - ** This method must be called before prepareClustersInMustRunMode() - ** to ensure the same order whatever the value of the 'mustrun' flag is. - */ - void prepareAreaWideIndexes(); - /*! ** \brief Invalidate all JIT data */ 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 0511942fa1..3b32763d51 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 @@ -211,7 +211,7 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this /*! ** \brief Check the validity of Min Stable Power with a new modulation value */ - bool checkMinStablePowerWithNewModulation(uint index, double value); + bool checkMinStablePowerWithNewModulation(uint idx, double value); //@} bool doWeGenerateTS(bool globalTSgeneration) const; @@ -226,30 +226,35 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this bool isActive() const; + //! The index of the cluster (within a list) + uint index = 0; + /*! ** \brief The group ID ** ** This value is computed from the field 'group' in 'group() ** \see group() */ - ThermalDispatchableGroup groupID; + ThermalDispatchableGroup groupID = thermalDispatchGrpOther1; //! Mustrun - bool mustrun; + bool mustrun = false; + bool isMustRun() const { return mustrun; } + //! Mustrun (as it were at the loading of the data) // // This value might differ from mustrun, because `mustrun` might be // modified for different reasons. // Only used by the solver in adequacy mode - bool mustrunOrigin; + bool mustrunOrigin = false; //! Nominal capacity - spinning (solver only) - double nominalCapacityWithSpinning; + double nominalCapacityWithSpinning = 0.; //! \name PMin //@{ //! Min. Stable Power (MW) - double minStablePower; + double minStablePower = 0.; struct DivModulation { @@ -265,28 +270,28 @@ class ThermalCluster final : public Cluster, public std::enable_shared_from_this } minDivModulation; //! Min. Up time (1..168) - uint minUpTime; + uint minUpTime = 1; //! Min. Down time (1..168) - uint minDownTime; + uint minDownTime = 1; //! Max entre . minUp/minDown time (1..168) uint minUpDownTime; //@} //! Spinning (%) - double spinning; + double spinning = 0.; //! Efficiency (%) double fuelEfficiency = 100; //! Forced Volatility - double forcedVolatility; + double forcedVolatility = 0.; //! Planned volatility - double plannedVolatility; + double plannedVolatility = 0.; //! Law (ts-generator) - ThermalLaw forcedLaw; + ThermalLaw forcedLaw = thermalLawUniform; //! Law (ts-generator) - ThermalLaw plannedLaw; + ThermalLaw plannedLaw = thermalLawUniform; //! \name Costs // Marginal (€/MWh) MA diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h b/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h index e45bd033c7..5bd3cda4e5 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/cluster_list.h @@ -20,7 +20,9 @@ */ #pragma once +#include #include "../common/cluster_list.h" +#include "cluster.h" namespace Antares { @@ -34,8 +36,7 @@ class ThermalClusterList : public ClusterList { public: std::string typeID() const override; - // Map container - using Map = typename std::map>; + uint64_t memoryUsage() const override; /*! ** \brief Get the size (bytes) occupied in memory by a `ThermalClusterList` structure @@ -79,7 +80,18 @@ class ThermalClusterList : public ClusterList void enableMustrunForEveryone(); //@} - Map mapping; + auto each_mustrun_and_enabled() const + { + return allClusters_ | std::views::filter(&ThermalCluster::isMustRun) + | std::views::filter(&ThermalCluster::isEnabled); + } + + auto each_enabled_and_not_mustrun() const + { + return allClusters_ | std::views::filter(&ThermalCluster::isEnabled) + | std::views::filter(std::not_fn(&ThermalCluster::isMustRun)); + } + /*! ** \brief Ensure data for the prepro are initialized @@ -99,7 +111,7 @@ class ThermalClusterList : public ClusterList ** \param folder The target folder ** \return A non-zero value if the operation succeeded, 0 otherwise */ - bool loadPreproFromFolder(Study& s, const StudyLoadOptions& options, const AnyString& folder); + bool loadPreproFromFolder(Study& s, const AnyString& folder); bool loadEconomicCosts(Study& s, const AnyString& folder); @@ -107,6 +119,14 @@ class ThermalClusterList : public ClusterList bool saveEconomicCosts(const AnyString& folder) const; bool saveToFolder(const AnyString& folder) const override; + + unsigned int enabledAndMustRunCount() const; + unsigned int enabledAndNotMustRunCount() const; + +private: + // Give a special index to enbled and not must-run THERMAL clusters + void rebuildIndex() const; + }; // class ThermalClusterList } // namespace Data } // namespace Antares diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/container.h b/src/libs/antares/study/include/antares/study/parts/thermal/container.h index 6eb517c501..f9053706bf 100644 --- a/src/libs/antares/study/include/antares/study/parts/thermal/container.h +++ b/src/libs/antares/study/include/antares/study/parts/thermal/container.h @@ -38,7 +38,7 @@ class PartThermal */ PartThermal(); //! Destructor - ~PartThermal(); + ~PartThermal() = default; //@} /*! @@ -51,29 +51,7 @@ class PartThermal ** ** \param n A number of years */ - void resizeAllTimeseriesNumbers(uint n); - - - - /*! - ** \brief Create and initialize the list of all clusters (with the mustrun flag or not) - ** - ** This method must be called before prepareClustersInMustRunMode() - ** to ensure the same order whatever the value of the 'mustrun' flag is. - */ - void prepareAreaWideIndexes(); - - /*! - ** \brief Prepare all thermal clusters in the 'mustrun' mode - ** - ** All clusters with the flag will be moved to the container 'mustrunList'. - ** As a consequence, they will no longer be seen as thermal clusters - ** from the solver's point of view. - ** \warning This method should only be used from the solver - ** - ** \return The number of clusters found in 'must-run' mode - */ - uint prepareClustersInMustRunMode(); + void resizeAllTimeseriesNumbers(uint n) const; /*! ** \brief Invalidate all JIT data @@ -99,7 +77,7 @@ class PartThermal // Check & correct availability timeseries for thermal availability // Only applies if time-series are ready-made - void checkAndCorrectAvailability(); + void checkAndCorrectAvailability() const; public: //! The unsupplied energy cost (Euros/MWh) @@ -109,31 +87,10 @@ class PartThermal //! List of all thermal clusters (enabled and disabled) except must-run clusters ThermalClusterList list; - //! List of all thermal clusters in 'must-run' mode - //! \warning This list must only be used from the solver - ThermalClusterList mustrunList; - - /*! - ** \brief All clusters for the area - ** - ** This variable is only available at runtime from the solver. - ** It is initialized in the same time that the runtime data. - ** - ** This list is mainly used to ensure the same order of the - ** thermal clusters in the outputs. - */ - std::vector clusters; - // Return unit count - inline size_t clusterCount() const - { - return clusters.size(); - } }; // class PartThermal } // namespace Data } // namespace Antares -#include "container.hxx" - #endif /* __ANTARES_LIBS_STUDY_PARTS_THERMAL_CONTAINER_H__ */ diff --git a/src/libs/antares/study/include/antares/study/parts/thermal/container.hxx b/src/libs/antares/study/include/antares/study/parts/thermal/container.hxx deleted file mode 100644 index 9b668b67c8..0000000000 --- a/src/libs/antares/study/include/antares/study/parts/thermal/container.hxx +++ /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 . -*/ -#ifndef __ANTARES_LIBS_STUDY_PARTS_THERMAL_CONTAINER_HXX__ -#define __ANTARES_LIBS_STUDY_PARTS_THERMAL_CONTAINER_HXX__ - -namespace Antares -{ -namespace Data -{ -inline void PartThermal::resizeAllTimeseriesNumbers(uint n) -{ - list.resizeAllTimeseriesNumbers(n); - mustrunList.resizeAllTimeseriesNumbers(n); -} - -} // namespace Data -} // namespace Antares - -#endif // __ANTARES_LIBS_STUDY_PARTS_THERMAL_CONTAINER_HXX__ diff --git a/src/libs/antares/study/include/antares/study/runtime/runtime.h b/src/libs/antares/study/include/antares/study/runtime/runtime.h index 301e530e94..702078919c 100644 --- a/src/libs/antares/study/include/antares/study/runtime/runtime.h +++ b/src/libs/antares/study/include/antares/study/runtime/runtime.h @@ -130,8 +130,6 @@ class StudyRuntimeInfos void initializeRangeLimits(const Study& study, StudyRangeLimits& limits); //! Prepare all thermal clusters in 'must-run' mode void initializeThermalClustersInMustRunMode(Study& study) const; - void removeDisabledThermalClustersFromSolverComputations(Study& study); - void removeDisabledRenewableClustersFromSolverComputations(Study& study); void removeDisabledShortTermStorageClustersFromSolverComputations(Study& study); void removeAllRenewableClustersFromSolverComputations(Study& study); void disableAllFilters(Study& study); diff --git a/src/libs/antares/study/load-options.cpp b/src/libs/antares/study/load-options.cpp index dae20b8835..b2370980df 100644 --- a/src/libs/antares/study/load-options.cpp +++ b/src/libs/antares/study/load-options.cpp @@ -45,16 +45,6 @@ StudyLoadOptions::StudyLoadOptions() : { } -void StudyLoadOptions::pushProgressLogs() const -{ - if (loadOnlyNeeded && progressTicks) - { - uint percent = progressTicks * 100 / progressTickCount; - if (percent < 100) - logs.info() << logMessage << " " << percent << '%'; - } -} - void StudyLoadOptions::checkForceSimulationMode() { const uint number_of_enabled_force_options diff --git a/src/libs/antares/study/parts/common/cluster.cpp b/src/libs/antares/study/parts/common/cluster.cpp index 348dbdab75..ed73548706 100644 --- a/src/libs/antares/study/parts/common/cluster.cpp +++ b/src/libs/antares/study/parts/common/cluster.cpp @@ -29,13 +29,8 @@ namespace Antares::Data { Cluster::Cluster(Area* parent) : - unitCount(0), - enabled(true), - parentArea(parent), - index(0), - nominalCapacity(0.), - areaWideIndex((uint)-1), - series(tsNumbers) + parentArea(parent), + series(tsNumbers) { } diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp index 2fd865cef8..818fa9a85f 100644 --- a/src/libs/antares/study/parts/common/cluster_list.cpp +++ b/src/libs/antares/study/parts/common/cluster_list.cpp @@ -41,66 +41,52 @@ namespace Antares::Data { using namespace Antares; -template -inline uint ClusterList::size() const -{ - return (uint)clusters.size(); -} - template inline bool ClusterList::empty() const { - return clusters.empty(); + return allClusters_.empty(); } template -typename ClusterList::iterator ClusterList::begin() +std::shared_ptr ClusterList::enabledClusterAt(unsigned int index) const { - return std::begin(clusters); + // No operator [] was found for std::view (returned by each_enabled()). + // The current function is there to replace it. + return *(std::views::drop(each_enabled(), index).begin()); } template -typename ClusterList::const_iterator ClusterList::begin() const +ClusterT* ClusterList::findInAll(std::string_view id) const { - return std::begin(clusters); + for (auto cluster : all()) + if (cluster->id() == id) + return cluster.get(); + return nullptr; } template -typename ClusterList::iterator ClusterList::end() +std::vector> ClusterList::all() const { - return std::end(clusters); -} - -template -typename ClusterList::const_iterator ClusterList::end() const -{ - return std::end(clusters); -} - -template -ClusterT* ClusterList::find(const Data::ClusterName& id) const -{ - const auto& it = std::ranges::find_if(clusters, [&id](auto& c) { return c->id() == id; }); - - return (it != clusters.end()) ? it->get() : nullptr; + return allClusters_; } template bool ClusterList::exists(const Data::ClusterName& id) const { - return std::ranges::any_of(clusters, [&id](const auto& c){ return c->id() == id; }); + return std::ranges::any_of(allClusters_, [&id](const auto& c){ return c->id() == id; }); } template -void ClusterList::clear() +void ClusterList::clearAll() { - clusters.clear(); + allClusters_.clear(); } template -void ClusterList::resizeAllTimeseriesNumbers(uint n) +void ClusterList::resizeAllTimeseriesNumbers(uint n) const { - each([&](Cluster& cluster) { cluster.series.timeseriesNumbers.reset(1, n); }); + for (auto c : allClusters_) + c->series.timeseriesNumbers.reset(1, n); } #define SEP IO::Separator @@ -112,49 +98,71 @@ void ClusterList::storeTimeseriesNumbers(Solver::IResultWriter& writer Clob path; std::string ts_content; - each([&](const Cluster& cluster) { - path.clear() << "ts-numbers" << SEP << typeID() << SEP << cluster.parentArea->id << SEP - << cluster.id() << ".txt"; + for (auto cluster : each_enabled()) + { + path.clear() << "ts-numbers" << SEP << typeID() << SEP << cluster->parentArea->id << SEP + << cluster->id() << ".txt"; ts_content.clear(); // We must clear ts_content here, since saveToBuffer does not do it. - cluster.series.timeseriesNumbers.saveToBuffer(ts_content, 0, true, predicate, true); + cluster->series.timeseriesNumbers.saveToBuffer(ts_content, 0, true, predicate, true); writer.addEntryFromBuffer(path.c_str(), ts_content); - }); + } } template -void ClusterList::rebuildIndex() +bool ClusterList::alreadyInAllClusters(std::string clusterId) { - std::sort(clusters.begin(), clusters.end(), [](const auto& a, const auto& b){ - return a->id() < b->id(); - }); + return std::ranges::any_of(allClusters_, [&clusterId](const auto& c) { return c->id() == clusterId; }); +} - uint indx = 0; - for (auto& c : clusters) - c->index = indx++; +template +void ClusterList::addToCompleteList(std::shared_ptr cluster) +{ + if (alreadyInAllClusters(cluster->id())) + return; + allClusters_.push_back(cluster); + sortCompleteList(); + rebuildIndexes(); } template -typename ClusterList::SharedPtr ClusterList::add( - const ClusterList::SharedPtr newcluster) +void ClusterList::sortCompleteList() { - if (!newcluster) - return nullptr; + std::ranges::sort(allClusters_, [](const auto a, const auto b) { return a->id() < b->id(); }); +} - if (exists(newcluster->id())) - return newcluster; +template +unsigned int ClusterList::enabledCount() const +{ + return std::ranges::count_if(allClusters_, &ClusterT::isEnabled); +} - clusters.push_back(newcluster); - rebuildIndex(); - return newcluster; +template +unsigned int ClusterList::allClustersCount() const +{ + return allClusters_.size(); } template -uint64_t ClusterList::memoryUsage() const +void ClusterList::rebuildIndexes() { - uint64_t ret = sizeof(ClusterList) + (2 * sizeof(void*)) * this->size(); + // First, we give an index to every cluster, enabled / must-run or not. + // We do that to : + // - Stick to what was done before and not change the results + // - Avoids seg faults, for instance when storing thermal noises (solver.hxx). + // Indeed : otherwise disabled clusters have an infinite index + unsigned int index = 0; + for (auto c : allClusters_) + { + c->areaWideIndex = index; + index++; + } - each([&](const ClusterT& clusters) { ret += clusters.memoryUsage(); }); - return ret; + index = 0; + for (auto c : each_enabled()) + { + c->areaWideIndex = index; + index++; + } } template @@ -177,7 +185,7 @@ bool ClusterList::rename(Data::ClusterName idToFind, Data::ClusterName Antares::TransformNameIntoID(newName, newID); // Looking for the renewable clusters in the list - auto* cluster_ptr = this->find(idToFind); + auto* cluster_ptr = this->findInAll(idToFind); if (!cluster_ptr) return true; @@ -203,77 +211,49 @@ bool ClusterList::rename(Data::ClusterName idToFind, Data::ClusterName if (cluster_ptr->parentArea) (cluster_ptr->parentArea)->invalidateJIT = true; - // Rebuilding the index - rebuildIndex(); return true; } template bool ClusterList::forceReload(bool reload) const { - return std::ranges::all_of(clusters, [&reload](const auto& c){ + return std::ranges::all_of(allClusters_, [&reload](const auto& c){ return c->forceReload(reload); }); - } template void ClusterList::markAsModified() const { - for (const auto& c : clusters) + for (const auto& c : allClusters_) c->markAsModified(); } template bool ClusterList::remove(const Data::ClusterName& id) { - auto nbDeletion = std::erase_if(clusters, [&id](const SharedPtr& c) { return c->id() == id; }); + auto nbDeletion = std::erase_if(allClusters_, [&id](const SharedPtr& c) { return c->id() == id; }); // Invalidating the parent area forceReload(); - // Rebuilding the index - rebuildIndex(); - return nbDeletion > 0; } template bool ClusterList::saveDataSeriesToFolder(const AnyString& folder) const { - return std::ranges::all_of(clusters, [&folder](const auto& c){ - return c->saveDataSeriesToFolder(folder); - }); -} - -template -bool ClusterList::saveDataSeriesToFolder(const AnyString& folder, const String& msg) const -{ - uint ticks = 0; - - return std::ranges::all_of(clusters, [&](const auto& c) - { - logs.info() << msg << " " << (ticks * 100 / (1 + this->clusters.size())) - << "% complete"; - ++ticks; + return std::ranges::all_of(allClusters_, [&folder](const auto c){ return c->saveDataSeriesToFolder(folder); }); } template bool ClusterList::loadDataSeriesFromFolder(Study& s, - const StudyLoadOptions& options, const AnyString& folder) { - bool ret = true; - - each([&](ClusterT& c) { - ret = c.loadDataSeriesFromFolder(s, folder) and ret; - - ++options.progressTicks; - options.pushProgressLogs(); - }); - return ret; + return std::ranges::all_of(allClusters_, + [&](auto c) { return c->loadDataSeriesFromFolder(s, folder); }); } template @@ -282,26 +262,13 @@ void ClusterList::retrieveTotalCapacityAndUnitCount(double& total, uin total = 0.; unitCount = 0; - for (const auto& c : clusters) + for (const auto& c : all()) { unitCount += c->unitCount; total += c->unitCount * c->nominalCapacity; } } -template -uint ClusterList::removeDisabledClusters() -{ - // nothing to do if there is no clusters available - if (empty()) - return 0; - - auto count = std::erase_if(clusters, [] (auto& c) { return !c->enabled; }); - - rebuildIndex(); - - return count; -} // Force template instantiation template class ClusterList; template class ClusterList; diff --git a/src/libs/antares/study/parts/renewable/cluster.cpp b/src/libs/antares/study/parts/renewable/cluster.cpp index e6a5a9f279..0a92231095 100644 --- a/src/libs/antares/study/parts/renewable/cluster.cpp +++ b/src/libs/antares/study/parts/renewable/cluster.cpp @@ -38,8 +38,8 @@ using namespace Antares; namespace Antares::Data { -Data::RenewableCluster::RenewableCluster(Area* parent) : - Cluster(parent), groupID(renewableOther1), tsMode(powerGeneration) +Data::RenewableCluster::RenewableCluster(Area* parent) : + Cluster(parent) { // assert assert(parent and "A parent for a renewable dispatchable cluster can not be null"); diff --git a/src/libs/antares/study/parts/renewable/cluster_list.cpp b/src/libs/antares/study/parts/renewable/cluster_list.cpp index b532a88526..ac04612ad5 100644 --- a/src/libs/antares/study/parts/renewable/cluster_list.cpp +++ b/src/libs/antares/study/parts/renewable/cluster_list.cpp @@ -38,6 +38,14 @@ std::string RenewableClusterList::typeID() const return "renewables"; } +uint64_t RenewableClusterList::memoryUsage() const +{ + uint64_t ret = sizeof(RenewableClusterList) + (2 * sizeof(void*)) * enabledCount(); + std::ranges::for_each(each_enabled(), [&ret](const auto c) { ret += c->memoryUsage(); }); + return ret; +} + + bool RenewableClusterList::saveToFolder(const AnyString& folder) const { // Make sure the folder is created @@ -50,27 +58,28 @@ bool RenewableClusterList::saveToFolder(const AnyString& folder) const IniFile ini; // Browse all clusters - each([&](const Data::RenewableCluster& c) { + for (auto c : all()) + { // Adding a section to the inifile - IniFile::Section* s = ini.addSection(c.name()); + IniFile::Section* s = ini.addSection(c->name()); // The section must not be empty // This key will be silently ignored the next time - s->add("name", c.name()); + s->add("name", c->name()); - if (not c.group().empty()) - s->add("group", c.group()); - if (not c.enabled) + if (!c->group().empty()) + s->add("group", c->group()); + if (!c->enabled) s->add("enabled", "false"); - if (not Math::Zero(c.nominalCapacity)) - s->add("nominalCapacity", c.nominalCapacity); + if (!Math::Zero(c->nominalCapacity)) + s->add("nominalCapacity", c->nominalCapacity); - if (not Math::Zero(c.unitCount)) - s->add("unitCount", c.unitCount); + if (!Math::Zero(c->unitCount)) + s->add("unitCount", c->unitCount); - s->add("ts-interpretation", c.getTimeSeriesModeAsString()); - }); + s->add("ts-interpretation", c->getTimeSeriesModeAsString()); + } // Write the ini file buffer.clear() << folder << SEP << "list.ini"; @@ -135,7 +144,7 @@ static bool ClusterLoadFromSection(const AnyString& filename, << "`: Invalid key/value"; continue; } - if (not ClusterLoadFromProperty(cluster, property)) + if (!ClusterLoadFromProperty(cluster, property)) { logs.warning() << '`' << filename << "`: `" << section.name << "`/`" << property->key << "`: The property is unknown and ignored"; @@ -172,25 +181,18 @@ bool RenewableClusterList::loadFromFolder(const AnyString& folder, Area* area) auto cluster = std::make_shared(area); // Load data of a renewable cluster from a ini file section - if (not ClusterLoadFromSection(buffer, *cluster, *section)) + if (!ClusterLoadFromSection(buffer, *cluster, *section)) { continue; } - // Check the data integrity of the cluster cluster->integrityCheck(); - - // adding the renewable cluster - if (not add(cluster)) - { - // This error should never happen - logs.error() << "Impossible to add the renewable cluster '" << cluster->name() - << "'"; - continue; - } + addToCompleteList(cluster); } } + rebuildIndexes(); + return ret; } return false; diff --git a/src/libs/antares/study/parts/renewable/container.cpp b/src/libs/antares/study/parts/renewable/container.cpp index 513db78df2..c63869e3f1 100644 --- a/src/libs/antares/study/parts/renewable/container.cpp +++ b/src/libs/antares/study/parts/renewable/container.cpp @@ -50,26 +50,9 @@ PartRenewable::~PartRenewable() { } -void PartRenewable::prepareAreaWideIndexes() -{ - // Copy the list with all renewable clusters - // And init the areaWideIndex (unique index for a given area) - if (list.empty()) - { - return; - } - - uint idx = 0; - for (const auto& cluster : list) - { - cluster->areaWideIndex = idx; - ++idx; - } -} - void PartRenewable::reset() { - list.clear(); + list.clearAll(); } } // namespace Antares::Data diff --git a/src/libs/antares/study/parts/thermal/cluster.cpp b/src/libs/antares/study/parts/thermal/cluster.cpp index 31ae126072..5608e0a5f9 100644 --- a/src/libs/antares/study/parts/thermal/cluster.cpp +++ b/src/libs/antares/study/parts/thermal/cluster.cpp @@ -114,18 +114,6 @@ namespace Data { Data::ThermalCluster::ThermalCluster(Area* parent) : Cluster(parent), - groupID(thermalDispatchGrpOther1), - mustrun(false), - mustrunOrigin(false), - nominalCapacityWithSpinning(0.), - minStablePower(0.), - minUpTime(1), - minDownTime(1), - spinning(0.), - forcedVolatility(0.), - plannedVolatility(0.), - forcedLaw(thermalLawUniform), - plannedLaw(thermalLawUniform), PthetaInf(HOURS_PER_YEAR, 0), costsTimeSeries(1, CostsTimeSeries()) { @@ -204,7 +192,7 @@ void Data::ThermalCluster::copyFrom(const ThermalCluster& cluster) // Making sure that the data related to the prepro and timeseries are present // prepro - if (not prepro) + if (!prepro) prepro = new PreproThermal(this->weak_from_this()); prepro->copyFrom(*cluster.prepro); @@ -285,7 +273,7 @@ void Data::ThermalCluster::calculationOfSpinning() // Nothing to do if the spinning is equal to zero // because it will the same multiply all entries of the matrix by 1. - if (not Math::Zero(spinning)) + if (!Math::Zero(spinning)) { logs.debug() << " Calculation of spinning... " << parentArea->name << "::" << pName; @@ -405,7 +393,7 @@ void Data::ThermalCluster::reverseCalculationOfSpinning() { // Nothing to do if the spinning is equal to zero // because it will the same multiply all entries of the matrix by 1. - if (not Math::Zero(spinning)) + if (!Math::Zero(spinning)) { logs.debug() << " Calculation of spinning (reverse)... " << parentArea->name << "::" << pName; @@ -470,7 +458,7 @@ void Data::ThermalCluster::reset() // warning: the variables `prepro` and `series` __must__ not be destroyed // since the interface may still have a pointer to them. // we must simply reset their content. - if (not prepro) + if (!prepro) prepro = new PreproThermal(this->weak_from_this()); prepro->reset(); ecoInput.reset(); @@ -478,7 +466,7 @@ void Data::ThermalCluster::reset() bool Data::ThermalCluster::integrityCheck() { - if (not parentArea) + if (!parentArea) { logs.error() << "Thermal cluster " << pName << ": The parent area is missing"; return false; @@ -655,7 +643,7 @@ void ThermalCluster::calculatMinDivModulation() bool ThermalCluster::checkMinStablePower() { - if (not minDivModulation.isCalculated) // not has been initialized + if (!minDivModulation.isCalculated) // not has been initialized calculatMinDivModulation(); if (minDivModulation.value < 0) @@ -683,9 +671,9 @@ bool ThermalCluster::checkMinStablePower() return true; } -bool ThermalCluster::checkMinStablePowerWithNewModulation(uint index, double value) +bool ThermalCluster::checkMinStablePowerWithNewModulation(uint idx, double value) { - if (not minDivModulation.isCalculated || index == minDivModulation.index) + if (!minDivModulation.isCalculated || idx == minDivModulation.index) calculatMinDivModulation(); else { @@ -693,7 +681,7 @@ bool ThermalCluster::checkMinStablePowerWithNewModulation(uint index, double val if (div < minDivModulation.value) { minDivModulation.value = div; - minDivModulation.index = index; + minDivModulation.index = idx; } } diff --git a/src/libs/antares/study/parts/thermal/cluster_list.cpp b/src/libs/antares/study/parts/thermal/cluster_list.cpp index 91315d0375..b782ee2e9a 100644 --- a/src/libs/antares/study/parts/thermal/cluster_list.cpp +++ b/src/libs/antares/study/parts/thermal/cluster_list.cpp @@ -48,8 +48,7 @@ ThermalClusterList::ThermalClusterList() ThermalClusterList::~ThermalClusterList() { - // deleting all thermal clusters - clear(); + clearAll(); } #define SEP IO::Separator @@ -59,13 +58,37 @@ std::string ThermalClusterList::typeID() const return "thermal"; } +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(); }); + return ret; +} + static bool ThermalClusterLoadFromSection(const AnyString& filename, ThermalCluster& cluster, const IniFile::Section& section); +void ThermalClusterList::rebuildIndex() const +{ + uint indx = 0; + 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(); }); +} + +unsigned int ThermalClusterList::enabledAndMustRunCount() const +{ + return std::ranges::count_if(allClusters_, [](auto c) { return c->isEnabled() && c->isMustRun(); }); +} + bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, Area* area) { - assert(area and "A parent area is required"); + assert(area && "A parent area is required"); // logs logs.info() << "Loading thermal configuration for the area " << area->name; @@ -91,7 +114,7 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A auto cluster = std::make_shared(area); // Load data of a thermal cluster from a ini file section - if (not ThermalClusterLoadFromSection(study.buffer, *cluster, *section)) + if (!ThermalClusterLoadFromSection(study.buffer, *cluster, *section)) { continue; } @@ -124,20 +147,20 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A }; bool r = cluster->modulation.loadFromCSVFile( modulationFile, thermalModulationMax, HOURS_PER_YEAR, options); - if (not r and study.usedByTheSolver) + if (!r && study.usedByTheSolver) { cluster->modulation.reset(thermalModulationMax, HOURS_PER_YEAR); cluster->modulation.fill(1.); cluster->modulation.fillColumn(thermalMinGenModulation, 0.); } - ret = ret and r; + ret = ret && r; // Special operations when not ran from the interface (aka solver) if (study.usedByTheSolver) { - if (not study.parameters.include.thermal.minStablePower) + if (!study.parameters.include.thermal.minStablePower) cluster->minStablePower = 0.; - if (not study.parameters.include.thermal.minUPTime) + if (!study.parameters.include.thermal.minUPTime) { cluster->minUpDownTime = 1; cluster->minUpTime = 1; @@ -147,7 +170,7 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A cluster->minUpDownTime = Math::Max(cluster->minUpTime, cluster->minDownTime); - if (not study.parameters.include.reserve.spinning) + if (!study.parameters.include.reserve.spinning) cluster->spinning = 0; cluster->nominalCapacityWithSpinning = cluster->nominalCapacity; @@ -155,20 +178,12 @@ bool ThermalClusterList::loadFromFolder(Study& study, const AnyString& folder, A // Check the data integrity of the cluster cluster->integrityCheck(); - - // adding the thermal cluster - auto added = add(cluster); - if (not added) - { - // This error should never happen - logs.error() << "Impossible to add the thermal cluster '" << cluster->name() - << "'"; - continue; - } - // keeping track of the cluster - mapping[cluster->id()] = added; + addToCompleteList(cluster); } + rebuildIndexes(); + rebuildIndex(); + return ret; } @@ -295,23 +310,25 @@ bool ThermalClusterLoadFromSection(const AnyString& filename, void ThermalClusterList::calculationOfSpinning() { - each([&](ThermalCluster& cluster) { cluster.calculationOfSpinning(); }); + for (auto cluster : each_enabled()) + cluster->calculationOfSpinning(); } void ThermalClusterList::reverseCalculationOfSpinning() { - each([&](ThermalCluster& cluster) { cluster.reverseCalculationOfSpinning(); }); + for (auto cluster : each_enabled()) + cluster->reverseCalculationOfSpinning(); } void ThermalClusterList::enableMustrunForEveryone() { - // enabling the mustrun mode - each([&](ThermalCluster& cluster) { cluster.mustrun = true; }); + for (auto c : allClusters_) + c->mustrun = true; } void ThermalClusterList::ensureDataPrepro() { - for (const auto& c : clusters) + for (const auto& c : all()) if (!c->prepro) c->prepro = new PreproThermal(c); } @@ -319,116 +336,114 @@ void ThermalClusterList::ensureDataPrepro() bool ThermalClusterList::saveToFolder(const AnyString& folder) const { // Make sure the folder is created - if (IO::Directory::Create(folder)) + if (!IO::Directory::Create(folder)) { - Clob buffer; - bool ret = true; - - // Allocate the inifile structure - IniFile ini; - - // Browse all clusters - each([&](const Data::ThermalCluster& c) { - // Adding a section to the inifile - IniFile::Section* s = ini.addSection(c.name()); - - // The section must not be empty - // This key will be silently ignored the next time - s->add("name", c.name()); - - if (not c.group().empty()) - s->add("group", c.group()); - if (not c.enabled) - s->add("enabled", "false"); - if (not Math::Zero(c.unitCount)) - s->add("unitCount", c.unitCount); - if (not Math::Zero(c.nominalCapacity)) - s->add("nominalCapacity", c.nominalCapacity); - // TS generation - if (c.tsGenBehavior != LocalTSGenerationBehavior::useGlobalParameter) - { - s->add("gen-ts", c.tsGenBehavior); - } - // Min. Stable Power - if (not Math::Zero(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 (not Math::Zero(c.spinning)) - s->add("spinning", c.spinning); - - // efficiency - if (c.fuelEfficiency != 100.0) - s->add("efficiency", c.fuelEfficiency); - - // volatility - if (not Math::Zero(c.forcedVolatility)) - s->add("volatility.forced", Math::Round(c.forcedVolatility, 3)); - if (not Math::Zero(c.plannedVolatility)) - s->add("volatility.planned", Math::Round(c.plannedVolatility, 3)); - - // laws - if (c.forcedLaw != thermalLawUniform) - s->add("law.forced", c.forcedLaw); - if (c.plannedLaw != thermalLawUniform) - s->add("law.planned", c.plannedLaw); - - // costs - if (c.costgeneration != setManually) - s->add("costgeneration", c.costgeneration); - if (not Math::Zero(c.marginalCost)) - s->add("marginal-cost", Math::Round(c.marginalCost, 3)); - if (not Math::Zero(c.spreadCost)) - s->add("spread-cost", c.spreadCost); - if (not Math::Zero(c.fixedCost)) - s->add("fixed-cost", Math::Round(c.fixedCost, 3)); - if (not Math::Zero(c.startupCost)) - s->add("startup-cost", Math::Round(c.startupCost, 3)); - if (not Math::Zero(c.marketBidCost)) - s->add("market-bid-cost", Math::Round(c.marketBidCost, 3)); - if (!Math::Zero(c.variableomcost)) - s->add("variableomcost", Math::Round(c.variableomcost,3)); - - - //pollutant factor - for (auto const& [key, val] : Pollutant::namesToEnum) - s->add(key, c.emissions.factors[val]); + logs.error() << "I/O Error: impossible to create '" << folder << "'"; + return false; + } + bool ret = true; + Clob buffer; + // Allocate the inifile structure + IniFile ini; + for (auto c : allClusters_) + { + // Adding a section to the inifile + IniFile::Section* s = ini.addSection(c->name()); + + // The section must not be empty + // This key will be silently ignored the next time + s->add("name", c->name()); + + if (!c->group().empty()) + s->add("group", c->group()); + if (!c->enabled) + s->add("enabled", "false"); + if (!Math::Zero(c->unitCount)) + s->add("unitCount", c->unitCount); + if (!Math::Zero(c->nominalCapacity)) + s->add("nominalCapacity", c->nominalCapacity); + // TS generation + if (c->tsGenBehavior != LocalTSGenerationBehavior::useGlobalParameter) + { + s->add("gen-ts", c->tsGenBehavior); + } + // Min. Stable Power + if (!Math::Zero(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 (!Math::Zero(c->spinning)) + s->add("spinning", c->spinning); + + // efficiency + if (c->fuelEfficiency != 100.0) + s->add("efficiency", c->fuelEfficiency); + + // volatility + if (!Math::Zero(c->forcedVolatility)) + s->add("volatility.forced", Math::Round(c->forcedVolatility, 3)); + if (!Math::Zero(c->plannedVolatility)) + s->add("volatility.planned", Math::Round(c->plannedVolatility, 3)); + + // laws + if (c->forcedLaw != thermalLawUniform) + s->add("law.forced", c->forcedLaw); + if (c->plannedLaw != thermalLawUniform) + s->add("law.planned", c->plannedLaw); + + // costs + if (c->costgeneration != setManually) + s->add("costgeneration", c->costgeneration); + if (!Math::Zero(c->marginalCost)) + s->add("marginal-cost", Math::Round(c->marginalCost, 3)); + if (!Math::Zero(c->spreadCost)) + s->add("spread-cost", c->spreadCost); + if (!Math::Zero(c->fixedCost)) + s->add("fixed-cost", Math::Round(c->fixedCost, 3)); + if (!Math::Zero(c->startupCost)) + s->add("startup-cost", Math::Round(c->startupCost, 3)); + if (!Math::Zero(c->marketBidCost)) + s->add("market-bid-cost", Math::Round(c->marketBidCost, 3)); + if (!Math::Zero(c->variableomcost)) + s->add("variableomcost", Math::Round(c->variableomcost,3)); + + + //pollutant factor + for (auto const& [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(); + if (IO::Directory::Create(buffer)) + { buffer.clear() << folder << SEP << ".." << SEP << ".." << SEP << "prepro" << SEP - << 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; - ret = c.modulation.saveToCSVFile(buffer) and ret; - } - else - ret = 0; - }); // Write the ini file buffer.clear() << folder << SEP << "list.ini"; - ret = ini.save(buffer) and ret; - } - else - { - logs.error() << "I/O Error: impossible to create '" << folder << "'"; - return false; + ret = ini.save(buffer) && ret; } - return true; + return ret; } bool ThermalClusterList::savePreproToFolder(const AnyString& folder) const @@ -436,14 +451,15 @@ bool ThermalClusterList::savePreproToFolder(const AnyString& folder) const Clob buffer; bool ret = true; - each([&](const ThermalCluster& c) { - if (c.prepro) + for (auto c : allClusters_) + { + if (c->prepro) { - assert(c.parentArea and "cluster: invalid parent area"); - buffer.clear() << folder << SEP << c.parentArea->id << SEP << c.id(); - ret = c.prepro->saveToFolder(buffer) and ret; + assert(c->parentArea && "cluster: invalid parent area"); + buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); + ret = c->prepro->saveToFolder(buffer) && ret; } - }); + } return ret; } @@ -452,30 +468,25 @@ bool ThermalClusterList::saveEconomicCosts(const AnyString& folder) const Clob buffer; bool ret = true; - each([&](const ThermalCluster& c) { - assert(c.parentArea and "cluster: invalid parent area"); - buffer.clear() << folder << SEP << c.parentArea->id << SEP << c.id(); - ret = c.ecoInput.saveToFolder(buffer) && ret; - }); + for (auto c : allClusters_) + { + assert(c->parentArea && "cluster: invalid parent area"); + buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); + ret = c->ecoInput.saveToFolder(buffer) && ret; + } return ret; } bool ThermalClusterList::loadPreproFromFolder(Study& study, - const StudyLoadOptions& options, const AnyString& folder) { const bool globalThermalTSgeneration = study.parameters.timeSeriesToGenerate & timeSeriesThermal; Clob buffer; - auto hasPrepro = [&](auto c) - { - ++options.progressTicks; - options.pushProgressLogs(); - return (bool) c->prepro; - }; + auto hasPrepro = [](auto c) { return (bool) c->prepro; }; - auto loadAndCheckPrepro = [&](auto c) + auto loadAndCheckPrepro = [&buffer, &folder, &study, &globalThermalTSgeneration](auto c) { assert(c->parentArea && "cluster: invalid parent area"); buffer.clear() << folder << SEP << c->parentArea->id << SEP << c->id(); @@ -489,13 +500,13 @@ bool ThermalClusterList::loadPreproFromFolder(Study& study, return result; }; - return std::ranges::all_of(clusters | std::views::filter(hasPrepro), + return std::ranges::all_of(allClusters_ | std::views::filter(hasPrepro), loadAndCheckPrepro); } bool ThermalClusterList::loadEconomicCosts(Study& study, const AnyString& folder) { - return std::ranges::all_of(clusters, [&study, folder](const auto& c) + return std::ranges::all_of(allClusters_, [&study, folder](const auto& c) { assert(c->parentArea && "cluster: invalid parent area"); Clob buffer; diff --git a/src/libs/antares/study/parts/thermal/container.cpp b/src/libs/antares/study/parts/thermal/container.cpp index 2b61a473c8..ff0f2803f0 100644 --- a/src/libs/antares/study/parts/thermal/container.cpp +++ b/src/libs/antares/study/parts/thermal/container.cpp @@ -43,98 +43,32 @@ bool PartThermal::forceReload(bool reload) const { bool ret = true; ret = list.forceReload(reload) && ret; - ret = mustrunList.forceReload(reload) && ret; return ret; } void PartThermal::markAsModified() const { list.markAsModified(); - mustrunList.markAsModified(); } -PartThermal::~PartThermal() -{ -} - -void PartThermal::prepareAreaWideIndexes() +void PartThermal::reset() { - // Copy the list with all thermal clusters - // And init the areaWideIndex (unique index for a given area) - if (list.empty()) - { - clusters.clear(); - return; - } - - clusters.assign(list.size(), nullptr); + unsuppliedEnergyCost = 0.; + spilledEnergyCost = 0.; - uint idx = 0; - for (const auto& cluster : list) - { - cluster->areaWideIndex = idx; - clusters[idx] = cluster.get(); - ++idx; - } + list.clearAll(); } -uint PartThermal::prepareClustersInMustRunMode() +void PartThermal::resizeAllTimeseriesNumbers(uint n) const { - // nothing to do if there is no cluster available - if (list.empty()) - return 0; - - // the number of clusters in 'must-run' mode - uint count = 0; - bool mustContinue; - do - { - mustContinue = false; - for (auto cluster : list) - { - if (!cluster->mustrun) - continue; - - // Detaching the thermal cluster from the main list... - list.remove(cluster->id()); - if (!cluster->enabled) - continue; - // ...and attaching it into the second list - if (!mustrunList.add(cluster)) - { - logs.error() << "Impossible to prepare the thermal cluster in 'must-run' mode: " - << cluster->parentArea->name << "::" << cluster->name(); - } - else - { - ++count; - logs.info() << "enabling 'must-run' mode for the cluster " - << cluster->parentArea->name << "::" << cluster->name(); - } - - // the iterator has been invalidated, loop again - mustContinue = true; - break; - } - } while (mustContinue); - - return count; + list.resizeAllTimeseriesNumbers(n); } -void PartThermal::reset() -{ - unsuppliedEnergyCost = 0.; - spilledEnergyCost = 0.; - - mustrunList.clear(); - list.clear(); - clusters.clear(); -} bool PartThermal::hasForcedTimeseriesGeneration() const { using Behavior = LocalTSGenerationBehavior; - return std::any_of(list.begin(), list.end(), [](const ThermalClusterList::SharedPtr& cluster) { + return std::ranges::any_of(list.all(), [](const ThermalClusterList::SharedPtr& cluster) { return cluster->tsGenBehavior == Behavior::forceGen; }); } @@ -142,15 +76,14 @@ bool PartThermal::hasForcedTimeseriesGeneration() const bool PartThermal::hasForcedNoTimeseriesGeneration() const { using Behavior = LocalTSGenerationBehavior; - return std::any_of(list.begin(), list.end(), [](const ThermalClusterList::SharedPtr& cluster) { + return std::ranges::any_of(list.all(), [](const ThermalClusterList::SharedPtr& cluster) { return cluster->tsGenBehavior == Behavior::forceNoGen; }); } -void PartThermal::checkAndCorrectAvailability() +void PartThermal::checkAndCorrectAvailability() const { - std::for_each( - clusters.begin(), clusters.end(), std::mem_fn(&ThermalCluster::checkAndCorrectAvailability)); + std::ranges::for_each(list.each_enabled(), &ThermalCluster::checkAndCorrectAvailability); } } // namespace Data diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index cbdafd2f04..b4f5d5c710 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -78,10 +78,7 @@ static void StudyRuntimeInfosInitializeAllAreas(Study& study, StudyRuntimeInfos& // Spinning - Economic Only - If no prepro if (!(timeSeriesThermal & study.parameters.timeSeriesToRefresh)) { - // Calculation of the spinning area.thermal.list.calculationOfSpinning(); - // We should not forget the list of clusters in 'must-run' mode - area.thermal.mustrunList.calculationOfSpinning(); } area.scratchpad.reserve(nbYearsInParallel); @@ -89,8 +86,8 @@ static void StudyRuntimeInfosInitializeAllAreas(Study& study, StudyRuntimeInfos& area.scratchpad.emplace_back(r, area); // statistics - r.thermalPlantTotalCount += area.thermal.list.size(); - r.thermalPlantTotalCountMustRun += area.thermal.mustrunList.size(); + r.thermalPlantTotalCount += area.thermal.list.enabledAndNotMustRunCount(); + r.thermalPlantTotalCountMustRun += area.thermal.list.enabledAndMustRunCount(); r.shortTermStorageCount += area.shortTermStorage.count(); } @@ -254,11 +251,10 @@ void StudyRuntimeInfos::checkThermalTSGeneration(Study& study) thermalTSRefresh = globalThermalTSgeneration; study.areas.each([this, globalThermalTSgeneration](Data::Area& area) { - area.thermal.list.each( - [this, globalThermalTSgeneration](const Data::ThermalCluster& cluster) { - thermalTSRefresh - = thermalTSRefresh || cluster.doWeGenerateTS(globalThermalTSgeneration); - }); + for (auto c : area.thermal.list.each_enabled_and_not_mustrun()) + { + thermalTSRefresh = thermalTSRefresh || c->doWeGenerateTS(globalThermalTSgeneration); + } }); } @@ -284,17 +280,12 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) study.calendarOutput.reset({gd.dayOfThe1stJanuary, gd.firstWeekday, gd.firstMonthInYear, gd.leapYear}); initializeRangeLimits(study, rangeLimits); - // Removing disabled thermal clusters from solver computations - removeDisabledThermalClustersFromSolverComputations(study); - // Removing disabled short-term storage objects from solver computations removeDisabledShortTermStorageClustersFromSolverComputations(study); switch (gd.renewableGeneration()) { case rgClusters: - // Removing disabled renewable clusters from solver computations - removeDisabledRenewableClustersFromSolverComputations(study); break; case rgAggregated: // Removing all renewable clusters from solver computations @@ -306,9 +297,6 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) break; } - // Must-run mode - initializeThermalClustersInMustRunMode(study); - // Areas StudyRuntimeInfosInitializeAllAreas(study, *this); @@ -341,37 +329,6 @@ uint StudyRuntimeInfos::interconnectionsCount() const return static_cast(areaLink.size()); } -void StudyRuntimeInfos::initializeThermalClustersInMustRunMode(Study& study) const -{ - logs.info(); - logs.info() << "Optimizing the thermal clusters in 'must-run' mode..."; - - // The number of thermal clusters in 'must-run' mode - uint count = 0; - - // each area... - for (uint a = 0; a != study.areas.size(); ++a) - { - Area& area = *(study.areas.byIndex[a]); - area.thermal.prepareAreaWideIndexes(); - count += area.thermal.prepareClustersInMustRunMode(); - } - - switch (count) - { - case 0: - logs.info() << "No thermal cluster in 'must-run' mode"; - break; - case 1: - logs.info() << "Found 1 thermal cluster in 'must-run' mode"; - break; - default: - logs.info() << "Found " << count << " thermal clusters in 'must-run' mode"; - } - // space - logs.info(); -} - static void removeClusters(Study& study, const char* type, std::function eachArea, @@ -404,22 +361,6 @@ static void removeClusters(Study& study, } } -void StudyRuntimeInfos::removeDisabledThermalClustersFromSolverComputations(Study& study) -{ - removeClusters( - study, "thermal", [](Area& area) { return area.thermal.list.removeDisabledClusters(); }); -} - -void StudyRuntimeInfos::removeDisabledRenewableClustersFromSolverComputations(Study& study) -{ - removeClusters(study, "renewable", [](Area& area) { - uint ret = area.renewable.list.removeDisabledClusters(); - if (ret > 0) - area.renewable.prepareAreaWideIndexes(); - return ret; - }); -} - void StudyRuntimeInfos::removeDisabledShortTermStorageClustersFromSolverComputations(Study& study) { removeClusters( diff --git a/src/libs/antares/study/scenario-builder/RenewableTSNumberData.cpp b/src/libs/antares/study/scenario-builder/RenewableTSNumberData.cpp index 120bb011bd..097134d2b6 100644 --- a/src/libs/antares/study/scenario-builder/RenewableTSNumberData.cpp +++ b/src/libs/antares/study/scenario-builder/RenewableTSNumberData.cpp @@ -52,17 +52,15 @@ bool renewableTSNumberData::apply(Study& study) const uint tsGenCountRenewable = get_tsGenCount(study); - uint clusterIndex = 0; - for (const auto& cluster : area.renewable.list) + for (const auto& cluster : area.renewable.list.each_enabled()) { // alias to the current column - assert(clusterIndex < pTSNumberRules.width); - const auto& col = pTSNumberRules[clusterIndex]; + assert(cluster->areaWideIndex < pTSNumberRules.width); + const auto& col = pTSNumberRules[cluster->areaWideIndex]; logprefix.clear() << "Renewable: area '" << area.name << "', cluster: '" << cluster->name() << "': "; ret = ApplyToMatrix(errors, logprefix, cluster->series, col, tsGenCountRenewable) && ret; - clusterIndex++; } return ret; } @@ -86,25 +84,16 @@ void renewableTSNumberData::saveToINIFile(const Study& /* study */, if (!pArea) return; -// Foreach year -#ifndef NDEBUG - if (pTSNumberRules.width) + for (auto cluster : pArea->renewable.list.all()) { - assert(pTSNumberRules.width == pArea->renewable.list.size()); - } -#endif - - for (uint index = 0; index != pTSNumberRules.width; ++index) - { - // Foreach renewable cluster... - for (uint y = 0; y != pTSNumberRules.height; ++y) + for (uint year = 0; year != pTSNumberRules.height; ++year) { - const uint val = get(pArea->renewable.list[index].get(), y); + const uint val = get(cluster.get(), year); // Equals to zero means 'auto', which is the default mode if (!val) continue; - file << prefix << pArea->id << "," << y << ',' - << pArea->renewable.list[index]->id() << " = " << val << '\n'; + file << prefix << pArea->id << "," << year << ',' + << cluster->id() << " = " << val << '\n'; } } } @@ -119,7 +108,7 @@ bool renewableTSNumberData::reset(const Study& study) // solver or not. // WARNING: At this point in time, the variable pArea->renewable.clusterCount() // might not be valid (because not really initialized yet) - const uint clusterCount = pArea->renewable.list.size(); + const uint clusterCount = pArea->renewable.list.allClustersCount(); // Resize pTSNumberRules.reset(clusterCount, nbYears); return true; diff --git a/src/libs/antares/study/scenario-builder/ThermalTSNumberData.cpp b/src/libs/antares/study/scenario-builder/ThermalTSNumberData.cpp index 3df5493f95..58007ebb7e 100644 --- a/src/libs/antares/study/scenario-builder/ThermalTSNumberData.cpp +++ b/src/libs/antares/study/scenario-builder/ThermalTSNumberData.cpp @@ -35,11 +35,11 @@ bool thermalTSNumberData::reset(const Study& study) // If an area is available, it can only be an overlay for thermal timeseries // WARNING: The total number of clusters may vary if used from the // solver or not. - // WARNING: At this point in time, the variable pArea->thermal.clusterCount() + // WARNING: At this point, the variable pArea->thermal.list.size() // might not be valid (because not really initialized yet) uint clusterCount = (study.usedByTheSolver) - ? (pArea->thermal.list.size() + pArea->thermal.mustrunList.size()) - : pArea->thermal.list.size(); + ? (pArea->thermal.list.enabledCount()) + : pArea->thermal.list.allClustersCount(); // Resize pTSNumberRules.reset(clusterCount, nbYears); @@ -56,25 +56,16 @@ void thermalTSNumberData::saveToINIFile(const Study& /* study */, if (!pArea) return; -#ifndef NDEBUG - if (pTSNumberRules.width) + for (auto cluster : pArea->thermal.list.all()) { - assert(pTSNumberRules.width == pArea->thermal.list.size()); - } -#endif - - // Foreach thermal cluster... - for (uint index = 0; index != pTSNumberRules.width; ++index) - { - // Foreach year ... - for (uint y = 0; y != pTSNumberRules.height; ++y) + for (uint year = 0; year != pTSNumberRules.height; ++year) { - const uint val = get(pArea->thermal.list[index].get(), y); + const uint val = get(cluster.get(), year); // Equals to zero means 'auto', which is the default mode if (!val) continue; - file << prefix << pArea->id << "," << y << ',' - << pArea->thermal.list[index]->id() << " = " << val << '\n'; + file << prefix << pArea->id << "," << year << ',' + << cluster->id() << " = " << val << '\n'; } } } @@ -98,23 +89,18 @@ bool thermalTSNumberData::apply(Study& study) // Alias to the current area assert(pArea != nullptr); assert(pArea->index < study.areas.size()); - Area& area = *(study.areas.byIndex[pArea->index]); - // The total number of clusters for the area - // WARNING: We may have some thermal clusters with the `mustrun` option - auto clusterCount = (uint)area.thermal.clusterCount(); + const Area& area = *(study.areas.byIndex[pArea->index]); const uint tsGenCountThermal = get_tsGenCount(study); - for (uint clusterIndex = 0; clusterIndex != clusterCount; ++clusterIndex) + for (auto cluster : area.thermal.list.each_enabled()) { - auto& cluster = *(area.thermal.clusters[clusterIndex]); - // alias to the current column - assert(clusterIndex < pTSNumberRules.width); - const auto& col = pTSNumberRules[clusterIndex]; + assert(cluster->areaWideIndex < pTSNumberRules.width); + const auto& col = pTSNumberRules[cluster->areaWideIndex]; - logprefix.clear() << "Thermal: area '" << area.name << "', cluster: '" << cluster.name() + logprefix.clear() << "Thermal: area '" << area.name << "', cluster: '" << cluster->name() << "': "; - ret = ApplyToMatrix(errors, logprefix, cluster.series, col, tsGenCountThermal) && ret; + ret = ApplyToMatrix(errors, logprefix, cluster->series, col, tsGenCountThermal) && ret; } return ret; } diff --git a/src/libs/antares/study/scenario-builder/rules.cpp b/src/libs/antares/study/scenario-builder/rules.cpp index 728259db02..3840117f6f 100644 --- a/src/libs/antares/study/scenario-builder/rules.cpp +++ b/src/libs/antares/study/scenario-builder/rules.cpp @@ -131,11 +131,7 @@ bool Rules::readThermalCluster(const AreaName::Vector& splitKey, String value, b if (!area) return false; - const ThermalCluster* cluster = area->thermal.list.find(clustername); - if (!cluster) - cluster = area->thermal.mustrunList.find(clustername); - - if (cluster) + if (const ThermalCluster* cluster = area->thermal.list.findInAll(clustername); cluster) { uint val = fromStringToTSnumber(value); thermal[area->index].setTSnumber(cluster, year, val); @@ -170,7 +166,7 @@ bool Rules::readRenewableCluster(const AreaName::Vector& splitKey, String value, if (!area) return false; - const RenewableCluster* cluster = area->renewable.list.find(clustername); + const RenewableCluster* cluster = area->renewable.list.findInAll(clustername); if (cluster) { diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index 1dfe16627b..7ce8aae935 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -1042,12 +1042,12 @@ bool Study::clusterRename(Cluster* cluster, ClusterName newName) if (dynamic_cast(cluster)) { - found = area.thermal.list.find(newID); + found = area.thermal.list.findInAll(newID); type = kThermal; } else if (dynamic_cast(cluster)) { - found = area.renewable.list.find(newID); + found = area.renewable.list.findInAll(newID); type = kRenewable; } @@ -1080,11 +1080,9 @@ bool Study::clusterRename(Cluster* cluster, ClusterName newName) { case kRenewable: ret = area.renewable.list.rename(cluster->id(), newName); - area.renewable.prepareAreaWideIndexes(); break; case kThermal: ret = area.thermal.list.rename(cluster->id(), newName); - area.thermal.prepareAreaWideIndexes(); break; case kUnknown: logs.error() << "Unknown cluster type"; @@ -1122,7 +1120,7 @@ void Study::destroyAllWindTSGeneratorData() void Study::destroyAllThermalTSGeneratorData() { areas.each([&](Data::Area& area) { - for (const auto& cluster : area.thermal.list) + for (const auto cluster : area.thermal.list.each_enabled_and_not_mustrun()) FreeAndNil(cluster->prepro); }); } @@ -1408,10 +1406,9 @@ bool Study::checkForFilenameLimits(bool output, const String& chfolder) const auto& cname = clustername; cname.clear(); - area.thermal.list.each([&](const Cluster& cluster) { - if (cluster.id().size() > cname.size()) - cname = cluster.id(); - }); + for (auto cluster : area.thermal.list.all()) + if (cluster->id().size() > cname.size()) + cname = cluster->id(); }); String filename; @@ -1521,7 +1518,7 @@ void Study::computePThetaInfForThermalClusters() const // Alias de la zone courant const auto& area = *(this->areas.byIndex[i]); - for (auto& cluster : area.thermal.list) + for (auto& cluster : area.thermal.list.each_enabled_and_not_mustrun()) { for (uint k = 0; k < HOURS_PER_YEAR; k++) cluster->PthetaInf[k] = cluster->modulation[Data::thermalMinGenModulation][k] diff --git a/src/libs/antares/study/study.importprepro.cpp b/src/libs/antares/study/study.importprepro.cpp index d247f5190a..bfb03c18ad 100644 --- a/src/libs/antares/study/study.importprepro.cpp +++ b/src/libs/antares/study/study.importprepro.cpp @@ -104,10 +104,9 @@ bool Study::importTimeseriesIntoInput() // Spinning area.thermal.list.reverseCalculationOfSpinning(); - area.thermal.mustrunList.reverseCalculationOfSpinning(); buffer.clear() << folderInput << SEP << "thermal" << SEP << "series"; - ret = area.thermal.list.saveDataSeriesToFolder(buffer.c_str(), msg) && ret; + ret = area.thermal.list.saveDataSeriesToFolder(buffer.c_str()) && ret; ++progression; }); } diff --git a/src/libs/antares/study/ui-runtimeinfos.cpp b/src/libs/antares/study/ui-runtimeinfos.cpp index 2a1bd459b5..6ad88981b5 100644 --- a/src/libs/antares/study/ui-runtimeinfos.cpp +++ b/src/libs/antares/study/ui-runtimeinfos.cpp @@ -72,10 +72,9 @@ void UIRuntimeInfo::reload() set.insert(i->second); } - for (uint j = 0; j < area->thermal.clusterCount(); ++j) + for (auto cluster : area->thermal.list.each_enabled()) { - ThermalCluster* cluster = area->thermal.clusters[j]; - pClusters.push_back(cluster); + pClusters.push_back(cluster.get()); } } } diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 1182e2a2ca..22aec1d596 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -404,10 +404,8 @@ void HydroManagement::prepareNetDemand(uint year, Data::SimulationMode mode, - ((mode != Data::SimulationMode::Adequacy) ? scratchpad.mustrunSum[hour] : scratchpad.originalMustrunSum[hour]); - area.renewable.list.each([&](const Antares::Data::RenewableCluster& cluster) { - assert(cluster.series.timeSeries.jit == nullptr && "No JIT data from the solver"); - netdemand -= cluster.valueAtTimeStep(year, hour); - }); + for (auto c : area.renewable.list.each_enabled()) + netdemand -= c->valueAtTimeStep(year, hour); } assert(!Math::NaN(netdemand) diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 4a71daebec..c3cadf8033 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -47,19 +47,16 @@ void DispatchableMarginPostProcessCmd::execute(const optRuntimeData& opt_runtime for (uint h = 0; h != nbHoursInWeek; ++h) dtgmrg[h] = 0.; - if (not area.thermal.list.empty()) - { - auto& hourlyResults = problemeHebdo_->ResultatsHoraires[area.index]; + auto& hourlyResults = problemeHebdo_->ResultatsHoraires[area.index]; - for (const auto& cluster : area.thermal.list) + for (const auto& cluster : area.thermal.list.each_enabled_and_not_mustrun()) + { + const auto& availableProduction = cluster->series.getColumn(year); + for (uint h = 0; h != nbHoursInWeek; ++h) { - const auto& availableProduction = cluster->series.getColumn(year); - for (uint h = 0; h != nbHoursInWeek; ++h) - { - double production = hourlyResults.ProductionThermique[h] - .ProductionThermiqueDuPalier[cluster->index]; - dtgmrg[h] += availableProduction[h + hourInYear] - production; - } + double production = hourlyResults.ProductionThermique[h] + .ProductionThermiqueDuPalier[cluster->index]; + dtgmrg[h] += availableProduction[h + hourInYear] - production; } } }); diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index a83717f898..a00e2a21c5 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -124,7 +124,7 @@ void PrepareDataFromClustersInMustrunMode(Data::Study& study, Data::Area::Scratc double* mrs = scratchpad.mustrunSum; double* adq = scratchpad.originalMustrunSum; - for (const auto& cluster : area.thermal.mustrunList) + for (const auto& cluster : area.thermal.list.each_mustrun_and_enabled()) { const auto& availableProduction = cluster->series.getColumn(year); if (inAdequacy && cluster->mustrunOrigin) @@ -144,7 +144,7 @@ void PrepareDataFromClustersInMustrunMode(Data::Study& study, Data::Area::Scratc if (inAdequacy) { - for (const auto& cluster : area.thermal.mustrunList) + for (const auto& cluster : area.thermal.list.each_mustrun_and_enabled()) { if (!cluster->mustrunOrigin) continue; @@ -222,7 +222,7 @@ void PrepareRandomNumbers(Data::Study& study, yearRandomNumbers& randomForYear) { uint indexArea = 0; - study.areas.each([&](Data::Area& area) { + study.areas.each([&](const Data::Area& area) { double rnd = 0.; rnd = randomForYear.pUnsuppliedEnergy[indexArea]; @@ -277,12 +277,8 @@ void PrepareRandomNumbers(Data::Study& study, //----------------------------- // Thermal noises //----------------------------- - auto end = area.thermal.list.mapping.end(); - for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) + for (auto cluster : area.thermal.list.each_enabled()) { - auto cluster = it->second; - if (!cluster->enabled) - continue; uint clusterIndex = cluster->areaWideIndex; double& rnd = randomForYear.pThermalNoisesByArea[indexArea][clusterIndex]; double randomClusterProdCost(0.); @@ -368,23 +364,23 @@ void BuildThermalPartOfWeeklyProblem(Data::Study& study, for (uint areaIdx = 0; areaIdx < nbPays; ++areaIdx) { auto& area = *study.areas.byIndex[areaIdx]; - area.thermal.list.each([&](const Data::ThermalCluster& cluster) + for (auto cluster : area.thermal.list.each_enabled_and_not_mustrun()) { auto& Pt = problem.PaliersThermiquesDuPays[areaIdx] - .PuissanceDisponibleEtCout[cluster.index]; + .PuissanceDisponibleEtCout[cluster->index]; Pt.CoutHoraireDeProductionDuPalierThermique[hourInWeek] = - cluster.getMarketBidCost(hourInYear, year) - + thermalNoises[areaIdx][cluster.areaWideIndex]; + cluster->getMarketBidCost(hourInYear, year) + + thermalNoises[areaIdx][cluster->areaWideIndex]; Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] - = cluster.series.getCoefficient(year, hourInYear); + = cluster->series.getCoefficient(year, hourInYear); Pt.PuissanceMinDuPalierThermique[hourInWeek] - = (Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] < cluster.PthetaInf[hourInYear]) + = (Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] < cluster->PthetaInf[hourInYear]) ? Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] - : cluster.PthetaInf[hourInYear]; - }); + : cluster->PthetaInf[hourInYear]; + } } } @@ -392,7 +388,7 @@ void BuildThermalPartOfWeeklyProblem(Data::Study& study, { auto& area = *study.areas.byIndex[k]; - for (uint l = 0; l != area.thermal.list.size(); ++l) + for (uint l = 0; l != area.thermal.list.enabledAndNotMustRunCount(); ++l) { problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[l] .PuissanceDisponibleDuPalierThermiqueRef diff --git a/src/solver/simulation/include/antares/solver/simulation/solver.hxx b/src/solver/simulation/include/antares/solver/simulation/solver.hxx index f56d3d5b8e..7c475f0f9c 100644 --- a/src/solver/simulation/include/antares/solver/simulation/solver.hxx +++ b/src/solver/simulation/include/antares/solver/simulation/solver.hxx @@ -626,7 +626,7 @@ void ISimulation::allocateMemoryForRandomNumbers(randomNumbe { // logs.info() << " area : " << a << " :"; auto& area = *(study.areas.byIndex[a]); - size_t nbClusters = area.thermal.list.mapping.size(); + size_t nbClusters = area.thermal.list.allClustersCount(); randomForParallelYears.pYears[y].pThermalNoisesByArea[a] = new double[nbClusters]; randomForParallelYears.pYears[y].pNbClustersByArea[a] = nbClusters; } @@ -688,12 +688,11 @@ void ISimulation::computeRandomNumbers(randomNumbers& random for (unsigned int a = 0; a != nbAreas; ++a) { // logs.info() << " area : " << a << " :"; - auto& area = *(study.areas.byIndex[a]); + const auto& area = *(study.areas.byIndex[a]); - auto end = area.thermal.list.mapping.end(); - for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) + for (auto cluster : area.thermal.list.all()) { - uint clusterIndex = it->second->areaWideIndex; + uint clusterIndex = cluster->areaWideIndex; double thermalNoise = runtime.random[Data::seedThermalCosts].next(); if (isPerformed) randomForYears.pYears[indexYear].pThermalNoisesByArea[a][clusterIndex] = thermalNoise; diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index 2e932d0164..fecb3af268 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -344,7 +344,7 @@ void SIM_AllocateAreas(PROBLEME_HEBDO& problem, for (unsigned k = 0; k < nbPays; k++) { - const uint nbPaliers = study.areas.byIndex[k]->thermal.list.size(); + const uint nbPaliers = study.areas.byIndex[k]->thermal.list.enabledAndNotMustRunCount(); problem.PaliersThermiquesDuPays[k].minUpDownTime.assign(nbPaliers, 0); problem.PaliersThermiquesDuPays[k].PminDuPalierThermiquePendantUneHeure diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index a453454e3c..2ace94c543 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -277,40 +277,40 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, NombrePaliers = 0; for (uint i = 0; i < study.areas.size(); ++i) { - auto& area = *(study.areas.byIndex[i]); + const auto& area = *(study.areas.byIndex[i]); auto& pbPalier = problem.PaliersThermiquesDuPays[i]; - pbPalier.NombreDePaliersThermiques = area.thermal.list.size(); + unsigned int clusterCount = area.thermal.list.enabledAndNotMustRunCount(); + pbPalier.NombreDePaliersThermiques = clusterCount; - for (uint clusterIndex = 0; clusterIndex != area.thermal.list.size(); ++clusterIndex) + for (auto cluster : area.thermal.list.each_enabled_and_not_mustrun()) { - auto& cluster = *(area.thermal.list[clusterIndex]); - pbPalier.NumeroDuPalierDansLEnsembleDesPaliersThermiques[clusterIndex] - = NombrePaliers + clusterIndex; - pbPalier.TailleUnitaireDUnGroupeDuPalierThermique[clusterIndex] - = cluster.nominalCapacityWithSpinning; - pbPalier.PminDuPalierThermiquePendantUneHeure[clusterIndex] = cluster.minStablePower; - pbPalier.PminDuPalierThermiquePendantUnJour[clusterIndex] = 0; - pbPalier.minUpDownTime[clusterIndex] = cluster.minUpDownTime; - - pbPalier.CoutDeDemarrageDUnGroupeDuPalierThermique[clusterIndex] = cluster.startupCost; - pbPalier.CoutDArretDUnGroupeDuPalierThermique[clusterIndex] = 0; - pbPalier.CoutFixeDeMarcheDUnGroupeDuPalierThermique[clusterIndex] = cluster.fixedCost; - pbPalier.DureeMinimaleDeMarcheDUnGroupeDuPalierThermique[clusterIndex] - = cluster.minUpTime; - pbPalier.DureeMinimaleDArretDUnGroupeDuPalierThermique[clusterIndex] - = cluster.minDownTime; - - pbPalier.PmaxDUnGroupeDuPalierThermique[clusterIndex] - = cluster.nominalCapacityWithSpinning; - pbPalier.pminDUnGroupeDuPalierThermique[clusterIndex] - = (pbPalier.PmaxDUnGroupeDuPalierThermique[clusterIndex] < cluster.minStablePower) - ? pbPalier.PmaxDUnGroupeDuPalierThermique[clusterIndex] - : cluster.minStablePower; - pbPalier.NomsDesPaliersThermiques[clusterIndex] = cluster.name().c_str(); + pbPalier.NumeroDuPalierDansLEnsembleDesPaliersThermiques[cluster->index] + = NombrePaliers + cluster->index; + pbPalier.TailleUnitaireDUnGroupeDuPalierThermique[cluster->index] + = cluster->nominalCapacityWithSpinning; + pbPalier.PminDuPalierThermiquePendantUneHeure[cluster->index] = cluster->minStablePower; + pbPalier.PminDuPalierThermiquePendantUnJour[cluster->index] = 0; + pbPalier.minUpDownTime[cluster->index] = cluster->minUpDownTime; + + pbPalier.CoutDeDemarrageDUnGroupeDuPalierThermique[cluster->index] = cluster->startupCost; + pbPalier.CoutDArretDUnGroupeDuPalierThermique[cluster->index] = 0; + pbPalier.CoutFixeDeMarcheDUnGroupeDuPalierThermique[cluster->index] = cluster->fixedCost; + pbPalier.DureeMinimaleDeMarcheDUnGroupeDuPalierThermique[cluster->index] + = cluster->minUpTime; + pbPalier.DureeMinimaleDArretDUnGroupeDuPalierThermique[cluster->index] + = cluster->minDownTime; + + pbPalier.PmaxDUnGroupeDuPalierThermique[cluster->index] + = cluster->nominalCapacityWithSpinning; + pbPalier.pminDUnGroupeDuPalierThermique[cluster->index] + = (pbPalier.PmaxDUnGroupeDuPalierThermique[cluster->index] < cluster->minStablePower) + ? pbPalier.PmaxDUnGroupeDuPalierThermique[cluster->index] + : cluster->minStablePower; + pbPalier.NomsDesPaliersThermiques[cluster->index] = cluster->name().c_str(); } - NombrePaliers += area.thermal.list.size(); + NombrePaliers += clusterCount; } problem.NombreDePaliersThermiques = NombrePaliers; @@ -606,10 +606,8 @@ void SIM_RenseignementProblemeHebdo(const Study& study, mustRunGen = scratchpad.miscGenSum[hourInYear] + rorSeries + scratchpad.mustrunSum[hourInYear]; - area.renewable.list.each([&](const RenewableCluster& cluster) { - assert(cluster.series.timeSeries.jit == nullptr && "No JIT data from the solver"); - mustRunGen += cluster.valueAtTimeStep(year, hourInYear); - }); + for (auto c : area.renewable.list.each_enabled()) + mustRunGen += c->valueAtTimeStep(year, hourInYear); } assert( diff --git a/src/solver/simulation/timeseries-numbers.cpp b/src/solver/simulation/timeseries-numbers.cpp index f9231d7ecf..700637ea72 100644 --- a/src/solver/simulation/timeseries-numbers.cpp +++ b/src/solver/simulation/timeseries-numbers.cpp @@ -81,6 +81,7 @@ static bool GenerateDeratedMode(Study& study) logs.info() << " :: using the `derated` mode"; if (study.parameters.useCustomScenario) logs.warning() << "The derated mode is enabled. The custom building mode will be ignored"; + return true; } @@ -133,11 +134,9 @@ class ThermalAreaNumberOfTSretriever : public AreaNumberOfTSretriever std::vector getAreaTimeSeriesNumber(const Area& area) override { std::vector to_return; - uint clusterCount = (uint)area.thermal.clusterCount(); - for (uint i = 0; i != clusterCount; ++i) + for (auto cluster : area.thermal.list.each_enabled()) { - auto& cluster = *(area.thermal.clusters[i]); - to_return.push_back(cluster.series.timeSeries.width); + to_return.push_back(cluster->series.timeSeries.width); } return to_return; } @@ -149,7 +148,7 @@ class RenewClustersAreaNumberOfTSretriever : public AreaNumberOfTSretriever std::vector getAreaTimeSeriesNumber(const Area& area) override { std::vector to_return; - for (const auto& cluster : area.renewable.list) + for (const auto cluster : area.renewable.list.each_enabled()) { to_return.push_back(cluster->series.timeSeries.width); } @@ -258,7 +257,7 @@ bool checkIntraModalConsistency(array& nbTimeseriesByMode return true; } -bool checkInterModalConsistencyForArea(Area& area, +bool checkInterModalConsistencyForArea(const Area& area, const array& isTSintermodal) { // 1. Making a list of TS numbers : @@ -300,23 +299,16 @@ bool checkInterModalConsistencyForArea(Area& area, indexTS = ts_to_tsIndex.at(timeSeriesThermal); if (isTSintermodal[indexTS]) { - const uint clusterCount = (uint)area.thermal.clusterCount(); - for (uint j = 0; j != clusterCount; ++j) - { - auto& cluster = *(area.thermal.clusters[j]); - listNumberTsOverArea.push_back(cluster.series.timeSeries.width); - } + for (auto cluster : area.thermal.list.each_enabled()) + listNumberTsOverArea.push_back(cluster->series.timeSeries.width); } // Renewable clusters : Add renewable's number of TS of each cluster in area ... indexTS = ts_to_tsIndex.at(timeSeriesRenewable); if (isTSintermodal[indexTS]) { - for (const auto& cluster : area.renewable.list) - { - uint nbTimeSeries = cluster->series.timeSeries.width; - listNumberTsOverArea.push_back(nbTimeSeries); - } + for (const auto cluster : area.renewable.list.each_enabled()) + listNumberTsOverArea.push_back(cluster->series.timeSeries.width); } // Now check if all elements of list of TS numbers are identical or equal to 1 @@ -408,11 +400,8 @@ void storeTSnumbersForIntraModal(const array& intramo if (isTSintramodal[indexTS]) { - for (auto [_, cluster] : area.thermal.list.mapping) - { - if (cluster->enabled && cluster->series.timeSeries.width > 1) - cluster->series.timeseriesNumbers[0][year] = intramodal_draws[indexTS]; - } + for (auto cluster : area.thermal.list.each_enabled()) + cluster->series.timeseriesNumbers[0][year] = intramodal_draws[indexTS]; } // -------------------------- @@ -422,11 +411,8 @@ void storeTSnumbersForIntraModal(const array& intramo if (isTSintramodal[indexTS]) { - for (auto& cluster : area.renewable.list) - { - if (cluster->enabled && cluster->series.timeSeries.width > 1) - cluster->series.timeseriesNumbers[0][year] = intramodal_draws[indexTS]; - } + for (auto& cluster : area.renewable.list.each_enabled()) + cluster->series.timeseriesNumbers[0][year] = intramodal_draws[indexTS]; } // ------------------------------- @@ -500,11 +486,9 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i // ------------- indexTS = ts_to_tsIndex.at(timeSeriesThermal); - auto end_th_clusters = area.thermal.list.mapping.end(); - for (auto i = area.thermal.list.mapping.begin(); i != end_th_clusters; ++i) + for (auto cluster : area.thermal.list.all()) { - ThermalClusterList::SharedPtr cluster = i->second; - if (not cluster->enabled) + if (!cluster->enabled) study.runtime->random[seedTimeseriesNumbers].next(); else { @@ -521,19 +505,14 @@ void drawAndStoreTSnumbersForNOTintraModal(const array& i // -------------------------- indexTS = ts_to_tsIndex.at(timeSeriesRenewable); - for (auto& cluster : area.renewable.list) + for (auto& cluster : area.renewable.list.each_enabled()) { - if (not cluster->enabled) - study.runtime->random[seedTimeseriesNumbers].next(); - else + if (!isTSintramodal[indexTS]) { - if (!isTSintramodal[indexTS]) - { - // There is no TS generation for renewable clusters - uint nbTimeSeries = cluster->series.timeSeries.width; - cluster->series.timeseriesNumbers[0][year] = (uint32_t)( - floor(study.runtime->random[seedTimeseriesNumbers].next() * nbTimeSeries)); - } + // There is no TS generation for renewable clusters + uint nbTimeSeries = cluster->series.timeSeries.width; + cluster->series.timeseriesNumbers[0][year] = (uint32_t)( + floor(study.runtime->random[seedTimeseriesNumbers].next() * nbTimeSeries)); } } @@ -583,12 +562,18 @@ Matrix* getFirstTSnumberInterModalMatrixFoundInArea( tsNumbersMtx = &(area.wind.series.timeseriesNumbers); else if (isTSintermodal[ts_to_tsIndex.at(timeSeriesHydro)]) tsNumbersMtx = &(area.hydro.series->timeseriesNumbers); - else if (isTSintermodal[ts_to_tsIndex.at(timeSeriesThermal)] - && area.thermal.clusterCount() > 0) - tsNumbersMtx = &(area.thermal.clusters[0]->series.timeseriesNumbers); + else if (isTSintermodal[ts_to_tsIndex.at(timeSeriesThermal)] && + !area.thermal.list.each_enabled().empty()) + { + std::shared_ptr cluster = *(area.thermal.list.each_enabled().begin()); + tsNumbersMtx = &(cluster->series.timeseriesNumbers); + } else if (isTSintermodal[ts_to_tsIndex.at(timeSeriesRenewable)] - && area.renewable.list.size() > 0) - tsNumbersMtx = &(area.renewable.list[0]->series.timeseriesNumbers); + && area.renewable.list.enabledCount() > 0) + { + std::shared_ptr cluster = *(area.renewable.list.each_enabled().begin()); + tsNumbersMtx = &(cluster->series.timeseriesNumbers); + } } assert(tsNumbersMtx); @@ -623,17 +608,15 @@ void applyMatrixDrawsToInterModalModesInArea(Matrix* tsNumbersMtx, if (isTSintermodal[ts_to_tsIndex.at(timeSeriesThermal)]) { - uint clusterCount = (uint)area.thermal.clusterCount(); - for (uint i = 0; i != clusterCount; ++i) + for (auto cluster : area.thermal.list.each_enabled()) { - auto& cluster = *(area.thermal.clusters[i]); - assert(year < cluster.series.timeseriesNumbers.height); - cluster.series.timeseriesNumbers[0][year] = draw; + assert(year < cluster->series.timeseriesNumbers.height); + cluster->series.timeseriesNumbers[0][year] = draw; } } if (isTSintermodal[ts_to_tsIndex.at(timeSeriesRenewable)]) { - for (const auto& cluster : area.renewable.list) + for (const auto& cluster : area.renewable.list.each_enabled()) { assert(year < cluster->series.timeseriesNumbers.height); cluster->series.timeseriesNumbers[0][year] = draw; @@ -676,7 +659,7 @@ bool TimeSeriesNumbers::Generate(Study& study) array intramodal_draws; std::fill(intramodal_draws.begin(), intramodal_draws.end(), 0); - if (not checkIntraModalConsistency(nbTimeseriesByMode, isTSintramodal, study)) + if (!checkIntraModalConsistency(nbTimeseriesByMode, isTSintramodal, study)) return false; for (uint year = 0; year < years; ++year) diff --git a/src/solver/ts-generator/generator.cpp b/src/solver/ts-generator/generator.cpp index 82f25d1b95..7db121112c 100644 --- a/src/solver/ts-generator/generator.cpp +++ b/src/solver/ts-generator/generator.cpp @@ -54,7 +54,7 @@ void ResizeGeneratedTimeSeries(Data::AreaList& areas, Data::Parameters& params) // Thermal bool globalThermalTSgeneration = params.timeSeriesToGenerate & Data::timeSeriesThermal; - for (auto [_, cluster] : area.thermal.list.mapping) + for (const auto& cluster : area.thermal.list.all()) { if (cluster->doWeGenerateTS(globalThermalTSgeneration)) cluster->series.timeSeries.reset(params.nbTimeSeriesThermal, HOURS_PER_YEAR); @@ -71,4 +71,4 @@ void DestroyAll(Data::Study& study) Destroy(study, (uint)-1); } -} // Antares::TSGenerator \ No newline at end of file +} // Antares::TSGenerator diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index af7fa927a6..b62b83d596 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -607,16 +607,12 @@ bool GenerateThermalTimeSeries(Data::Study& study, generator->currentYear = year; study.areas.each([&](Data::Area& area) { - auto end = area.thermal.list.mapping.end(); - for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) + for (auto cluster : area.thermal.list.all()) { - auto& cluster = *(it->second); - - if (cluster.doWeGenerateTS(globalThermalTSgeneration) && refreshTSonCurrentYear) + if (cluster->doWeGenerateTS(globalThermalTSgeneration) && refreshTSonCurrentYear) { - (*generator)(area, cluster); + (*generator)(area, *cluster); } - ++progression; } }); diff --git a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h index a3a2740cfa..79bff464d5 100644 --- a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h +++ b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h @@ -258,10 +258,10 @@ class OverallCost : public Variable::IVariable, NextT, VCardO * state.hourlyResults->PompageHoraire[state.hourInTheWeek]); // Thermal costs - for (uint clusterIndex = 0; clusterIndex != area->thermal.clusterCount(); ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { pValuesForTheCurrentYear[numSpace][state.hourInTheYear] - += thermal[area->index].thermalClustersOperatingCost[clusterIndex]; + += thermal[area->index].thermalClustersOperatingCost[cluster->areaWideIndex]; } // Next variable diff --git a/src/solver/variable/include/antares/solver/variable/area.inc.hxx b/src/solver/variable/include/antares/solver/variable/area.inc.hxx index 0ebc6bd3c6..28146ad13d 100644 --- a/src/solver/variable/include/antares/solver/variable/area.inc.hxx +++ b/src/solver/variable/include/antares/solver/variable/area.inc.hxx @@ -127,11 +127,10 @@ void Areas::hourForEachArea(State& state, uint numSpace) // Initializing the state for the current area state.initFromAreaIndex(area.index, numSpace); - // For each thermal cluster - for (uint j = 0; j != area.thermal.clusterCount(); ++j) + for (auto cluster : area.thermal.list.each_enabled()) { // Intiializing the state for the current thermal cluster - state.initFromThermalClusterIndex(j); + state.initFromThermalClusterIndex(cluster->areaWideIndex); } // Variables @@ -194,17 +193,16 @@ void Areas::yearEndBuild(State& state, uint year, uint numSpace) // Variables auto& variablesForArea = pAreas[area.index]; - // For each thermal cluster - for (uint j = 0; j != area.thermal.clusterCount(); ++j) + for(auto cluster : area.thermal.list.each_enabled()) { - state.thermalCluster = area.thermal.clusters[j]; + state.thermalCluster = cluster.get(); state.yearEndResetThermal(); // Variables variablesForArea.yearEndBuildPrepareDataForEachThermalCluster(state, year, numSpace); // Building the end of year - state.yearEndBuildFromThermalClusterIndex(j); + state.yearEndBuildFromThermalClusterIndex(cluster->areaWideIndex); // Variables variablesForArea.yearEndBuildForEachThermalCluster(state, year, numSpace); diff --git a/src/solver/variable/include/antares/solver/variable/economy/avail-dispatchable-generation.h b/src/solver/variable/include/antares/solver/variable/economy/avail-dispatchable-generation.h index 51e33e0ab0..69b4fecbef 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/avail-dispatchable-generation.h +++ b/src/solver/variable/include/antares/solver/variable/economy/avail-dispatchable-generation.h @@ -186,23 +186,18 @@ class AvailableDispatchGen NextType::simulationEnd(); } - void addThermalClusterList(Data::ThermalClusterList& list, unsigned int year, unsigned int numSpace) + void yearBegin(unsigned int year, unsigned int numSpace) { - for (const auto& cluster : list) + // Somme de toutes les productions disponibles pour l'ensemble des + // paliers thermiques (+must-run) + pValuesForTheCurrentYear[numSpace].reset(); + for (const auto cluster : pArea->thermal.list.each_enabled()) { const auto& availableProduction = cluster->series.getColumn(year); for (unsigned int hour = 0; hour != cluster->series.timeSeries.height; ++hour) pValuesForTheCurrentYear[numSpace].hour[hour] += availableProduction[hour]; } - } - void yearBegin(unsigned int year, unsigned int numSpace) - { - // Somme de toutes les productions disponibles pour l'ensemble des - // paliers thermiques (+must-run) - pValuesForTheCurrentYear[numSpace].reset(); - addThermalClusterList(pArea->thermal.list, year, numSpace); - addThermalClusterList(pArea->thermal.mustrunList, year, numSpace); // Next variable NextType::yearBegin(year, numSpace); diff --git a/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h b/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h index f91fa4740e..191390ac04 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h +++ b/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h @@ -265,12 +265,10 @@ class DispatchableGeneration { auto area = state.area; auto& thermal = state.thermal; - for (uint clusterIndex = 0; clusterIndex != state.area->thermal.clusterCount(); - ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { - const auto* thermalCluster = area->thermal.clusters[clusterIndex]; - pValuesForTheCurrentYear[numSpace][thermalCluster->groupID][state.hourInTheYear] - += thermal[area->index].thermalClustersProductions[clusterIndex]; + pValuesForTheCurrentYear[numSpace][cluster->groupID][state.hourInTheYear] + += thermal[area->index].thermalClustersProductions[cluster->areaWideIndex]; } // Next variable diff --git a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h index 2473d553c2..ead53944c3 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h @@ -155,7 +155,7 @@ class NbOfDispatchedUnitsByPlant : public Variable::IVariablethermal.clusterCount(); + pSize = area->thermal.list.enabledCount(); if (pSize) { AncestorType::pResults.resize(pSize); @@ -293,13 +293,10 @@ class NbOfDispatchedUnitsByPlant : public Variable::IVariablethermal.clusterCount(); - ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { - const auto* thermalCluster = area->thermal.clusters[clusterIndex]; - pValuesForTheCurrentYear[numSpace][thermalCluster->areaWideIndex] - .hour[state.hourInTheYear] - = thermal[area->index].numberOfUnitsONbyCluster[clusterIndex]; + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].hour[state.hourInTheYear] + = thermal[area->index].numberOfUnitsONbyCluster[cluster->areaWideIndex]; } // Next variable @@ -327,12 +324,12 @@ class NbOfDispatchedUnitsByPlant : public Variable::IVariablethermal; // Write the data for the current year - for (uint i = 0; i < pSize; ++i) + for (auto cluster : thermal.list.each_enabled()) { // Write the data for the current year - results.variableCaption = thermal.clusters[i]->name(); // VCardType::Caption(); + results.variableCaption = cluster->name(); // VCardType::Caption(); results.variableUnit = VCardType::Unit(); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].template buildAnnualSurveyReport( results, fileLevel, precision); } } diff --git a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h index 95d15cba3c..e350e4d8d5 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h @@ -158,7 +158,7 @@ class NonProportionalCostByDispatchablePlant pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel]; // Get the area - pSize = area->thermal.clusterCount(); + pSize = area->thermal.list.enabledCount(); if (pSize) { AncestorType::pResults.resize(pSize); @@ -305,12 +305,12 @@ class NonProportionalCostByDispatchablePlant const auto& thermal = results.data.area->thermal; // Write the data for the current year - for (uint i = 0; i < pSize; ++i) + for (auto cluster : thermal.list.each_enabled()) { // Write the data for the current year - results.variableCaption = thermal.clusters[i]->name(); // VCardType::Caption(); + results.variableCaption = cluster->name(); // VCardType::Caption(); results.variableUnit = VCardType::Unit(); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].template buildAnnualSurveyReport( results, fileLevel, precision); } } diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h index 2355a68928..0a97ad2051 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h @@ -160,7 +160,7 @@ class ProductionByDispatchablePlant pminOfTheClusterForYear = new double*[pNbYearsParallel]; // Get the area - pSize = area->thermal.clusterCount(); + pSize = area->thermal.list.enabledCount(); if (pSize) { AncestorType::pResults.resize(pSize); @@ -303,18 +303,16 @@ class ProductionByDispatchablePlant { auto& area = state.area; auto& thermal = state.thermal; - for (uint clusterIndex = 0; clusterIndex != state.area->thermal.clusterCount(); - ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { - const auto* thermalCluster = area->thermal.clusters[clusterIndex]; // Production for this hour - pValuesForTheCurrentYear[numSpace][thermalCluster->areaWideIndex] + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex] .hour[state.hourInTheYear] - += thermal[area->index].thermalClustersProductions[clusterIndex]; + += thermal[area->index].thermalClustersProductions[cluster->areaWideIndex]; - pminOfTheClusterForYear[numSpace][(thermalCluster->areaWideIndex * maxHoursInAYear) + pminOfTheClusterForYear[numSpace][(cluster->areaWideIndex * maxHoursInAYear) + state.hourInTheYear] - = thermal[area->index].PMinOfClusters[clusterIndex]; + = thermal[area->index].PMinOfClusters[cluster->areaWideIndex]; } // Next variable @@ -357,12 +355,12 @@ class ProductionByDispatchablePlant const auto& thermal = results.data.area->thermal; // Write the data for the current year - for (uint i = 0; i < pSize; ++i) + for (auto cluster : thermal.list.each_enabled()) { // Write the data for the current year - results.variableCaption = thermal.clusters[i]->name(); // VCardType::Caption(); + results.variableCaption = cluster->name(); // VCardType::Caption(); results.variableUnit = VCardType::Unit(); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].template buildAnnualSurveyReport( results, fileLevel, precision); } } diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h index a8f0766c68..dc8164f3aa 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h @@ -153,7 +153,7 @@ class ProductionByRenewablePlant : public Variable::IVariablerenewable.list.size(); + pSize = area->renewable.list.enabledCount(); if (pSize) { AncestorType::pResults.resize(pSize); @@ -271,7 +271,7 @@ class ProductionByRenewablePlant : public Variable::IVariablerenewable.list) + for (const auto renewableCluster : state.area->renewable.list.each_enabled()) { double renewableClusterProduction = renewableCluster->valueAtTimeStep(state.year, state.hourInTheYear); @@ -318,12 +318,12 @@ class ProductionByRenewablePlant : public Variable::IVariablerenewable; // Write the data for the current year - for (uint i = 0; i < pSize; ++i) + for (auto cluster : renewable.list.each_enabled()) { // Write the data for the current year - results.variableCaption = renewable.list[i]->name(); + results.variableCaption = cluster->name(); results.variableUnit = VCardType::Unit(); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].template buildAnnualSurveyReport( results, fileLevel, precision); } } diff --git a/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h b/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h index aa5912e0bc..3627e00d80 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h +++ b/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h @@ -151,7 +151,7 @@ class ProfitByPlant : public Variable::IVariable, NextT, VC pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel]; // Get the area - pNbClustersOfArea = area->thermal.clusterCount(); + pNbClustersOfArea = area->thermal.list.enabledCount(); if (pNbClustersOfArea) { AncestorType::pResults.resize(pNbClustersOfArea); @@ -265,13 +265,11 @@ class ProfitByPlant : public Variable::IVariable, NextT, VC uint hourInTheWeek = state.hourInTheWeek; uint hourInTheYear = state.hourInTheYear; - for (uint clusterIndex = 0; clusterIndex != state.area->thermal.clusterCount(); - ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { - auto* cluster = state.area->thermal.clusters[clusterIndex]; double hourlyClusterProduction - = thermal[area->index].thermalClustersProductions[clusterIndex]; - double pMin = thermal[area->index].PMinOfClusters[clusterIndex]; + = thermal[area->index].thermalClustersProductions[cluster->areaWideIndex]; + double pMin = thermal[area->index].PMinOfClusters[cluster->areaWideIndex]; uint tsIndex = cluster->series.timeseriesNumbers[0][state.year]; // Thermal cluster profit @@ -306,12 +304,12 @@ class ProfitByPlant : public Variable::IVariable, NextT, VC const auto& thermal = results.data.area->thermal; // Write the data for the current year - for (uint i = 0; i < pNbClustersOfArea; ++i) + for (auto cluster : thermal.list.each_enabled()) { // Write the data for the current year - results.variableCaption = thermal.clusters[i]->name(); // VCardType::Caption(); + results.variableCaption = cluster->name(); // VCardType::Caption(); results.variableUnit = VCardType::Unit(); - pValuesForTheCurrentYear[numSpace][i].template buildAnnualSurveyReport( + pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].template buildAnnualSurveyReport( results, fileLevel, precision); } } diff --git a/src/solver/variable/include/antares/solver/variable/economy/renewableGeneration.h b/src/solver/variable/include/antares/solver/variable/economy/renewableGeneration.h index 08eec29552..5e4b15c2ca 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/renewableGeneration.h +++ b/src/solver/variable/include/antares/solver/variable/economy/renewableGeneration.h @@ -261,7 +261,7 @@ class RenewableGeneration void hourForEachArea(State& state, unsigned int numSpace) { - for (const auto& renewableCluster : state.area->renewable.list) + for (const auto renewableCluster : state.area->renewable.list.each_enabled()) { double renewableClusterProduction = renewableCluster->valueAtTimeStep(state.year, state.hourInTheYear); diff --git a/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h b/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h index 649c6855bd..c83dbbb9ca 100644 --- a/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h +++ b/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h @@ -240,16 +240,14 @@ class ThermalAirPollutantEmissions : public Variable::IVariablethermal.clusterCount(); ++clusterIndex) + for (auto cluster : area->thermal.list.each_enabled()) { - auto* thermalCluster = area->thermal.clusters[clusterIndex]; - // Multiply every pollutant factor with production - for (int i = 0; i < Antares::Data::Pollutant::POLLUTANT_MAX; i++) + for (int pollutant = 0; pollutant < Antares::Data::Pollutant::POLLUTANT_MAX; pollutant++) { - pValuesForTheCurrentYear[numSpace][i][state.hourInTheYear] - += thermalCluster->emissions.factors[i] - * thermal[state.area->index].thermalClustersProductions[clusterIndex]; + pValuesForTheCurrentYear[numSpace][pollutant][state.hourInTheYear] + += cluster->emissions.factors[pollutant] + * thermal[state.area->index].thermalClustersProductions[cluster->areaWideIndex]; } } diff --git a/src/solver/variable/include/antares/solver/variable/info.h b/src/solver/variable/include/antares/solver/variable/info.h index 09b13b438f..41d08574bf 100644 --- a/src/solver/variable/include/antares/solver/variable/info.h +++ b/src/solver/variable/include/antares/solver/variable/info.h @@ -366,7 +366,7 @@ struct VariableAccessor const Data::PartThermal& thermal = results.data.area->thermal; for (uint i = 0; i != container.size(); ++i) { - results.variableCaption = thermal.clusters[i]->name(); + results.variableCaption = thermal.list.enabledClusterAt(i)->name(); container[i].template buildDigest(results, digestLevel, dataLevel); } @@ -395,13 +395,13 @@ struct VariableAccessor if (thermal_details) { auto& thermal = results.data.area->thermal; - results.variableCaption = thermal.clusters[idx]->name(); + results.variableCaption = thermal.list.enabledClusterAt(idx)->name(); return true; } if (renewable_details) { auto& renewable = results.data.area->renewable; - results.variableCaption = renewable.list[idx]->name(); + results.variableCaption = renewable.list.enabledClusterAt(idx)->name(); return true; } if (st_storage_details) diff --git a/src/solver/variable/include/antares/solver/variable/surveyresults/reportbuilder.hxx b/src/solver/variable/include/antares/solver/variable/surveyresults/reportbuilder.hxx index ff0480c8a1..d3dea1a9b7 100644 --- a/src/solver/variable/include/antares/solver/variable/surveyresults/reportbuilder.hxx +++ b/src/solver/variable/include/antares/solver/variable/surveyresults/reportbuilder.hxx @@ -318,7 +318,7 @@ private: if (VariablesStatsByDataLevel::count) { auto& area = *results.data.area; - for (const auto& cluster : area.thermal.list) + for (auto cluster : area.thermal.list.each_enabled_and_not_mustrun()) { results.data.thermalCluster = cluster.get(); diff --git a/src/solver/variable/state.cpp b/src/solver/variable/state.cpp index 7665214f82..60121c5b59 100644 --- a/src/solver/variable/state.cpp +++ b/src/solver/variable/state.cpp @@ -44,7 +44,7 @@ ThermalState::StateForAnArea& ThermalState::operator[](size_t areaIndex) void ThermalState::StateForAnArea::initializeFromArea(const Data::Area& area) { - const auto count = area.thermal.clusterCount(); + const auto count = area.thermal.list.enabledCount(); thermalClustersProductions.resize(count); numberOfUnitsONbyCluster.resize(count); thermalClustersOperatingCost.resize(count); @@ -69,10 +69,10 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex) { // asserts assert(area); - assert(clusterAreaWideIndex < area->thermal.clusterCount()); + assert(clusterAreaWideIndex < area->thermal.list.enabledCount()); // alias to the current thermal cluster - thermalCluster = area->thermal.clusters[clusterAreaWideIndex]; + thermalCluster = area->thermal.list.enabledClusterAt(clusterAreaWideIndex).get(); double thermalClusterAvailableProduction = thermalCluster->series.getCoefficient(this->year, hourInTheYear); @@ -232,7 +232,7 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex) // Get cluster properties - Data::ThermalCluster* currentCluster = area->thermal.clusters[clusterAreaWideIndex]; + Data::ThermalCluster* currentCluster = area->thermal.list.enabledClusterAt(clusterAreaWideIndex).get(); assert(endHourForCurrentYear <= Variable::maxHoursInAYear); assert(endHourForCurrentYear <= currentCluster->series.timeSeries.height); diff --git a/src/solver/variable/surveyresults/surveyresults.cpp b/src/solver/variable/surveyresults/surveyresults.cpp index ec349a37c1..d358b8b7f4 100644 --- a/src/solver/variable/surveyresults/surveyresults.cpp +++ b/src/solver/variable/surveyresults/surveyresults.cpp @@ -123,27 +123,24 @@ static void ExportGridInfosAreas(const Data::Study& study, } // Thermal clusters - for (uint i = 0; i != area.thermal.clusterCount(); ++i) + for (auto cluster : area.thermal.list.each_enabled()) { - assert(NULL != area.thermal.clusters[i]); - auto& cluster = *(area.thermal.clusters[i]); - outThermal << area.id << '\t'; - outThermal << cluster.id() << '\t'; - outThermal << cluster.name() << '\t'; - outThermal << Data::ThermalCluster::GroupName(cluster.groupID) << '\t'; - outThermal << cluster.unitCount << '\t'; - outThermal << cluster.nominalCapacity << '\t'; - outThermal << cluster.minStablePower << '\t'; - outThermal << cluster.minUpTime << '\t'; - outThermal << cluster.minDownTime << '\t'; - outThermal << cluster.spinning << '\t'; - outThermal << cluster.emissions.factors[Antares::Data::Pollutant::CO2] << '\t'; - outThermal << cluster.marginalCost << '\t'; - outThermal << cluster.fixedCost << '\t'; - outThermal << cluster.startupCost << '\t'; - outThermal << cluster.marketBidCost << '\t'; - outThermal << cluster.spreadCost << '\n'; + outThermal << cluster->id() << '\t'; + outThermal << cluster->name() << '\t'; + outThermal << Data::ThermalCluster::GroupName(cluster->groupID) << '\t'; + outThermal << cluster->unitCount << '\t'; + outThermal << cluster->nominalCapacity << '\t'; + outThermal << cluster->minStablePower << '\t'; + outThermal << cluster->minUpTime << '\t'; + outThermal << cluster->minDownTime << '\t'; + outThermal << cluster->spinning << '\t'; + outThermal << cluster->emissions.factors[Antares::Data::Pollutant::CO2] << '\t'; + outThermal << cluster->marginalCost << '\t'; + outThermal << cluster->fixedCost << '\t'; + outThermal << cluster->startupCost << '\t'; + outThermal << cluster->marketBidCost << '\t'; + outThermal << cluster->spreadCost << '\n'; } // each thermal cluster }); // each area diff --git a/src/tests/end-to-end/utils/utils.cpp b/src/tests/end-to-end/utils/utils.cpp index 7704fcb2ac..3d3ef97732 100644 --- a/src/tests/end-to-end/utils/utils.cpp +++ b/src/tests/end-to-end/utils/utils.cpp @@ -43,10 +43,7 @@ std::shared_ptr addClusterToArea(Area* area, const std::string& cluster->setName(clusterName); cluster->reset(); - auto added = area->thermal.list.add(cluster); - - area->thermal.list.mapping[cluster->id()] = added; - area->thermal.prepareAreaWideIndexes(); + area->thermal.list.addToCompleteList(cluster); return cluster; } 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 76a5376739..a0d301f162 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 @@ -38,14 +38,12 @@ using namespace Antares::Data; void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->thermal.clusters.push_back(cluster.get()); - area->thermal.list.add(cluster); - area->thermal.list.mapping[cluster->id()] = cluster; + area->thermal.list.addToCompleteList(cluster); } void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->renewable.list.add(cluster); + area->renewable.list.addToCompleteList(cluster); } template @@ -125,11 +123,6 @@ struct Fixture thCluster_12->series.timeSeries.resize(14, 1); thCluster_31->series.timeSeries.resize(14, 1); - // Thermal clusters : update areas local numbering for clusters - area_1->thermal.prepareAreaWideIndexes(); - area_2->thermal.prepareAreaWideIndexes(); - area_3->thermal.prepareAreaWideIndexes(); - // Add renewable clusters rnCluster_21 = addClusterToArea(area_2, "rn-cluster-21"); rnCluster_31 = addClusterToArea(area_3, "rn-cluster-31"); @@ -140,11 +133,6 @@ struct Fixture rnCluster_31->series.timeSeries.resize(9, 1); rnCluster_32->series.timeSeries.resize(9, 1); - // Renewable clusters : update areas local numbering for clusters - area_1->renewable.prepareAreaWideIndexes(); - area_2->renewable.prepareAreaWideIndexes(); - area_3->renewable.prepareAreaWideIndexes(); - // Resize all TS numbers storage (1 column x nbYears lines) area_1->resizeAllTimeseriesNumbers(study->parameters.nbYears); area_2->resizeAllTimeseriesNumbers(study->parameters.nbYears); 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 015559dac4..e5e09773e9 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 @@ -79,14 +79,12 @@ void referenceScBuilderFile::write() void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->thermal.clusters.push_back(cluster.get()); - area->thermal.list.add(cluster); - area->thermal.list.mapping[cluster->id()] = cluster; + area->thermal.list.addToCompleteList(cluster); } void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->renewable.list.add(cluster); + area->renewable.list.addToCompleteList(cluster); } template @@ -166,11 +164,6 @@ struct commonFixture thCluster_12->series.timeSeries.resize(14, 1); thCluster_31->series.timeSeries.resize(14, 1); - // Thermal clusters : update areas local numbering for clusters - area_1->thermal.prepareAreaWideIndexes(); - area_2->thermal.prepareAreaWideIndexes(); - area_3->thermal.prepareAreaWideIndexes(); - // Add renewable clusters rnCluster_21 = addClusterToArea(area_2, "rn-cluster-21"); rnCluster_31 = addClusterToArea(area_3, "rn-cluster-31"); @@ -181,11 +174,6 @@ struct commonFixture rnCluster_31->series.timeSeries.resize(9, 1); rnCluster_32->series.timeSeries.resize(9, 1); - // Renewable clusters : update areas local numbering for clusters - area_1->renewable.prepareAreaWideIndexes(); - area_2->renewable.prepareAreaWideIndexes(); - area_3->renewable.prepareAreaWideIndexes(); - // Resize all TS numbers storage (1 column x nbYears lines) area_1->resizeAllTimeseriesNumbers(study->parameters.nbYears); area_2->resizeAllTimeseriesNumbers(study->parameters.nbYears); diff --git a/src/tests/src/libs/antares/study/test_study.cpp b/src/tests/src/libs/antares/study/test_study.cpp index 16981c5f80..1474f85178 100644 --- a/src/tests/src/libs/antares/study/test_study.cpp +++ b/src/tests/src/libs/antares/study/test_study.cpp @@ -79,14 +79,16 @@ BOOST_FIXTURE_TEST_CASE(thermal_cluster_delete, OneAreaStudy) auto disabledCluster = std::make_shared(areaA); disabledCluster->setName("Cluster1"); disabledCluster->enabled = false; + auto enabledCluster = std::make_shared(areaA); + enabledCluster->setName("Cluster2"); + enabledCluster->enabled = true; - areaA->thermal.list.add(disabledCluster); - // Check that "Cluster1" is found - BOOST_CHECK_EQUAL(areaA->thermal.list.find("cluster1"), disabledCluster.get()); + areaA->thermal.list.addToCompleteList(disabledCluster); + areaA->thermal.list.addToCompleteList(enabledCluster); - study->initializeRuntimeInfos(); // This should remove all disabled thermal clusters // Check that "Cluster1" isn't found - BOOST_CHECK_EQUAL(areaA->thermal.list.find("cluster1"), nullptr); + for (const auto c : areaA->thermal.list.each_enabled()) + BOOST_CHECK(c->name() != "Cluster1"); } BOOST_FIXTURE_TEST_CASE(renewable_cluster_delete, OneAreaStudy) @@ -94,14 +96,16 @@ BOOST_FIXTURE_TEST_CASE(renewable_cluster_delete, OneAreaStudy) auto disabledCluster = std::make_shared(areaA); disabledCluster->setName("Cluster1"); disabledCluster->enabled = false; + auto enabledCluster = std::make_shared(areaA); + enabledCluster->setName("Cluster2"); + enabledCluster->enabled = true; - areaA->renewable.list.add(disabledCluster); - // Check that "Cluster1" is found - BOOST_CHECK_EQUAL(areaA->renewable.list.find("cluster1"), disabledCluster.get()); + areaA->renewable.list.addToCompleteList(disabledCluster); + areaA->renewable.list.addToCompleteList(enabledCluster); - study->initializeRuntimeInfos(); // This should remove all disabled renewable clusters // Check that "Cluster1" isn't found - BOOST_CHECK_EQUAL(areaA->renewable.list.find("cluster1"), nullptr); + for (const auto c : areaA->renewable.list.each_enabled()) + BOOST_CHECK(c->name() != "Cluster1"); } BOOST_FIXTURE_TEST_CASE(short_term_storage_delete, OneAreaStudy) @@ -155,9 +159,9 @@ BOOST_FIXTURE_TEST_CASE(thermal_cluster_add, OneAreaStudy) BOOST_CHECK_EQUAL(newCluster->name(), "Cluster"); BOOST_CHECK_EQUAL(newCluster->id(), "cluster"); - areaA->thermal.list.add(newCluster); - BOOST_CHECK_EQUAL(areaA->thermal.list.find("cluster"), newCluster.get()); - BOOST_CHECK_EQUAL(areaA->thermal.list.find("Cluster"), nullptr); + areaA->thermal.list.addToCompleteList(newCluster); + BOOST_CHECK_EQUAL(areaA->thermal.list.findInAll("cluster"), newCluster.get()); + BOOST_CHECK_EQUAL(areaA->thermal.list.findInAll("Cluster"), nullptr); } /*! @@ -171,7 +175,7 @@ struct ThermalClusterStudy: public OneAreaStudy { auto newCluster = std::make_shared(areaA); newCluster->setName("Cluster"); - areaA->thermal.list.add(newCluster); + areaA->thermal.list.addToCompleteList(newCluster); cluster = newCluster.get(); } @@ -187,9 +191,10 @@ BOOST_FIXTURE_TEST_CASE(thermal_cluster_rename, ThermalClusterStudy) BOOST_FIXTURE_TEST_CASE(thermal_cluster_delete, ThermalClusterStudy) { - BOOST_CHECK(areaA->thermal.list.find("cluster") == cluster); + // gp : remove() only used in GUI (will go away when removing the GUI) + BOOST_CHECK(areaA->thermal.list.findInAll("cluster") == cluster); areaA->thermal.list.remove("cluster"); - BOOST_CHECK(areaA->thermal.list.find("cluster") == nullptr); + BOOST_CHECK(areaA->thermal.list.findInAll("cluster") == nullptr); BOOST_CHECK(areaA->thermal.list.empty()); } @@ -204,9 +209,9 @@ BOOST_FIXTURE_TEST_CASE(renewable_cluster_add, OneAreaStudy) BOOST_CHECK(newCluster->name() == "WindCluster"); BOOST_CHECK(newCluster->id() == "windcluster"); - areaA->renewable.list.add(newCluster); - BOOST_CHECK(areaA->renewable.list.find("windcluster") == newCluster.get()); - BOOST_CHECK(areaA->renewable.list.find("WindCluster") == nullptr); + areaA->renewable.list.addToCompleteList(newCluster); + BOOST_CHECK(areaA->renewable.list.findInAll("windcluster") == newCluster.get()); + BOOST_CHECK(areaA->renewable.list.findInAll("WindCluster") == nullptr); } @@ -222,7 +227,7 @@ struct RenewableClusterStudy : public OneAreaStudy areaA = study->areaAdd("A"); auto newCluster = std::make_shared(areaA); newCluster->setName("WindCluster"); - areaA->renewable.list.add(newCluster); + areaA->renewable.list.addToCompleteList(newCluster); cluster = newCluster.get(); } @@ -238,9 +243,10 @@ BOOST_FIXTURE_TEST_CASE(renewable_cluster_rename, RenewableClusterStudy) BOOST_FIXTURE_TEST_CASE(renewable_cluster_delete, RenewableClusterStudy) { - BOOST_CHECK(areaA->renewable.list.find("windcluster") == cluster); + // gp : remove() only used in GUI (will go away when removing the GUI) + BOOST_CHECK(areaA->renewable.list.findInAll("windcluster") == cluster); BOOST_CHECK(areaA->renewable.list.remove("windcluster")); - BOOST_CHECK(areaA->renewable.list.find("windcluster") == nullptr); + BOOST_CHECK(areaA->renewable.list.findInAll("windcluster") == nullptr); BOOST_CHECK(areaA->renewable.list.empty()); } diff --git a/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp b/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp index d905483254..23fe483e0c 100644 --- a/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp +++ b/src/tests/src/libs/antares/study/thermal-price-definition/thermal-price-definition.cpp @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_SUITE(s) BOOST_FIXTURE_TEST_CASE(ThermalClusterList_loadFromFolder_basic, FixtureFull) { clusterList.loadFromFolder(*study, folder, area); - auto cluster = clusterList.mapping["some cluster"]; + auto cluster = clusterList.findInAll("some cluster"); BOOST_CHECK(cluster->startupCost == 70000.0); BOOST_CHECK(cluster->costgeneration == useCostTimeseries); @@ -181,12 +181,10 @@ BOOST_FIXTURE_TEST_CASE(ThermalClusterList_loadFromFolder_basic, FixtureFull) BOOST_FIXTURE_TEST_CASE(checkCo2_checkCO2CostColumnNumber_OK, FixtureFull) { area->thermal.list.loadFromFolder(*study, folder, area); - auto cluster = area->thermal.list.mapping["some cluster"]; + auto cluster = area->thermal.list.findInAll("some cluster"); cluster->series.timeSeries.reset(3, 8760); - area->thermal.prepareAreaWideIndexes(); - auto& ecoInput = cluster->ecoInput; ecoInput.co2cost.reset(3, 8760); @@ -196,12 +194,10 @@ BOOST_FIXTURE_TEST_CASE(checkCo2_checkCO2CostColumnNumber_OK, FixtureFull) BOOST_FIXTURE_TEST_CASE(checkCo2_checkCO2CostColumnNumber_KO, FixtureFull) { area->thermal.list.loadFromFolder(*study, folder, area); - auto cluster = area->thermal.list.mapping["some cluster"]; + auto cluster = area->thermal.list.findInAll("some cluster"); cluster->series.timeSeries.reset(3, 8760); - area->thermal.prepareAreaWideIndexes(); - auto& ecoInput = cluster->ecoInput; ecoInput.co2cost.reset(2, 8760); @@ -212,12 +208,10 @@ BOOST_FIXTURE_TEST_CASE(checkCo2_checkCO2CostColumnNumber_KO, FixtureFull) BOOST_FIXTURE_TEST_CASE(checkFuelAndCo2_checkColumnNumber_OK, FixtureFull) { area->thermal.list.loadFromFolder(*study, folder, area); - auto cluster = area->thermal.list.mapping["some cluster"]; + auto cluster = area->thermal.list.findInAll("some cluster"); cluster->series.timeSeries.reset(3, 8760); - area->thermal.prepareAreaWideIndexes(); - cluster->ecoInput.fuelcost.reset(3, 8760); cluster->ecoInput.co2cost.reset(3, 8760); @@ -228,7 +222,7 @@ BOOST_FIXTURE_TEST_CASE(checkFuelAndCo2_checkColumnNumber_OK, FixtureFull) BOOST_FIXTURE_TEST_CASE(ThermalCluster_costGenManualCalculationOfMarketBidAndMarginalCostPerHour, FixtureFull) { clusterList.loadFromFolder(*study, folder, area); - auto cluster = clusterList.mapping["some cluster"]; + auto cluster = clusterList.findInAll("some cluster"); cluster->costgeneration = Data::setManually; cluster->ComputeCostTimeSeries(); @@ -243,11 +237,11 @@ BOOST_FIXTURE_TEST_CASE(ThermalCluster_costGenTimeSeriesCalculationOfMarketBidAn TimeSeriesFile co2("CO2Cost.txt", 8760); clusterList.loadFromFolder(*study, folder, area); - auto cluster = clusterList.mapping["some cluster"]; + auto cluster = clusterList.findInAll("some cluster"); cluster->modulation.reset(1, 8760); cluster->ecoInput.loadFromFolder(*study, folder); - fillThermalEconomicTimeSeries(cluster.get()); + fillThermalEconomicTimeSeries(cluster); cluster->ComputeCostTimeSeries(); @@ -258,7 +252,7 @@ BOOST_FIXTURE_TEST_CASE(ThermalCluster_costGenTimeSeriesCalculationOfMarketBidAn BOOST_FIXTURE_TEST_CASE(computeMarketBidCost, FixtureFull) { clusterList.loadFromFolder(*study, folder, area); - auto cluster = clusterList.mapping["some cluster"]; + auto cluster = clusterList.findInAll("some cluster"); BOOST_CHECK_CLOSE(cluster->computeMarketBidCost(1, 2, 1), 24.12, 0.001); } diff --git a/src/tests/src/solver/simulation/tests-ts-numbers.cpp b/src/tests/src/solver/simulation/tests-ts-numbers.cpp index 5791faaab3..e40fcbc8d5 100644 --- a/src/tests/src/solver/simulation/tests-ts-numbers.cpp +++ b/src/tests/src/solver/simulation/tests-ts-numbers.cpp @@ -71,15 +71,13 @@ void addClusterToAreaList(Area* area, std::shared_ptr cluster); template<> void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->thermal.clusters.push_back(cluster.get()); - area->thermal.list.add(cluster); - area->thermal.list.mapping[cluster->id()] = cluster; + area->thermal.list.addToCompleteList(cluster); } template<> void addClusterToAreaList(Area* area, std::shared_ptr cluster) { - area->renewable.list.add(cluster); + area->renewable.list.addToCompleteList(cluster); } template diff --git a/src/ui/action/handler/antares-study/area/create.cpp b/src/ui/action/handler/antares-study/area/create.cpp index 04950485bb..cc671fec5d 100644 --- a/src/ui/action/handler/antares-study/area/create.cpp +++ b/src/ui/action/handler/antares-study/area/create.cpp @@ -287,7 +287,7 @@ void Create::createActionsForAStandardAreaCopy(Context& ctx, bool copyPosition) auto* root = new RootNodePlant(pOriginalAreaName); // browsing each thermal cluster - for (auto& c : area->thermal.list) + for (auto c : area->thermal.list.all()) *root += StandardActionsToCopyThermalCluster(pOriginalAreaName, c->name()); *this += root; diff --git a/src/ui/action/handler/antares-study/thermal-cluster/create.cpp b/src/ui/action/handler/antares-study/thermal-cluster/create.cpp index 0eab4f280d..495d434d5f 100644 --- a/src/ui/action/handler/antares-study/thermal-cluster/create.cpp +++ b/src/ui/action/handler/antares-study/thermal-cluster/create.cpp @@ -80,7 +80,7 @@ bool Create::prepareWL(Context& ctx) if (suffix == "" || pInfos.behavior == bhMerge) { TransformNameIntoID(pFuturPlantName, id); - clusterFound = area ? area->thermal.list.find(id) : nullptr; + clusterFound = area ? area->thermal.list.findInAll(id) : nullptr; if (clusterFound) { Data::AreaName::Size sepPos = id.find_last_of('-'); @@ -101,7 +101,7 @@ bool Create::prepareWL(Context& ctx) pFuturPlantName.clear() << pTargetPlantName << "-" << indx; id.clear(); TransformNameIntoID(pFuturPlantName, id); - clusterFound = area->thermal.list.find(id); + clusterFound = area->thermal.list.findInAll(id); } while (clusterFound); } } @@ -109,13 +109,13 @@ bool Create::prepareWL(Context& ctx) { pFuturPlantName += suffix; TransformNameIntoID(pFuturPlantName, id); - clusterFound = area ? area->thermal.list.find(id) : nullptr; + clusterFound = area ? area->thermal.list.findInAll(id) : nullptr; } } else { TransformNameIntoID(pFuturPlantName, id); - clusterFound = area ? area->thermal.list.find(id) : nullptr; + clusterFound = area ? area->thermal.list.findInAll(id) : nullptr; } pInfos.caption.clear() << "Plant " << pFuturPlantName; @@ -161,7 +161,7 @@ bool Create::performWL(Context& ctx) if (!source) return false; TransformNameIntoID(pOriginalPlantName, id); - ctx.originalPlant = source->thermal.list.find(id); + ctx.originalPlant = source->thermal.list.findInAll(id); if (!ctx.originalPlant) return false; @@ -169,14 +169,13 @@ bool Create::performWL(Context& ctx) id.clear(); TransformNameIntoID(pFuturPlantName, id); - ctx.cluster = ctx.area->thermal.list.find(id); + ctx.cluster = ctx.area->thermal.list.findInAll(id); if (!ctx.cluster) { ctx.cluster = new Data::ThermalCluster(ctx.area); ctx.cluster->setName(pFuturPlantName); ctx.cluster->reset(); - (ctx.area)->thermal.list.add(std::shared_ptr(ctx.cluster)); - (ctx.area)->thermal.prepareAreaWideIndexes(); + (ctx.area)->thermal.list.addToCompleteList(std::shared_ptr(ctx.cluster)); } else { diff --git a/src/ui/action/handler/antares-study/thermal-cluster/root-node.cpp b/src/ui/action/handler/antares-study/thermal-cluster/root-node.cpp index 7dd40037e9..01b034da80 100644 --- a/src/ui/action/handler/antares-study/thermal-cluster/root-node.cpp +++ b/src/ui/action/handler/antares-study/thermal-cluster/root-node.cpp @@ -80,7 +80,7 @@ bool RootNode::performWL(Context& ctx) { // bool forcePlantCreate = ctx.clusterForceCreate[pOriginalAreaName]; if (pInfos.behavior == bhOverwrite) - ctx.area->thermal.list.clear(); + ctx.area->thermal.list.clearAll(); return true; } return false; diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.cpp index 3198c747c8..ebfe851030 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.cpp @@ -64,7 +64,7 @@ wxString RenewableClusterSummarySingleArea::columnCaption(int colIndx) const wxString RenewableClusterSummarySingleArea::cellValue(int x, int y) const { - Data::RenewableCluster* cluster = (pArea and (uint) y < pArea->renewable.list.size()) + Data::RenewableCluster* cluster = (pArea and (uint) y < pArea->renewable.list.allClustersCount()) ? pArea->renewable.list[y].get() : nullptr; switch (x) @@ -83,7 +83,7 @@ wxString RenewableClusterSummarySingleArea::cellValue(int x, int y) const double RenewableClusterSummarySingleArea::cellNumericValue(int x, int y) const { - Data::RenewableCluster* cluster = (pArea and (uint) y < pArea->renewable.list.size()) + Data::RenewableCluster* cluster = (pArea and (uint) y < pArea->renewable.list.allClustersCount()) ? pArea->renewable.list[y].get() : nullptr; // gp : do we wish to have the line empty if cluster disabled @@ -105,7 +105,7 @@ double RenewableClusterSummarySingleArea::cellNumericValue(int x, int y) const bool RenewableClusterSummarySingleArea::cellValue(int x, int y, const String& v) { - auto* cluster = (pArea and (uint) y < pArea->renewable.list.size()) + auto* cluster = (pArea and (uint) y < pArea->renewable.list.allClustersCount()) ? pArea->renewable.list[y].get() : nullptr; diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.h index 101c931279..3d277891d8 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/renewable.areasummary.h @@ -44,7 +44,7 @@ class RenewableClusterSummarySingleArea : public CommonClusterSummarySingleArea } virtual int height() const { - return (pArea) ? pArea->renewable.list.size() : 0; + return (pArea) ? pArea->renewable.list.allClustersCount() : 0; } virtual wxString columnCaption(int colIndx) const override; diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.cpp index 50cd2fcc64..15a233b38b 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.cpp @@ -75,7 +75,7 @@ wxString ThermalClusterSummarySingleArea::columnCaption(int colIndx) const wxString ThermalClusterSummarySingleArea::cellValue(int x, int y) const { - Data::ThermalCluster* cluster = (pArea and (uint) y < pArea->thermal.list.size()) + Data::ThermalCluster* cluster = (pArea and (uint) y < pArea->thermal.list.allClustersCount()) ? pArea->thermal.list[y].get() : nullptr; if (!cluster->enabled) @@ -118,7 +118,7 @@ wxString ThermalClusterSummarySingleArea::cellValue(int x, int y) const double ThermalClusterSummarySingleArea::cellNumericValue(int x, int y) const { - Data::ThermalCluster* cluster = (pArea and (uint) y < pArea->thermal.list.size()) + Data::ThermalCluster* cluster = (pArea and (uint) y < pArea->thermal.list.allClustersCount()) ? pArea->thermal.list[y].get() : nullptr; if (!cluster->enabled) @@ -161,7 +161,7 @@ double ThermalClusterSummarySingleArea::cellNumericValue(int x, int y) const bool ThermalClusterSummarySingleArea::cellValue(int x, int y, const String& v) { - auto* cluster = (pArea and (uint) y < pArea->thermal.list.size()) + auto* cluster = (pArea and (uint) y < pArea->thermal.list.allClustersCount()) ? pArea->thermal.list[y].get() : nullptr; diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.h b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.h index 049ec84c91..bb4bb0c3a5 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.h +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/area/thermal.areasummary.h @@ -44,7 +44,7 @@ class ThermalClusterSummarySingleArea : public CommonClusterSummarySingleArea } virtual int height() const override { - return (pArea) ? pArea->thermal.list.size() : 0; + return (pArea) ? pArea->thermal.list.allClustersCount() : 0; } virtual wxString columnCaption(int colIndx) const override; diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-renewable-renderer.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-renewable-renderer.cpp index 363fe97d72..50bd75bba1 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-renewable-renderer.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-renewable-renderer.cpp @@ -37,7 +37,7 @@ int renewableScBuilderRenderer::height() const { if (!(!study) && !(!pRules) && selectedArea()) { - return (int)selectedArea()->renewable.list.size(); + return (int)selectedArea()->renewable.list.allClustersCount(); } return 0; } @@ -45,7 +45,7 @@ int renewableScBuilderRenderer::height() const wxString renewableScBuilderRenderer::rowCaption(int rowIndx) const { if (!(!study) && !(!pRules) && selectedArea() - && (uint)rowIndx < selectedArea()->renewable.list.size()) + && (uint)rowIndx < selectedArea()->renewable.list.allClustersCount()) { return wxString() << wxT( " ") << wxStringFromUTF8(selectedArea()->renewable.list[rowIndx]->name()) @@ -57,7 +57,7 @@ wxString renewableScBuilderRenderer::rowCaption(int rowIndx) const bool renewableScBuilderRenderer::cellValue(int x, int y, const String& value) { if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears && selectedArea() - && (uint)y < selectedArea()->renewable.list.size()) + && (uint)y < selectedArea()->renewable.list.allClustersCount()) { assert(selectedArea()->index < pRules->areaCount()); assert((uint)y < pRules->renewable[selectedArea()->index].width()); @@ -73,7 +73,7 @@ bool renewableScBuilderRenderer::cellValue(int x, int y, const String& value) double renewableScBuilderRenderer::cellNumericValue(int x, int y) const { if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears && selectedArea() - && (uint)y < selectedArea()->renewable.list.size()) + && (uint)y < selectedArea()->renewable.list.allClustersCount()) { assert((uint)y < pRules->renewable[selectedArea()->index].width()); assert((uint)x < pRules->renewable[selectedArea()->index].height()); diff --git a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-thermal-renderer.cpp b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-thermal-renderer.cpp index 46ac844d89..c31d39e64e 100644 --- a/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-thermal-renderer.cpp +++ b/src/ui/simulator/toolbox/components/datagrid/renderer/scenario-builder-thermal-renderer.cpp @@ -37,7 +37,7 @@ int thermalScBuilderRenderer::height() const { if (!(!study) && !(!pRules) && selectedArea()) { - return (int)selectedArea()->thermal.list.size(); + return (int)selectedArea()->thermal.list.allClustersCount(); } return 0; } @@ -45,7 +45,7 @@ int thermalScBuilderRenderer::height() const wxString thermalScBuilderRenderer::rowCaption(int rowIndx) const { if (!(!study) && !(!pRules) && selectedArea() - && (uint)rowIndx < selectedArea()->thermal.list.size()) + && (uint)rowIndx < selectedArea()->thermal.list.allClustersCount()) { return wxString() << wxT(" ") << wxStringFromUTF8(selectedArea()->thermal.list[rowIndx]->name()) @@ -57,7 +57,7 @@ wxString thermalScBuilderRenderer::rowCaption(int rowIndx) const bool thermalScBuilderRenderer::cellValue(int x, int y, const String& value) { if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears && selectedArea() - && (uint)y < selectedArea()->thermal.list.size()) + && (uint)y < selectedArea()->thermal.list.allClustersCount()) { assert(selectedArea()->index < pRules->areaCount()); assert((uint)y < pRules->thermal[selectedArea()->index].width()); @@ -72,7 +72,7 @@ bool thermalScBuilderRenderer::cellValue(int x, int y, const String& value) double thermalScBuilderRenderer::cellNumericValue(int x, int y) const { if (!(!study) && !(!pRules) && (uint)x < study->parameters.nbYears && selectedArea() - && (uint)y < selectedArea()->thermal.list.size()) + && (uint)y < selectedArea()->thermal.list.allClustersCount()) { assert((uint)y < pRules->thermal[selectedArea()->index].width()); assert((uint)x < pRules->thermal[selectedArea()->index].height()); diff --git a/src/ui/simulator/toolbox/components/htmllistbox/datasource/renewable-cluster-order.cpp b/src/ui/simulator/toolbox/components/htmllistbox/datasource/renewable-cluster-order.cpp index 520b4d321a..3b3c7de962 100644 --- a/src/ui/simulator/toolbox/components/htmllistbox/datasource/renewable-cluster-order.cpp +++ b/src/ui/simulator/toolbox/components/htmllistbox/datasource/renewable-cluster-order.cpp @@ -47,16 +47,13 @@ void GetRenewableClusterMap(Data::Area* area, RenewableClusterMap& l, const wxSt { wxString grp; - const Data::RenewableClusterList::iterator end = area->renewable.list.end(); - for (Data::RenewableClusterList::iterator i = area->renewable.list.begin(); i != end; ++i) + for (auto cluster : area->renewable.list.all()) { - Data::RenewableCluster* cluster = i->get(); - if (search.empty()) { grp = wxStringFromUTF8(cluster->group()); grp.MakeLower(); - l[grp].push_back(cluster); + l[grp].push_back(cluster.get()); } } } diff --git a/src/ui/simulator/toolbox/components/htmllistbox/datasource/thermal-cluster-order.cpp b/src/ui/simulator/toolbox/components/htmllistbox/datasource/thermal-cluster-order.cpp index 3fc272246c..0570014053 100644 --- a/src/ui/simulator/toolbox/components/htmllistbox/datasource/thermal-cluster-order.cpp +++ b/src/ui/simulator/toolbox/components/htmllistbox/datasource/thermal-cluster-order.cpp @@ -47,16 +47,13 @@ void GetThermalClusterMap(Data::Area* area, ThermalClusterMap& l, const wxString { wxString grp; - const Data::ThermalClusterList::iterator end = area->thermal.list.end(); - for (Data::ThermalClusterList::iterator i = area->thermal.list.begin(); i != end; ++i) + for (auto cluster : area->thermal.list.all()) { - Data::ThermalCluster* cluster = i->get(); - if (search.empty()) { grp = wxStringFromUTF8(cluster->group()); grp.MakeLower(); - l[grp].push_back(cluster); + l[grp].push_back(cluster.get()); } } } diff --git a/src/ui/simulator/toolbox/components/map/manager.cpp b/src/ui/simulator/toolbox/components/map/manager.cpp index 5cb0857ea1..5809b757a9 100644 --- a/src/ui/simulator/toolbox/components/map/manager.cpp +++ b/src/ui/simulator/toolbox/components/map/manager.cpp @@ -758,11 +758,8 @@ void Manager::selectFromBoundingBox(const wxPoint& a, const wxPoint& b, const si j->first->selected(true); if (mouseSelectionPlants) { - Data::ThermalClusterList::iterator tend = area->thermal.list.end(); - for (Data::ThermalClusterList::iterator t = area->thermal.list.begin(); - t != tend; - ++t) - clusterlist.push_back((*t).get()); + for(auto cluster : area->thermal.list.all()) + clusterlist.push_back(cluster.get()); } continue; } diff --git a/src/ui/simulator/toolbox/input/area.cpp b/src/ui/simulator/toolbox/input/area.cpp index 3bb068f0d1..d364875a81 100644 --- a/src/ui/simulator/toolbox/input/area.cpp +++ b/src/ui/simulator/toolbox/input/area.cpp @@ -219,10 +219,10 @@ class SpotlightProviderArea final : public Component::Spotlight::IProvider if (0 != (equipment & Data::timeSeriesThermal)) { - if (area->thermal.list.size() > 0) + if (area->thermal.list.allClustersCount() > 0) { CString<32, false> text; - text << area->thermal.list.size(); + text << area->thermal.list.allClustersCount(); const uint8_t R_COLOR = 210; const uint8_t G_COLOR = 217; const uint8_t B_COLOR = 216; @@ -235,10 +235,10 @@ class SpotlightProviderArea final : public Component::Spotlight::IProvider } if (0 != (equipment & Data::timeSeriesRenewable)) { - if (area->renewable.list.size() > 0) + if (area->renewable.list.allClustersCount() > 0) { CString<32, false> text; - text << area->renewable.list.size(); + text << area->renewable.list.allClustersCount(); item->addRightTag(text, 210, 217, 216); } } diff --git a/src/ui/simulator/toolbox/input/renewable-cluster.cpp b/src/ui/simulator/toolbox/input/renewable-cluster.cpp index 2d7e713504..8f9c60b318 100644 --- a/src/ui/simulator/toolbox/input/renewable-cluster.cpp +++ b/src/ui/simulator/toolbox/input/renewable-cluster.cpp @@ -285,7 +285,6 @@ void RenewableCluster::internalDeletePlant(void*) Refresh(); MarkTheStudyAsModified(); updateInnerValues(); - pArea->renewable.prepareAreaWideIndexes(); study->uiinfo->reload(); } else @@ -367,7 +366,7 @@ void RenewableCluster::internalAddPlant(void*) // Trying to find an uniq name YString sFl; sFl.clear() << "new cluster"; - while (pArea->renewable.list.find(sFl)) + while (pArea->renewable.list.findInAll(sFl.c_str())) { ++indx; sFl.clear() << "new cluster " << indx; @@ -381,8 +380,7 @@ void RenewableCluster::internalAddPlant(void*) logs.info() << "adding new renewable cluster " << pArea->id << '.' << sFl; cluster->setName(sFl); cluster->reset(); - pArea->renewable.list.add(cluster); - pArea->renewable.prepareAreaWideIndexes(); + pArea->renewable.list.addToCompleteList(cluster); // Update the list update(); @@ -403,7 +401,7 @@ void RenewableCluster::internalClonePlant(void*) if (!pArea || !pLastSelectedRenewableCluster) return; - if (!pArea->renewable.list.find(pLastSelectedRenewableCluster->renewableAggregate()->id())) + if (!pArea->renewable.list.findInAll(pLastSelectedRenewableCluster->renewableAggregate()->id())) { // The selected has been obviously invalidated pLastSelectedRenewableCluster = nullptr; @@ -442,7 +440,7 @@ void RenewableCluster::internalClonePlant(void*) YString sFl; sFl << copy << indx; // lowercase - while (pArea->renewable.list.find(sFl)) + while (pArea->renewable.list.findInAll(sFl.c_str())) { ++indx; sFl.clear() << copy << indx; @@ -458,8 +456,7 @@ void RenewableCluster::internalClonePlant(void*) // Reset to default values cluster->copyFrom(selectedPlant); - pArea->renewable.list.add(cluster); - pArea->renewable.prepareAreaWideIndexes(); + pArea->renewable.list.addToCompleteList(cluster); // Update the list update(); diff --git a/src/ui/simulator/toolbox/input/thermal-cluster.cpp b/src/ui/simulator/toolbox/input/thermal-cluster.cpp index a520326cf8..8939dc7242 100644 --- a/src/ui/simulator/toolbox/input/thermal-cluster.cpp +++ b/src/ui/simulator/toolbox/input/thermal-cluster.cpp @@ -311,7 +311,6 @@ void ThermalCluster::internalDeletePlant(void*) Refresh(); MarkTheStudyAsModified(); updateInnerValues(); - pArea->thermal.prepareAreaWideIndexes(); study->uiinfo->reload(); // delete associated constraints @@ -426,7 +425,7 @@ void ThermalCluster::internalAddPlant(void*) // Trying to find an uniq name YString sFl; sFl.clear() << "new cluster"; - while (pArea->thermal.list.find(sFl)) + while (pArea->thermal.list.findInAll(sFl.c_str())) { ++indx; sFl.clear() << "new cluster " << indx; @@ -440,8 +439,7 @@ void ThermalCluster::internalAddPlant(void*) logs.info() << "adding new thermal cluster " << pArea->id << '.' << sFl; cluster->setName(sFl); cluster->reset(); - pArea->thermal.list.add(cluster); - pArea->thermal.prepareAreaWideIndexes(); + pArea->thermal.list.addToCompleteList(cluster); // Update the list update(); @@ -463,7 +461,7 @@ void ThermalCluster::internalClonePlant(void*) if (!pArea || !pLastSelectedThermalCluster) return; - if (!pArea->thermal.list.find(pLastSelectedThermalCluster->thermalAggregate()->id())) + if (!pArea->thermal.list.findInAll(pLastSelectedThermalCluster->thermalAggregate()->id())) { // The selected has been obviously invalidated pLastSelectedThermalCluster = nullptr; @@ -502,7 +500,7 @@ void ThermalCluster::internalClonePlant(void*) YString sFl; sFl << copy << indx; // lowercase - while (pArea->thermal.list.find(sFl)) + while (pArea->thermal.list.findInAll(sFl.c_str())) { ++indx; sFl.clear() << copy << indx; @@ -518,8 +516,7 @@ void ThermalCluster::internalClonePlant(void*) // Reset to default values cluster->copyFrom(selectedPlant); - pArea->thermal.list.add(cluster); - pArea->thermal.prepareAreaWideIndexes(); + pArea->thermal.list.addToCompleteList(cluster); // Update the list update(); diff --git a/src/ui/simulator/windows/inspector/frame.cpp b/src/ui/simulator/windows/inspector/frame.cpp index c62cf43001..e2a4770101 100644 --- a/src/ui/simulator/windows/inspector/frame.cpp +++ b/src/ui/simulator/windows/inspector/frame.cpp @@ -168,7 +168,7 @@ void Frame::onSelectAllPlants(wxCommandEvent&) for (auto i = data->areas.begin(); i != areaEnd; ++i) { Data::Area& area = *(*i); - for (auto& c : area.thermal.list) + for (auto c : area.thermal.list.all()) data->ThClusters.insert(c.get()); } data->areas.clear(); @@ -773,7 +773,7 @@ void Frame::apply(const InspectorData::Ptr& data) { const Data::Area& area = *(*i); nbLinks += (uint)area.links.size(); - nbThermalClusters += area.thermal.list.size(); + nbThermalClusters += area.thermal.list.allClustersCount(); } pPGAreaLinks->SetValueFromInt(nbLinks); pPGAreaPlants->SetValueFromInt(nbThermalClusters);