From 2b977e1e07a4b594c3d1f881a46b0ca2ba8fdcbc Mon Sep 17 00:00:00 2001 From: payetvin <113102157+payetvin@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:32:13 +0100 Subject: [PATCH] Remove numspace from hydro management (#1730) - Extracted random number generation from HydroManagement, which was unrelated - Have one instance of HydroManagement for each MC year, to get rid of the space-indexed containers --- src/solver/hydro/management/daily.cpp | 4 +- src/solver/hydro/management/management.cpp | 151 ++++++++---------- src/solver/hydro/management/management.h | 47 +++--- src/solver/hydro/management/monthly.cpp | 6 +- src/solver/simulation/adequacy.cpp | 8 +- src/solver/simulation/adequacy.h | 4 +- src/solver/simulation/economy.cpp | 2 +- src/solver/simulation/economy.h | 2 +- .../simulation/sim_calcul_economique.cpp | 8 +- src/solver/simulation/simulation.h | 2 +- src/solver/simulation/solver.h | 5 +- src/solver/simulation/solver.hxx | 44 ++--- 12 files changed, 132 insertions(+), 151 deletions(-) diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index f28b9600ac..d3051fac27 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -231,7 +231,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St auto const srcinflows = area.hydro.series->storage.getColumn(y); - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; auto& scratchpad = area.scratchpad[numSpace]; @@ -250,7 +250,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St auto const& maxP = maxPower[Data::PartHydro::genMaxP]; auto const& maxE = maxPower[Data::PartHydro::genMaxE]; - auto& ventilationResults = ventilationResults_[numSpace][z]; + auto& ventilationResults = ventilationResults_[z]; std::shared_ptr debugData(nullptr); diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 853caf5d2d..785961f750 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -40,14 +40,43 @@ using namespace Yuni; namespace Antares { -double HydroManagement::GammaVariable(double r) +namespace Solver +{ + +double randomReservoirLevel(double min, double avg, double max, MersenneTwister& random) +{ + if (Math::Equals(min, max)) + return avg; + if (Math::Equals(avg, min) || Math::Equals(avg, max)) + return avg; + + double e = (avg - min) / (max - min); + double re = 1. - e; + + assert(Math::Abs(1. + e) > 1e-12); + assert(Math::Abs(2. - e) > 1e-12); + + double v1 = (e * e) * re / (1. + e); + double v2 = e * re * re / (2. - e); + double v = Math::Min(v1, v2) * .5; + + assert(Math::Abs(v) > 1e-12); + + double a = e * (e * re / v - 1.); + double b = re * (e * re / v - 1.); + + double x = BetaVariable(a, b, random); + return x * max + (1. - x) * min; +} + +double GammaVariable(double r, MersenneTwister &random) { double x = 0.; do { double s = r - 1.; - double u = random_(); - double v = random_(); + double u = random(); + double v = random(); double w = u * (1. - u); assert(Math::Abs(w) > 1e-12); assert(3. * (r - 0.25) / w > 0.); @@ -70,14 +99,16 @@ double HydroManagement::GammaVariable(double r) return x; } -inline double HydroManagement::BetaVariable(double a, double b) +double BetaVariable(double a, double b, MersenneTwister &random) { - double y = GammaVariable(a); - double z = GammaVariable(b); + double y = GammaVariable(a, random); + double z = GammaVariable(b, random); assert(Math::Abs(y + z) > 1e-12); return y / (y + z); } +} // namespace Solver + HydroManagement::HydroManagement(const Data::AreaList& areas, const Data::Parameters& params, const Date::Calendar& calendar, @@ -89,42 +120,25 @@ HydroManagement::HydroManagement(const Data::AreaList& areas, maxNbYearsInParallel_(maxNbYearsInParallel), resultWriter_(resultWriter) { - tmpDataByArea_ = new TmpDataByArea* [maxNbYearsInParallel_]; - for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) - tmpDataByArea_[numSpace] = new TmpDataByArea[areas_.size()]; - - random_.reset(parameters_.seed[Data::seedHydroManagement]); - // Ventilation results memory allocation uint nbDaysPerYear = 365; - ventilationResults_.resize(maxNbYearsInParallel_); - for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) + ventilationResults_.resize(areas_.size()); + for (uint areaIndex = 0; areaIndex < areas_.size(); ++areaIndex) { - ventilationResults_[numSpace].resize(areas_.size()); - for (uint areaIndex = 0; areaIndex < areas_.size(); ++areaIndex) - { - auto& area = *areas_.byIndex[areaIndex]; - size_t clusterCount = area.thermal.clusterCount(); + auto& area = *areas_.byIndex[areaIndex]; + size_t clusterCount = area.thermal.clusterCount(); - ventilationResults_[numSpace][areaIndex].HydrauliqueModulableQuotidien.assign(nbDaysPerYear, 0); + ventilationResults_[areaIndex].HydrauliqueModulableQuotidien.assign(nbDaysPerYear, 0); - if (area.hydro.reservoirManagement) - { - ventilationResults_[numSpace][areaIndex].NiveauxReservoirsDebutJours.assign(nbDaysPerYear, 0.); - ventilationResults_[numSpace][areaIndex].NiveauxReservoirsFinJours.assign(nbDaysPerYear, 0.); - } + if (area.hydro.reservoirManagement) + { + ventilationResults_[areaIndex].NiveauxReservoirsDebutJours.assign(nbDaysPerYear, 0.); + ventilationResults_[areaIndex].NiveauxReservoirsFinJours.assign(nbDaysPerYear, 0.); } } } -HydroManagement::~HydroManagement() -{ - for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) - delete[] tmpDataByArea_[numSpace]; - delete[] tmpDataByArea_; -} - -void HydroManagement::prepareInflowsScaling(uint numSpace, uint year) +void HydroManagement::prepareInflowsScaling(uint year) { areas_.each([&](const Data::Area& area) { @@ -132,7 +146,7 @@ void HydroManagement::prepareInflowsScaling(uint numSpace, uint year) auto const& srcinflows = area.hydro.series->storage.getColumn(year); - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; double totalYearInflows = 0.0; for (uint month = 0; month != 12; ++month) @@ -172,14 +186,14 @@ void HydroManagement::prepareInflowsScaling(uint numSpace, uint year) }); } -void HydroManagement::minGenerationScaling(uint numSpace, uint year) const +void HydroManagement::minGenerationScaling(uint year) { - areas_.each([this, &numSpace, &year](const Data::Area& area) + areas_.each([this, &year](const Data::Area& area) { auto const& srcmingen = area.hydro.series->mingen.getColumn(year); uint z = area.index; - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; double totalYearMingen = 0.0; for (uint month = 0; month != 12; ++month) @@ -228,9 +242,9 @@ void HydroManagement::minGenerationScaling(uint numSpace, uint year) const }); } -bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const +bool HydroManagement::checkMonthlyMinGeneration(uint year, const Data::Area& area) const { - const auto& data = tmpDataByArea_[numSpace][area.index]; + const auto& data = tmpDataByArea_[area.index]; for (uint month = 0; month != 12; ++month) { uint realmonth = calendar_.months[month].realmonth; @@ -248,9 +262,9 @@ bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint year, const return true; } -bool HydroManagement::checkYearlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const +bool HydroManagement::checkYearlyMinGeneration(uint year, const Data::Area& area) const { - const auto& data = tmpDataByArea_[numSpace][area.index]; + const auto& data = tmpDataByArea_[area.index]; if (data.totalYearMingen > data.totalYearInflows) { // Yearly minimum generation <= Yearly inflows @@ -334,10 +348,10 @@ bool HydroManagement::checkHourlyMinGeneration(uint year, const Data::Area& area return true; } -bool HydroManagement::checkMinGeneration(uint numSpace, uint year) const +bool HydroManagement::checkMinGeneration(uint year) const { bool ret = true; - areas_.each([this, &numSpace, &ret, &year](const Data::Area& area) + areas_.each([this, &ret, &year](const Data::Area& area) { bool useHeuristicTarget = area.hydro.useHeuristicTarget; bool followLoadModulations = area.hydro.followLoadModulations; @@ -355,9 +369,9 @@ bool HydroManagement::checkMinGeneration(uint numSpace, uint year) const } if (reservoirManagement) - ret = checkYearlyMinGeneration(numSpace, year, area) && ret; + ret = checkYearlyMinGeneration(year, area) && ret; else - ret = checkMonthlyMinGeneration(numSpace, year, area) && ret; + ret = checkMonthlyMinGeneration(year, area) && ret; }); return ret; } @@ -372,7 +386,7 @@ void HydroManagement::prepareNetDemand(uint numSpace, uint year, Data::StudyMode const auto& rormatrix = area.hydro.series->ror; const auto* ror = rormatrix.getColumn(year); - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; const double* loadSeries = area.load.series.getColumn(year); const double* windSeries = area.wind.series.getColumn(year); const double* solarSeries = area.solar.series.getColumn(year); @@ -414,12 +428,12 @@ void HydroManagement::prepareNetDemand(uint numSpace, uint year, Data::StudyMode }); } -void HydroManagement::prepareEffectiveDemand(uint numSpace) +void HydroManagement::prepareEffectiveDemand() { areas_.each([&](Data::Area& area) { auto z = area.index; - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; for (uint day = 0; day != 365; ++day) { @@ -429,7 +443,7 @@ void HydroManagement::prepareEffectiveDemand(uint numSpace) double effectiveDemand = 0; area.hydro.allocation.eachNonNull([&](unsigned areaindex, double value) { - effectiveDemand += (tmpDataByArea_[numSpace][areaindex]).DLN[day] * value; + effectiveDemand += (tmpDataByArea_[areaindex]).DLN[day] * value; }); assert(!Math::NaN(effectiveDemand) && "nan value detected for effectiveDemand"); @@ -476,50 +490,25 @@ void HydroManagement::prepareEffectiveDemand(uint numSpace) }); } -double HydroManagement::randomReservoirLevel(double min, double avg, double max) -{ - if (Math::Equals(min, max)) - return avg; - if (Math::Equals(avg, min) || Math::Equals(avg, max)) - return avg; - - double e = (avg - min) / (max - min); - double re = 1. - e; - - assert(Math::Abs(1. + e) > 1e-12); - assert(Math::Abs(2. - e) > 1e-12); - - double v1 = (e * e) * re / (1. + e); - double v2 = e * re * re / (2. - e); - double v = Math::Min(v1, v2) * .5; - - assert(Math::Abs(v) > 1e-12); - - double a = e * (e * re / v - 1.); - double b = re * (e * re / v - 1.); - - double x = BetaVariable(a, b); - return x * max + (1. - x) * min; -} - void HydroManagement::makeVentilation(double* randomReservoirLevel, Solver::Variable::State& state, uint y, uint numSpace) { - memset(tmpDataByArea_[numSpace], 0, sizeof(TmpDataByArea) * areas_.size()); + tmpDataByArea_.resize(areas_.size()); + memset(tmpDataByArea_.data(), 0, sizeof(TmpDataByArea) * areas_.size()); - prepareInflowsScaling(numSpace, y); - minGenerationScaling(numSpace, y); - if (!checkMinGeneration(numSpace, y)) + prepareInflowsScaling(y); + minGenerationScaling(y); + if (!checkMinGeneration(y)) { throw FatalError("hydro management: invalid minimum generation"); } prepareNetDemand(numSpace, y, parameters_.mode); - prepareEffectiveDemand(numSpace); + prepareEffectiveDemand(); - prepareMonthlyOptimalGenerations(randomReservoirLevel, y, numSpace); + prepareMonthlyOptimalGenerations(randomReservoirLevel, y); prepareDailyOptimalGenerations(state, y, numSpace); } diff --git a/src/solver/hydro/management/management.h b/src/solver/hydro/management/management.h index 90bb8d0f24..909da320c8 100644 --- a/src/solver/hydro/management/management.h +++ b/src/solver/hydro/management/management.h @@ -40,6 +40,11 @@ namespace Variable { class State; } + +double randomReservoirLevel(double min, double avg, double max, MersenneTwister& random); +double BetaVariable(double a, double b, MersenneTwister &random); +double GammaVariable(double a, MersenneTwister &random); + } // namespace Solver enum @@ -94,8 +99,7 @@ typedef struct //de jour (en cas de gestion des reservoirs). } VENTILATION_HYDRO_RESULTS_BY_AREA; -// vector of [numSpace][area] -using ALL_HYDRO_VENTILATION_RESULTS = std::vector>; +using HYDRO_VENTILATION_RESULTS = std::vector; class HydroManagement final @@ -107,39 +111,35 @@ class HydroManagement final unsigned int maxNbYearsInParallel, Solver::IResultWriter& resultWriter); - ~HydroManagement(); - - double randomReservoirLevel(double min, double avg, double max); - //! Perform the hydro ventilation void makeVentilation(double* randomReservoirLevel, - Solver::Variable::State& state, - uint y, - uint numSpace); + Solver::Variable::State& state, + uint y, + uint numSpace); - ALL_HYDRO_VENTILATION_RESULTS& ventilationResults() { return ventilationResults_; } + const HYDRO_VENTILATION_RESULTS& ventilationResults() { return ventilationResults_; } private: //! Prepare inflows scaling for each area - void prepareInflowsScaling(uint numSpace, uint year); + void prepareInflowsScaling(uint year); //! Prepare minimum generation scaling for each area - void minGenerationScaling(uint numSpace, uint year) const; + void minGenerationScaling(uint year); //! check Monthly minimum generation is lower than available inflows - bool checkMonthlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const; + bool checkMonthlyMinGeneration(uint year, const Data::Area& area) const; //! check Yearly minimum generation is lower than available inflows - bool checkYearlyMinGeneration(uint numSpace, uint year, const Data::Area& area) const; + bool checkYearlyMinGeneration(uint year, const Data::Area& area) const; //! check Weekly minimum generation is lower than available inflows bool checkWeeklyMinGeneration(uint year, const Data::Area& area) const; //! check Hourly minimum generation is lower than available inflows bool checkHourlyMinGeneration(uint year, const Data::Area& area) const; //! check minimum generation is lower than available inflows - bool checkMinGeneration(uint numSpace, uint year) const; + bool checkMinGeneration(uint year) const; //! Prepare the net demand for each area void prepareNetDemand(uint numSpace, uint year, Data::StudyMode mode); //! Prepare the effective demand for each area - void prepareEffectiveDemand(uint numSpace); + void prepareEffectiveDemand(); //! Monthly Optimal generations - void prepareMonthlyOptimalGenerations(double* random_reservoir_level, uint y, uint numSpace); + void prepareMonthlyOptimalGenerations(double* random_reservoir_level, uint y); //! Monthly target generations // note: inflows may have two different types, if in swap mode or not @@ -154,26 +154,17 @@ class HydroManagement final Data::Area& area, uint y, uint numSpace); - //@} - //! \name Utilities - //@{ - //! Beta variable - double BetaVariable(double a, double b); - //! Gamma variable - double GammaVariable(double a); - //@} private: - TmpDataByArea** tmpDataByArea_; + std::vector tmpDataByArea_; const Data::AreaList& areas_; const Date::Calendar& calendar_; const Data::Parameters& parameters_; - MersenneTwister random_; unsigned int maxNbYearsInParallel_ = 0; Solver::IResultWriter& resultWriter_; - ALL_HYDRO_VENTILATION_RESULTS ventilationResults_; + HYDRO_VENTILATION_RESULTS ventilationResults_; }; // class HydroManagement } // namespace Antares diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index c526916f4e..9c2ead7927 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -142,15 +142,13 @@ double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDat return total; } -void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_level, - uint y, - uint numSpace) +void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_level, uint y) { uint indexArea = 0; areas_.each([&](Data::Area& area) { uint z = area.index; - auto& data = tmpDataByArea_[numSpace][z]; + auto& data = tmpDataByArea_[z]; auto& minLvl = area.hydro.reservoirLevel[Data::PartHydro::minimum]; auto& maxLvl = area.hydro.reservoirLevel[Data::PartHydro::maximum]; diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 73e11c3ffa..0d311813a7 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -95,7 +95,7 @@ bool Adequacy::simulationBegin() bool Adequacy::simplexIsRequired(uint hourInTheYear, uint numSpace, - const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) const + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) const { uint areaCount = study.areas.size(); uint indx = hourInTheYear; @@ -106,7 +106,7 @@ bool Adequacy::simplexIsRequired(uint hourInTheYear, for (uint areaIdx = 0; areaIdx != areaCount; ++areaIdx) { - auto& hydroVentilation = hydroVentilationResults[numSpace][areaIdx]; + auto& hydroVentilation = hydroVentilationResults[areaIdx]; double quantity = pProblemesHebdo[numSpace].ConsommationsAbattues[j].ConsommationAbattueDuPays[areaIdx] @@ -126,7 +126,7 @@ bool Adequacy::year(Progression::Task& progression, yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults, + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults, OptimizationStatisticsWriter& optWriter) { // No failed week at year start @@ -293,7 +293,7 @@ bool Adequacy::year(Progression::Task& progression, { assert(k < state.resSpilled.width); assert(j < state.resSpilled.height); - auto& hydroVentilation = hydroVentilationResults[numSpace][k]; + auto& hydroVentilation = hydroVentilationResults[k]; auto& hourlyResults = pProblemesHebdo[numSpace].ResultatsHoraires[k]; hourlyResults.TurbinageHoraire[j] diff --git a/src/solver/simulation/adequacy.h b/src/solver/simulation/adequacy.h index 8832670f1a..70807a880a 100644 --- a/src/solver/simulation/adequacy.h +++ b/src/solver/simulation/adequacy.h @@ -82,7 +82,7 @@ class Adequacy yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const ALL_HYDRO_VENTILATION_RESULTS&, + const HYDRO_VENTILATION_RESULTS&, OptimizationStatisticsWriter& optWriter); void incrementProgression(Progression::Task& progression); @@ -99,7 +99,7 @@ class Adequacy private: bool simplexIsRequired(uint hourInTheYear, uint numSpace, - const ALL_HYDRO_VENTILATION_RESULTS&) const; + const HYDRO_VENTILATION_RESULTS&) const; uint pNbWeeks; uint pStartTime; diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 8a20964ad0..85effa779a 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -121,7 +121,7 @@ bool Economy::year(Progression::Task& progression, yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults, + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults, OptimizationStatisticsWriter& optWriter) { // No failed week at year start diff --git a/src/solver/simulation/economy.h b/src/solver/simulation/economy.h index 7eb8c174f5..29741f7646 100644 --- a/src/solver/simulation/economy.h +++ b/src/solver/simulation/economy.h @@ -83,7 +83,7 @@ class Economy yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const ALL_HYDRO_VENTILATION_RESULTS&, + const HYDRO_VENTILATION_RESULTS&, OptimizationStatisticsWriter& optWriter); void incrementProgression(Progression::Task& progression); diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index 0183ee82e5..aebc31d233 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -395,7 +395,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, uint weekInTheYear, uint numSpace, const int PasDeTempsDebut, - const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) + const HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { const auto& parameters = study.parameters; auto& studyruntime = *study.runtime; @@ -689,7 +689,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, .MinEnergieHydrauParIntervalleOptimise; const std::vector& DNT - = hydroVentilationResults[numSpace][k].HydrauliqueModulableQuotidien; + = hydroVentilationResults[k].HydrauliqueModulableQuotidien; double WSL = problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir; @@ -778,7 +778,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, for (uint j = 0; j < 7; ++j) { uint day = study.calendar.hours[PasDeTempsDebut + j * 24].dayYear; - weekTarget_tmp += hydroVentilationResults[numSpace][k] + weekTarget_tmp += hydroVentilationResults[k] .HydrauliqueModulableQuotidien[day]; } @@ -799,7 +799,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, uint day = study.calendar.hours[PasDeTempsDebut + j * 24].dayYear; problem.CaracteristiquesHydrauliques[k] .CntEnergieH2OParIntervalleOptimise[j] - = hydroVentilationResults[numSpace][k].HydrauliqueModulableQuotidien[day] + = hydroVentilationResults[k].HydrauliqueModulableQuotidien[day] * problem.CaracteristiquesHydrauliques[k].WeeklyGeneratingModulation * marginGen / weekGenerationTarget; } diff --git a/src/solver/simulation/simulation.h b/src/solver/simulation/simulation.h index b105059bc3..a17579ca22 100644 --- a/src/solver/simulation/simulation.h +++ b/src/solver/simulation/simulation.h @@ -58,7 +58,7 @@ void SIM_RenseignementProblemeHebdo(const Antares::Data::Study& study, uint weekInTheYear, uint numSpace, const int, - const ALL_HYDRO_VENTILATION_RESULTS&); + const HYDRO_VENTILATION_RESULTS&); void SIM_RenseignementProblemeHoraireAdequation(uint); diff --git a/src/solver/simulation/solver.h b/src/solver/simulation/solver.h index 45bf02ac47..fe21d9b430 100644 --- a/src/solver/simulation/solver.h +++ b/src/solver/simulation/solver.h @@ -124,7 +124,8 @@ class ISimulation : public Impl */ void computeRandomNumbers(randomNumbers& randomForYears, std::vector& years, - std::map& isYearPerformed); + std::map& isYearPerformed, + MersenneTwister& randomHydro); /*! ** \brief Computes statistics on annual (system and solution) costs, to be printed in output @@ -157,8 +158,6 @@ class ISimulation : public Impl uint pNbMaxPerformedYearsInParallel; //! Year by year output results bool pYearByYear; - //! Hydro management - HydroManagement hydroManagement; //! Hydro hot start bool pHydroHotStart; //! The first set of parallel year(s) with a performed year was already run ? diff --git a/src/solver/simulation/solver.hxx b/src/solver/simulation/solver.hxx index 8a33ad50b5..74d087fa43 100644 --- a/src/solver/simulation/solver.hxx +++ b/src/solver/simulation/solver.hxx @@ -78,7 +78,12 @@ public: state(pState), yearByYear(pYearByYear), pDurationCollector(durationCollector), - pResultWriter(resultWriter) + pResultWriter(resultWriter), + hydroManagement(study.areas, + study.parameters, + study.calendar, + study.maxNbYearsInParallel, + resultWriter) { hydroHotStart = (study.parameters.initialReservoirLevels.iniLevels == Data::irlHotStart); } @@ -98,6 +103,7 @@ private: bool hydroHotStart; Benchmarking::IDurationCollector& pDurationCollector; IResultWriter& pResultWriter; + HydroManagement hydroManagement; private: /* ** \brief Log failed week @@ -161,15 +167,10 @@ public: simulation_->prepareClustersInMustRunMode(numSpace, y); // 4 - Hydraulic ventilation - { - Benchmarking::Timer timer; - simulation_->hydroManagement.makeVentilation(randomReservoirLevel, - state[numSpace], - y, - numSpace); - timer.stop(); - pDurationCollector.addDuration("hydro_ventilation", timer.get_duration()); - } + Benchmarking::Timer timer; + hydroManagement.makeVentilation(randomReservoirLevel, state[numSpace], y, numSpace); + timer.stop(); + pDurationCollector.addDuration("hydro_ventilation", timer.get_duration()); // Updating the state state[numSpace].year = y; @@ -189,7 +190,7 @@ public: randomForCurrentYear, failedWeekList, isFirstPerformedYearOfSimulation, - simulation_->hydroManagement.ventilationResults(), + hydroManagement.ventilationResults(), optWriter); // Log failing weeks @@ -243,11 +244,6 @@ inline ISimulation::ISimulation(Data::Study& study, pNbYearsReallyPerformed(0), pNbMaxPerformedYearsInParallel(0), pYearByYear(study.parameters.yearByYear), - hydroManagement(study.areas, - study.parameters, - study.calendar, - study.maxNbYearsInParallel, - resultWriter), pFirstSetParallelWithAPerformedYearWasRun(false), pDurationCollector(duration_collector), pQueueService(study.pQueueService), @@ -666,12 +662,14 @@ void ISimulation::allocateMemoryForRandomNumbers(randomNumbers& randomForP template void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, std::vector& years, - std::map& isYearPerformed) + std::map& isYearPerformed, + MersenneTwister& randomHydroGenerator) { auto& runtime = *study.runtime; uint indexYear = 0; std::vector::iterator ity; + for (ity = years.begin(); ity != years.end(); ++ity) { uint y = *ity; @@ -717,9 +715,10 @@ void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, // Previous month's first day in the year int firstDayOfMonth = study.calendar.months[initResLevelOnSimMonth].daysYear.first; - double randomLevel = hydroManagement.randomReservoirLevel(min[firstDayOfMonth], + double randomLevel = randomReservoirLevel(min[firstDayOfMonth], avg[firstDayOfMonth], - max[firstDayOfMonth]); + max[firstDayOfMonth], + randomHydroGenerator); // Possibly update the intial level from scenario builder if (study.parameters.useCustomScenario) @@ -922,6 +921,10 @@ void ISimulation::loopThroughYears(uint firstYear, { assert(endYear <= study.parameters.nbYears); + // Init random hydro + MersenneTwister randomHydroGenerator; + randomHydroGenerator.reset(study.parameters.seed[Data::seedHydroManagement]); + // List of parallel years sets std::vector setsOfParallelYears; @@ -954,7 +957,8 @@ void ISimulation::loopThroughYears(uint firstYear, if (set_it->regenerateTS) regenerateTimeSeries(set_it->yearForTSgeneration); - computeRandomNumbers(randomForParallelYears, set_it->yearsIndices, set_it->isYearPerformed); + computeRandomNumbers(randomForParallelYears, set_it->yearsIndices, set_it->isYearPerformed, + randomHydroGenerator); std::vector::iterator year_it;