diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 31ef7126aa..fb605c1d1a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,12 @@ Antares Changelog ================= +# v8.6.6 (03/2024) +## Bugfixes +Adequacy patch CSR - fix DTG MRG (#1982) +Fix ts numbers for no gen clusters (#1969) +Remove unitcount limit for time series generation (#1960) + # v8.6.4 (11/2023) ## Bugfixes * Fix Oracle Linux minizip build + actually run zip unit tests (#1744) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da9c639cc6..df09cab06d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) # FetchContent_MakeAvailable # Version set(ANTARES_VERSION_HI 8) set(ANTARES_VERSION_LO 6) -set(ANTARES_VERSION_REVISION 5) +set(ANTARES_VERSION_REVISION 6) set(ANTARES_VERSION_YEAR 2024) project(antares diff --git a/src/libs/antares/study/parameters/adq-patch-params.cpp b/src/libs/antares/study/parameters/adq-patch-params.cpp index 584ff0f095..c51d554359 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.cpp +++ b/src/libs/antares/study/parameters/adq-patch-params.cpp @@ -176,7 +176,6 @@ bool AdqPatchParams::checkAdqPatchParams(const StudyMode studyMode, checkAdqPatchStudyModeEconomyOnly(studyMode); checkAdqPatchContainsAdqPatchArea(areas); checkAdqPatchIncludeHurdleCost(includeHurdleCostParameters); - checkAdqPatchDisabledLocalMatching(); return true; } @@ -205,11 +204,4 @@ void AdqPatchParams::checkAdqPatchIncludeHurdleCost(const bool includeHurdleCost if (curtailmentSharing.includeHurdleCost && !includeHurdleCostParameters) throw Error::IncompatibleHurdleCostCSR(); } - -void AdqPatchParams::checkAdqPatchDisabledLocalMatching() const -{ - if (!localMatching.enabled && curtailmentSharing.priceTakingOrder == AdqPatchPTO::isDens) - throw Error::AdqPatchDisabledLMR(); -} - -} // Antares::Data::AdequacyPatch +} // namespace Antares::Data::AdequacyPatch diff --git a/src/libs/antares/study/parameters/adq-patch-params.h b/src/libs/antares/study/parameters/adq-patch-params.h index 796e905837..66bfed70cf 100644 --- a/src/libs/antares/study/parameters/adq-patch-params.h +++ b/src/libs/antares/study/parameters/adq-patch-params.h @@ -11,7 +11,6 @@ using namespace Yuni; namespace Antares::Data::AdequacyPatch { - //! A default threshold value for initiate curtailment sharing rule const double defaultThresholdToRunCurtailmentSharing = 0.0; //! A default threshold value for display local matching rule violations @@ -60,7 +59,6 @@ enum class AdqPatchPTO }; // enum AdqPatchPTO - struct LocalMatching { bool enabled = true; @@ -73,12 +71,11 @@ struct LocalMatching //! rule. bool setToZeroOutsideOutsideLinks = true; /*! - ** \brief Reset to default values related to local matching - */ + ** \brief Reset to default values related to local matching + */ void reset(); bool updateFromKeyValue(const String& key, const String& value); void addProperties(IniFile::Section* section) const; - }; class CurtailmentSharing @@ -97,7 +94,9 @@ class CurtailmentSharing //! Check CSR cost function prior & after CSR optimization bool checkCsrCostFunction; - bool updateFromKeyValue(const String& key, const String& value); + bool recomputeDTGMRG = false; + + bool updateFromKeyValue(const Yuni::String& key, const Yuni::String& value); void addProperties(IniFile::Section* section) const; void reset(); @@ -106,10 +105,8 @@ class CurtailmentSharing void resetThresholds(); }; - struct AdqPatchParams { - bool enabled; LocalMatching localMatching; CurtailmentSharing curtailmentSharing; @@ -122,11 +119,9 @@ struct AdqPatchParams const AreaList& areas, const bool includeHurdleCostParameters) const; - void checkAdqPatchStudyModeEconomyOnly(const StudyMode studyMode) const; void checkAdqPatchContainsAdqPatchArea(const Antares::Data::AreaList& areas) const; void checkAdqPatchIncludeHurdleCost(const bool includeHurdleCost) const; - void checkAdqPatchDisabledLocalMatching() const; }; } // namespace Antares::Data::AdequacyPatch diff --git a/src/libs/antares/study/scenario-builder/TSnumberData.cpp b/src/libs/antares/study/scenario-builder/TSnumberData.cpp index 2b35738421..5235d74a3c 100644 --- a/src/libs/antares/study/scenario-builder/TSnumberData.cpp +++ b/src/libs/antares/study/scenario-builder/TSnumberData.cpp @@ -395,8 +395,6 @@ bool thermalTSNumberData::apply(Study& study) // WARNING: We may have some thermal clusters with the `mustrun` option auto clusterCount = (uint)area.thermal.clusterCount(); - const uint tsGenCountThermal = get_tsGenCount(study); - for (uint clusterIndex = 0; clusterIndex != clusterCount; ++clusterIndex) { auto& cluster = *(area.thermal.clusters[clusterIndex]); @@ -404,9 +402,13 @@ bool thermalTSNumberData::apply(Study& study) assert(clusterIndex < pTSNumberRules.width); const auto& col = pTSNumberRules[clusterIndex]; - logprefix.clear() << "Thermal: Area '" << area.name << "', cluster: '" << cluster.name() + uint tsGenCount = cluster.tsGenBehavior == LocalTSGenerationBehavior::forceNoGen ? + cluster.series->timeSeries.width : get_tsGenCount(study); + + 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, tsGenCount) && ret; + } return ret; } diff --git a/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp index 9bf0665d4b..d02c6ea7cd 100644 --- a/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp @@ -1,57 +1,35 @@ #include "adq_patch_post_process_list.h" #include "../post_process_commands.h" - namespace Antares::Solver::Simulation { - AdqPatchPostProcessList::AdqPatchPostProcessList(const AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, uint thread_number, AreaList& areas, SheddingPolicy sheddingPolicy, SimplexOptimization splxOptimization, - Calendar& calendar) - : interfacePostProcessList(problemeHebdo, thread_number) + Calendar& calendar) : + interfacePostProcessList(problemeHebdo, thread_number) { - post_process_list.push_back(std::make_unique( - problemeHebdo_, - thread_number_, - areas)); + post_process_list.push_back( + std::make_unique(problemeHebdo_, thread_number_, areas)); // Here a post process particular to adq patch post_process_list.push_back(std::make_unique( - adqPatchParams, - problemeHebdo_, - areas, - thread_number_)); - post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas, - false, - false)); + adqPatchParams, problemeHebdo_, areas, thread_number_)); + post_process_list.push_back( + std::make_unique(problemeHebdo_, areas, false, false)); post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas, - sheddingPolicy, - splxOptimization, - thread_number)); + problemeHebdo_, areas, sheddingPolicy, splxOptimization, thread_number)); // Here a post process particular to adq patch post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas, - thread_number)); - post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas, - true, - false)); - post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas, - calendar)); - post_process_list.push_back(std::make_unique( - problemeHebdo_, - areas)); + adqPatchParams, problemeHebdo_, areas, thread_number)); + post_process_list.push_back( + std::make_unique(problemeHebdo_, areas, true, false)); + post_process_list.push_back( + std::make_unique(problemeHebdo_, areas, calendar)); + post_process_list.push_back( + std::make_unique(problemeHebdo_, areas)); } -} // namespace Antares::Solver::Simulation \ No newline at end of file +} // namespace Antares::Solver::Simulation diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp index 170de3df36..16f36bc7bc 100644 --- a/src/solver/optimisation/post_process_commands.cpp +++ b/src/solver/optimisation/post_process_commands.cpp @@ -1,3 +1,23 @@ +/* +** Copyright 2007-2024, RTE (https://www.rte-france.com) +** See AUTHORS.txt +** SPDX-License-Identifier: MPL-2.0 +** This file is part of Antares-Simulator, +** Adequacy and Performance assessment for interconnected energy networks. +** +** Antares_Simulator is free software: you can redistribute it and/or modify +** it under the terms of the Mozilla Public Licence 2.0 as published by +** the Mozilla Foundation, either version 2 of the License, or +** (at your option) any later version. +** +** Antares_Simulator is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** Mozilla Public Licence 2.0 for more details. +** +** You should have received a copy of the Mozilla Public Licence 2.0 +** along with Antares_Simulator. If not, see . +*/ #include "post_process_commands.h" #include "../simulation/common-eco-adq.h" @@ -105,10 +125,14 @@ void RemixHydroPostProcessCmd::execute(const optRuntimeData& opt_runtime_data) using namespace Antares::Data::AdequacyPatch; DTGmarginForAdqPatchPostProcessCmd::DTGmarginForAdqPatchPostProcessCmd( + const AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, AreaList& areas, unsigned int thread_number) : - basePostProcessCommand(problemeHebdo), area_list_(areas), thread_number_(thread_number) + basePostProcessCommand(problemeHebdo), + adqPatchParams_(adqPatchParams), + area_list_(areas), + thread_number_(thread_number) { } @@ -136,8 +160,11 @@ void DTGmarginForAdqPatchPostProcessCmd::execute(const optRuntimeData&) // calculate DTG MRG CSR and adjust ENS if neccessary if (problemeHebdo_->adequacyPatchRuntimeData->wasCSRTriggeredAtAreaHour(Area, hour)) { - dtgMrgCsr = std::max(0.0, dtgMrg - ens); - ens = std::max(0.0, ens - dtgMrg); + if (adqPatchParams_.curtailmentSharing.recomputeDTGMRG) + { + dtgMrgCsr = std::max(0.0, dtgMrg - ens); + ens = std::max(0.0, ens - dtgMrg); + } // set MRG PRICE to value of unsupplied energy cost, if LOLD=1.0 (ENS>0.5) if (ens > 0.5) mrgCost = -area_list_[Area]->thermal.unsuppliedEnergyCost; @@ -190,8 +217,8 @@ CurtailmentSharingPostProcessCmd::CurtailmentSharingPostProcessCmd(const AdqPatc AreaList& areas, unsigned int thread_number) : basePostProcessCommand(problemeHebdo), + area_list_(areas), adqPatchParams_(adqPatchParams), - area_list_(areas), thread_number_(thread_number) { } @@ -225,11 +252,11 @@ double CurtailmentSharingPostProcessCmd::calculateDensNewAndTotalLmrViolation() { for (uint hour = 0; hour < nbHoursInWeek; hour++) { - const auto [netPositionInit, densNew, totalNodeBalance] - = calculateAreaFlowBalance(problemeHebdo_, - adqPatchParams_.localMatching.setToZeroOutsideInsideLinks, - Area, - hour); + const auto [netPositionInit, densNew, totalNodeBalance] = calculateAreaFlowBalance( + problemeHebdo_, + adqPatchParams_.localMatching.setToZeroOutsideInsideLinks, + Area, + hour); // adjust densNew according to the new specification/request by ELIA /* DENS_new (node A) = max [ 0; ENS_init (node A) + net_position_init (node A) + ? flows (node 1 -> node A) - DTG.MRG(node A)] */ @@ -245,10 +272,11 @@ double CurtailmentSharingPostProcessCmd::calculateDensNewAndTotalLmrViolation() .ValeursHorairesDeDefaillanceNegative[hour]; // check LMR violations totalLmrViolation += LmrViolationAreaHour( - problemeHebdo_, - totalNodeBalance, - adqPatchParams_.curtailmentSharing.thresholdDisplayViolations, - Area, hour); + problemeHebdo_, + totalNodeBalance, + adqPatchParams_.curtailmentSharing.thresholdDisplayViolations, + Area, + hour); } } } diff --git a/src/solver/optimisation/post_process_commands.h b/src/solver/optimisation/post_process_commands.h index d04daf02ce..4a58237bb2 100644 --- a/src/solver/optimisation/post_process_commands.h +++ b/src/solver/optimisation/post_process_commands.h @@ -51,14 +51,18 @@ class RemixHydroPostProcessCmd : public basePostProcessCommand class DTGmarginForAdqPatchPostProcessCmd : public basePostProcessCommand { + using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; + public: - DTGmarginForAdqPatchPostProcessCmd(PROBLEME_HEBDO* problemeHebdo, + DTGmarginForAdqPatchPostProcessCmd(const AdqPatchParams& adqPatchParams, + PROBLEME_HEBDO* problemeHebdo, AreaList& areas, unsigned int thread_number); void execute(const optRuntimeData& opt_runtime_data) override; private: + const AdqPatchParams& adqPatchParams_; const AreaList& area_list_; unsigned int thread_number_ = 0; }; @@ -91,6 +95,7 @@ class HydroLevelsFinalUpdatePostProcessCmd : public basePostProcessCommand class CurtailmentSharingPostProcessCmd : public basePostProcessCommand { using AdqPatchParams = Antares::Data::AdequacyPatch::AdqPatchParams; + public: CurtailmentSharingPostProcessCmd(const AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index b0f069ea73..5ee965c913 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -94,7 +94,6 @@ class GeneratorTempData final private: uint nbHoursPerYear; - const uint daysPerYear; MersenneTwister& rndgenerator; @@ -125,9 +124,8 @@ class GeneratorTempData final double bp[366]; - double FPOW[366][102]; - - double PPOW[366][102]; + std::vector> FPOW; + std::vector> PPOW; String pTempFilename; @@ -141,7 +139,6 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, IResultWriter::Ptr writer) : study(study), nbHoursPerYear(study.runtime->nbHoursPerYear), - daysPerYear(study.runtime->nbDaysPerYear), rndgenerator(study.runtime->random[Data::seedTsGenThermal]), pProgression(progr), pWriter(writer) @@ -153,6 +150,9 @@ GeneratorTempData::GeneratorTempData(Data::Study& study, nbThermalTimeseries = parameters.nbTimeSeriesThermal; derated = parameters.derated; + + FPOW.resize(DAYS_PER_YEAR); + PPOW.resize(DAYS_PER_YEAR); } void GeneratorTempData::writeResultsToDisk(const Data::Area& area, @@ -191,7 +191,7 @@ void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, { case Data::thermalLawUniform: { - for (uint d = 0; d < daysPerYear; ++d) + for (uint d = 0; d < DAYS_PER_YEAR; ++d) { double D = (double)duration[d]; double xtemp = volatility * (D - 1.); @@ -202,7 +202,7 @@ void GeneratorTempData::prepareIndispoFromLaw(Data::ThermalLaw law, } case Data::thermalLawGeometric: { - for (uint d = 0; d < daysPerYear; ++d) + for (uint d = 0; d < DAYS_PER_YEAR; ++d) { double D = (double)duration[d]; double xtemp = volatility * volatility * D * (D - 1.); @@ -312,8 +312,11 @@ void GeneratorTempData::operator()(Data::Area& area, Data::ThermalCluster& clust int FOD_reel = 0; int POD_reel = 0; - for (uint d = 0; d < daysPerYear; ++d) + for (uint d = 0; d < DAYS_PER_YEAR; ++d) { + FPOW[d].resize(cluster.unitCount + 1); + PPOW[d].resize(cluster.unitCount + 1); + PODOfTheDay = (int)POD[d]; FODOfTheDay = (int)FOD[d]; @@ -385,9 +388,8 @@ void GeneratorTempData::operator()(Data::Area& area, Data::ThermalCluster& clust if (tsIndex > 1) dstSeries = &cluster.series->timeSeries[tsIndex - 2]; - for (uint dayInTheYear = 0; dayInTheYear < daysPerYear; ++dayInTheYear) + for (uint dayInTheYear = 0; dayInTheYear < DAYS_PER_YEAR; ++dayInTheYear) { - assert(AUN <= 100 and "Thermal Prepro: AUN is out of bounds (>=100)"); assert(dayInTheYear < 366); assert(not(lf[dayInTheYear] < 0.)); assert(not(lp[dayInTheYear] < 0.)); 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 9268bab171..c9fd0f06b0 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 @@ -385,5 +385,4 @@ BOOST_AUTO_TEST_CASE(on_link_area2_area3_and_on_year_19__ntc_TS_number_6_is_chos BOOST_CHECK(my_rule.apply()); BOOST_CHECK_EQUAL(link_23->timeseriesNumbers[0][yearNumber.to()], tsNumber.to() - 1); } - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/tests/src/solver/optimisation/adequacy_patch.cpp b/src/tests/src/solver/optimisation/adequacy_patch.cpp index 6ae3c2867c..44a0935ab1 100644 --- a/src/tests/src/solver/optimisation/adequacy_patch.cpp +++ b/src/tests/src/solver/optimisation/adequacy_patch.cpp @@ -502,7 +502,6 @@ BOOST_AUTO_TEST_CASE(check_valid_adq_param) auto p = createParams(); BOOST_CHECK_NO_THROW(p.checkAdqPatchStudyModeEconomyOnly(Antares::Data::stdmEconomy)); BOOST_CHECK_NO_THROW(p.checkAdqPatchIncludeHurdleCost(true)); - BOOST_CHECK_NO_THROW(p.checkAdqPatchDisabledLocalMatching()); } BOOST_AUTO_TEST_CASE(check_adq_param_wrong_mode) @@ -517,10 +516,3 @@ BOOST_AUTO_TEST_CASE(check_adq_param_wrong_hurdle_cost) auto p = createParams(); BOOST_CHECK_THROW(p.checkAdqPatchIncludeHurdleCost(false), Error::IncompatibleHurdleCostCSR); } - -BOOST_AUTO_TEST_CASE(check_adq_param_wrong_lmr_disabled) -{ - auto p = createParams(); - p.localMatching.enabled = false; - BOOST_CHECK_THROW(p.checkAdqPatchDisabledLocalMatching(), Error::AdqPatchDisabledLMR); -}