From 967433f95ab0c77fa53669c8fcb5cb114b445fb6 Mon Sep 17 00:00:00 2001 From: guilpier-code <62292552+guilpier-code@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:18:33 +0200 Subject: [PATCH] Move thermal noises to class Simulation (#1594) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [skip ci] Remove global vars : a bit of cleaning * Remove global vars : valeursGenereesParPays's allocation moved in a constructor + simplifying runtime * Remove global vars : unnecessary initialization of HydrauliqueModulableQuotidien (already done in simulation) * Remove global vars : remove unnecessary function, as it only calls one other function * Remove global vars : back to previous state, before wrong correction * Remove global vars : a bit of clarification in ALEA_TirageAuSortChroniques * Remove global vars : renaming * Remove global vars : simplifying and clarifying a bit thermal noises * Remove global vars : moving thermal noises to where it belongs + removing the useless AleaCoutDeProductionParPalier * Remove global vars : forgot to update adequacy mode with the new way we add thermal noise * Remove global vars : regression fix * Remove global vars : extract thermal part of weekly problem building, because of adq patch * [skip ci] Remove global vars : just clarifying * Remove global vars : remove call to SIM_RenseignementProblemeHebdo in AdequacyPatchOptimization::solve * Remove global vars : after previous commit removal, simplifications come naturally * Remove global vars : some cleaning * Fix/global var hydro modulable (#1614) * Global vars - try remove HydrauliqueModulableQuotidien : simple renaming * Global vars - try remove HydrauliqueModulableQuotidien : cleaning n class HydroManagement * Global vars : rename and move down struct VALEURS_GENEREES_PAR_PAYS * [skip ci] Global vars : small simplification * remove TS number global var : we don't need timeseriesNumberYear in StudyRuntimeInfos (#1618) * [skip ci] remove TS number global var : correction after review * Update src/libs/antares/study/area/scratchpad.cpp Co-authored-by: abdoulbari zakir <32519851+a-zakir@users.noreply.github.com> * Apply a-zakir's remark * Remove unused argument from StudyRuntimeInfos's ctor (#1634) --------- Co-authored-by: Florian Omnès Co-authored-by: abdoulbari zakir <32519851+a-zakir@users.noreply.github.com> --- src/libs/antares/study/area/scratchpad.cpp | 5 +- src/libs/antares/study/runtime/runtime.cpp | 27 +-- src/libs/antares/study/runtime/runtime.h | 16 +- src/libs/antares/study/study.cpp | 2 +- src/solver/aleatoire/alea_fonctions.h | 14 +- .../alea_tirage_au_sort_chroniques.cpp | 105 +++--------- .../daily2/h2o2_j_donnees_optimisation.h | 2 +- .../hydro/daily2/h2o2_j_optim_costs.cpp | 4 +- src/solver/hydro/management/daily.cpp | 89 +++++----- src/solver/hydro/management/management.cpp | 151 ++++++++++------- src/solver/hydro/management/management.h | 160 +++++++++--------- src/solver/hydro/management/monthly.cpp | 21 ++- .../adq_patch_curtailment_sharing.cpp | 1 - .../adequacy_patch_weekly_optimization.cpp | 13 +- .../adequacy_patch_weekly_optimization.h | 4 +- .../optimisation/base_weekly_optimization.cpp | 5 +- .../optimisation/base_weekly_optimization.h | 3 +- src/solver/simulation/adequacy.cpp | 35 ++-- src/solver/simulation/adequacy.h | 9 +- src/solver/simulation/common-eco-adq.cpp | 92 +++++++++- src/solver/simulation/common-eco-adq.h | 6 + src/solver/simulation/economy.cpp | 15 +- src/solver/simulation/economy.h | 4 +- .../simulation/sim_allocation_tableaux.cpp | 3 +- .../simulation/sim_calcul_economique.cpp | 118 +++++-------- src/solver/simulation/sim_structure_donnees.h | 13 -- src/solver/simulation/simulation.h | 3 +- src/solver/simulation/solver.h | 4 +- src/solver/simulation/solver.hxx | 131 ++++++-------- src/solver/ts-generator/thermal.cpp | 15 +- src/solver/variable/economy/max-mrg.cpp | 2 +- src/solver/variable/economy/max-mrg.h | 7 +- src/solver/variable/state.cpp | 2 +- src/solver/variable/state.h | 2 +- .../test-store-timeseries-number.cpp | 2 +- .../solver/simulation/test-time_series.cpp | 2 +- .../solver/simulation/tests-ts-numbers.cpp | 2 +- 37 files changed, 507 insertions(+), 582 deletions(-) diff --git a/src/libs/antares/study/area/scratchpad.cpp b/src/libs/antares/study/area/scratchpad.cpp index ab15440698..36aba7b633 100644 --- a/src/libs/antares/study/area/scratchpad.cpp +++ b/src/libs/antares/study/area/scratchpad.cpp @@ -45,6 +45,7 @@ AreaScratchpad::AreaScratchpad(const StudyRuntimeInfos& rinfos, Area& area) : ts { // alias to the simulation mode auto mode = rinfos.mode; + uint nbMonthsPerYear = 12; for (uint i = 0; i != 168; ++i) dispatchableGenerationMargin[i] = 0; @@ -123,8 +124,8 @@ AreaScratchpad::AreaScratchpad(const StudyRuntimeInfos& rinfos, Area& area) : ts auto& colPowerOverWater = m[PreproHydro::powerOverWater]; auto& colMaxEnergy = m[PreproHydro::maximumEnergy]; - for (uint m = 0; m < rinfos.nbMonthsPerYear; ++m) - valueCol += colMaxEnergy[m] * (1. - colPowerOverWater[m]); + for (uint month = 0; month < nbMonthsPerYear; ++month) + valueCol += colMaxEnergy[month] * (1. - colPowerOverWater[month]); hydroHasInflows = (valueCol > 0.); } diff --git a/src/libs/antares/study/runtime/runtime.cpp b/src/libs/antares/study/runtime/runtime.cpp index 4c625e14f8..bb2fa4383c 100644 --- a/src/libs/antares/study/runtime/runtime.cpp +++ b/src/libs/antares/study/runtime/runtime.cpp @@ -245,23 +245,13 @@ void StudyRuntimeInfos::initializeRangeLimits(const Study& study, StudyRangeLimi } } -StudyRuntimeInfos::StudyRuntimeInfos(uint nbYearsParallel) : - nbYears(0), - nbHoursPerYear(0), - nbDaysPerYear(0), - nbMonthsPerYear(0), - parameters(nullptr), - timeseriesNumberYear(nullptr), - thermalPlantTotalCount(0), - thermalPlantTotalCountMustRun(0), - quadraticOptimizationHasFailed(false) +StudyRuntimeInfos::StudyRuntimeInfos() : + nbYears(0), + parameters(nullptr), + thermalPlantTotalCount(0), + thermalPlantTotalCountMustRun(0), + quadraticOptimizationHasFailed(false) { - // Evite les confusions de numeros de TS entre AMC - timeseriesNumberYear = new uint[nbYearsParallel]; - for (uint numSpace = 0; numSpace < nbYearsParallel; numSpace++) - { - timeseriesNumberYear[numSpace] = 999999; - } } void StudyRuntimeInfos::checkThermalTSGeneration(Study& study) @@ -284,9 +274,6 @@ bool StudyRuntimeInfos::loadFromStudy(Study& study) auto& gd = study.parameters; nbYears = gd.nbYears; - nbHoursPerYear = 8760; - nbDaysPerYear = 365; - nbMonthsPerYear = 12; parameters = &study.parameters; mode = gd.mode; thermalPlantTotalCount = 0; @@ -453,8 +440,6 @@ void StudyRuntimeInfos::removeAllRenewableClustersFromSolverComputations(Study& StudyRuntimeInfos::~StudyRuntimeInfos() { logs.debug() << "Releasing runtime data"; - - delete[] timeseriesNumberYear; } #ifndef NDEBUG diff --git a/src/libs/antares/study/runtime/runtime.h b/src/libs/antares/study/runtime/runtime.h index a90820592d..33e78f3c20 100644 --- a/src/libs/antares/study/runtime/runtime.h +++ b/src/libs/antares/study/runtime/runtime.h @@ -76,7 +76,7 @@ class StudyRuntimeInfos /*! ** \brief Default constructor */ - StudyRuntimeInfos(uint nbYearsParallel); + StudyRuntimeInfos(); /*! ** \brief Destructor */ @@ -91,12 +91,6 @@ class StudyRuntimeInfos public: //! The number of years to process uint nbYears; - //! How many hours per year - uint nbHoursPerYear; // default: 8760 - //! Number of days per year - uint nbDaysPerYear; - //! Number - uint nbMonthsPerYear; //! Alias for General data Parameters* parameters; @@ -115,14 +109,6 @@ class StudyRuntimeInfos //! Random numbers generators MersenneTwister random[seedMax]; - /*! - ** \brief The index to use when retrieving the time-series numbers - ** - ** To allow the drop of the years with no solution, we can not fully rely - ** on the current year. So we have to maintain a rotating index (0..nbYears) - */ - uint* timeseriesNumberYear; - //! Total uint thermalPlantTotalCount; uint thermalPlantTotalCountMustRun; diff --git a/src/libs/antares/study/study.cpp b/src/libs/antares/study/study.cpp index a539b9b13a..43d5fd6c04 100644 --- a/src/libs/antares/study/study.cpp +++ b/src/libs/antares/study/study.cpp @@ -564,7 +564,7 @@ bool Study::checkHydroHotStart() bool Study::initializeRuntimeInfos() { delete runtime; - runtime = new StudyRuntimeInfos(maxNbYearsInParallel); + runtime = new StudyRuntimeInfos(); return runtime->loadFromStudy(*this); } diff --git a/src/solver/aleatoire/alea_fonctions.h b/src/solver/aleatoire/alea_fonctions.h index d6e03c90e0..e54d825358 100644 --- a/src/solver/aleatoire/alea_fonctions.h +++ b/src/solver/aleatoire/alea_fonctions.h @@ -24,17 +24,11 @@ ** ** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions */ -#ifndef __SOLVER_ALEA_H__ -#define __SOLVER_ALEA_H__ +#pragma once #include "../simulation/sim_structure_donnees.h" #include "antares/study/study.h" -void ALEA_TirageAuSortChroniques(const Antares::Data::Study& study, - double const* const* thermalNoisesByArea, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays); - -void HydroVentilation(); - -#endif // __SOLVER_ALEA_H__ +void ApplyRandomTSnumbers(const Antares::Data::Study& study, + unsigned int year, + uint numSpace); \ No newline at end of file diff --git a/src/solver/aleatoire/alea_tirage_au_sort_chroniques.cpp b/src/solver/aleatoire/alea_tirage_au_sort_chroniques.cpp index 5810dc1694..b39a83fd76 100644 --- a/src/solver/aleatoire/alea_tirage_au_sort_chroniques.cpp +++ b/src/solver/aleatoire/alea_tirage_au_sort_chroniques.cpp @@ -24,42 +24,26 @@ ** ** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions */ -#include "alea_sys.h" -#include -#include "../simulation/sim_structure_probleme_economique.h" #include "../simulation/sim_extern_variables_globales.h" #include "alea_fonctions.h" -#include -#include -#include -#include -#include -#include #include using namespace Yuni; using namespace Antares; using namespace Antares::Data; -static void InitializeTimeSeriesNumbers_And_ThermalClusterProductionCost( - const Study& study, - double const* const* thermalNoisesByArea, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) +void ApplyRandomTSnumbers(const Study& study, + unsigned int year, + uint numSpace) { - auto& runtime = *study.runtime; - - uint year = runtime.timeseriesNumberYear[numSpace]; - // each area const unsigned int count = study.areas.size(); - for (unsigned int i = 0; i != count; ++i) + for (unsigned int areaIndex = 0; areaIndex != count; ++areaIndex) { // Variables - the current area - NUMERO_CHRONIQUES_TIREES_PAR_PAYS& ptchro = NumeroChroniquesTireesParPays[numSpace][i]; - auto& area = *(study.areas.byIndex[i]); - VALEURS_GENEREES_PAR_PAYS& ptvalgen = valeursGenereesParPays[numSpace][i]; + NUMERO_CHRONIQUES_TIREES_PAR_PAYS& ptchro = NumeroChroniquesTireesParPays[numSpace][areaIndex]; + auto& area = *(study.areas.byIndex[areaIndex]); // Load { @@ -81,9 +65,6 @@ static void InitializeTimeSeriesNumbers_And_ThermalClusterProductionCost( assert(year < data.timeseriesNumbers.height); ptchro.Hydraulique = (data.count != 1) ? (long)data.timeseriesNumbers[0][year] : 0; // zero-based - // Hydro - mod - std::fill(ptvalgen.HydrauliqueModulableQuotidien.begin(), - ptvalgen.HydrauliqueModulableQuotidien.end(),0); } // Wind { @@ -105,87 +86,59 @@ static void InitializeTimeSeriesNumbers_And_ThermalClusterProductionCost( const auto& data = *cluster->series; assert(year < data.timeseriesNumbers.height); - unsigned int index = cluster->areaWideIndex; + unsigned int clusterIndex = cluster->areaWideIndex; - ptchro.RenouvelableParPalier[index] = (data.timeSeries.width != 1) - ? (long)data.timeseriesNumbers[0][year] - : 0; // zero-based + ptchro.RenouvelableParPalier[clusterIndex] = (data.timeSeries.width != 1) + ? (long)data.timeseriesNumbers[0][year] + : 0; // zero-based } } // Thermal { - uint indexCluster = 0; auto end = area.thermal.list.mapping.end(); for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) { ThermalClusterList::SharedPtr cluster = it->second; - // Draw a new random number, whatever the cluster is - double rnd = thermalNoisesByArea[i][indexCluster]; if (!cluster->enabled) { - indexCluster++; continue; } const auto& data = *cluster->series; assert(year < data.timeseriesNumbers.height); - unsigned int index = cluster->areaWideIndex; + unsigned int clusterIndex = cluster->areaWideIndex; // the matrix data.series should be properly initialized at this stage // because the ts-generator has already been launched - ptchro.ThermiqueParPalier[index] = (data.timeSeries.width != 1) - ? (long)data.timeseriesNumbers[0][year] - : 0; // zero-based - - // ptvalgen.AleaCoutDeProductionParPalier[index] = - // (rnd - 0.5) * (cluster->spreadCost + 1e-4); - // MBO - // 15/04/2014 : bornage du cout thermique - // 01/12/2014 : prise en compte du spreadCost non nul - - if (cluster->spreadCost == 0) // 5e-4 < |AleaCoutDeProductionParPalier| < 6e-4 - { - if (rnd < 0.5) - ptvalgen.AleaCoutDeProductionParPalier[index] = 1e-4 * (5 + 2 * rnd); - else - ptvalgen.AleaCoutDeProductionParPalier[index] - = -1e-4 * (5 + 2 * (rnd - 0.5)); - } - else - { - ptvalgen.AleaCoutDeProductionParPalier[index] - = (rnd - 0.5) * (cluster->spreadCost); - - if (Math::Abs(ptvalgen.AleaCoutDeProductionParPalier[index]) < 5.e-4) - { - if (Math::Abs(ptvalgen.AleaCoutDeProductionParPalier[index]) >= 0) - ptvalgen.AleaCoutDeProductionParPalier[index] += 5.e-4; - else - ptvalgen.AleaCoutDeProductionParPalier[index] -= 5.e-4; - } - } - - indexCluster++; + ptchro.ThermiqueParPalier[clusterIndex] = (data.timeSeries.width != 1) + ? (long)data.timeseriesNumbers[0][year] + : 0; // zero-based } } // thermal } // each area + + // ------------------------------ // Transmission capacities + // ------------------------------ // each link - for (unsigned int i = 0; i < runtime.interconnectionsCount(); ++i) + for (unsigned int linkIndex = 0; linkIndex < study.runtime->interconnectionsCount(); ++linkIndex) { - AreaLink* link = runtime.areaLink[i]; + AreaLink* link = study.runtime->areaLink[linkIndex]; assert(year < link->timeseriesNumbers.height); NUMERO_CHRONIQUES_TIREES_PAR_INTERCONNEXION& ptchro - = NumeroChroniquesTireesParInterconnexion[numSpace][i]; + = NumeroChroniquesTireesParInterconnexion[numSpace][linkIndex]; const uint directWidth = link->directCapacities.width; [[maybe_unused]] const uint indirectWidth = link->indirectCapacities.width; assert(directWidth == indirectWidth); ptchro.TransmissionCapacities = (directWidth != 1) ? link->timeseriesNumbers[0][year] : 0; // zero-based } + + // ------------------------------ //Binding constraints + // ------------------------------ //Setting 0 for time_series of width 0 is done when using the value. //To do this here we would have to check every BC for its width for (const auto& group: study.bindingConstraintsGroups) { @@ -194,15 +147,3 @@ static void InitializeTimeSeriesNumbers_And_ThermalClusterProductionCost( NumeroChroniquesTireesParGroup[numSpace][group->name()] = group->timeseriesNumbers[0][year]; } } - -void ALEA_TirageAuSortChroniques(const Antares::Data::Study& study, - double const* const* thermalNoisesByArea, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) -{ - // Time-series numbers - // Retrieve all time-series numbers - // Initialize in the same time the production costs of all thermal clusters. - InitializeTimeSeriesNumbers_And_ThermalClusterProductionCost(study, - thermalNoisesByArea, numSpace, valeursGenereesParPays); -} diff --git a/src/solver/hydro/daily2/h2o2_j_donnees_optimisation.h b/src/solver/hydro/daily2/h2o2_j_donnees_optimisation.h index 1d900de041..a6733498b2 100644 --- a/src/solver/hydro/daily2/h2o2_j_donnees_optimisation.h +++ b/src/solver/hydro/daily2/h2o2_j_donnees_optimisation.h @@ -144,7 +144,7 @@ constexpr unsigned int seed = 0x79683264; // "hyd2" in hexa class Hydro_problem_costs { public: - Hydro_problem_costs(const Data::Study& study); + Hydro_problem_costs(const Data::Parameters& parameters); inline double get_end_days_levels_cost() const { diff --git a/src/solver/hydro/daily2/h2o2_j_optim_costs.cpp b/src/solver/hydro/daily2/h2o2_j_optim_costs.cpp index 619e94f5d0..6a26a68f0a 100644 --- a/src/solver/hydro/daily2/h2o2_j_optim_costs.cpp +++ b/src/solver/hydro/daily2/h2o2_j_optim_costs.cpp @@ -28,7 +28,7 @@ #include "h2o2_j_donnees_optimisation.h" #include "antares/study/fwd.h" -Hydro_problem_costs::Hydro_problem_costs(const Data::Study& study) +Hydro_problem_costs::Hydro_problem_costs(const Data::Parameters& parameters) { noiseGenerator.reset(Constants::seed); end_days_levels = -1. / 32.; @@ -36,7 +36,7 @@ Hydro_problem_costs::Hydro_problem_costs(const Data::Study& study) deviations = 1.; violations = 68.; - switch (study.parameters.hydroHeuristicPolicy.hhPolicy) + switch (parameters.hydroHeuristicPolicy.hhPolicy) { case Data::hhpMaximizeGeneration: waste = 33 * 68.; diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index d7f7989f9e..8c2a6ab245 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -81,7 +81,6 @@ enum struct DebugData { - using PerArea = HydroManagement::PerArea; using InflowsType = Matrix::ColumnType; using MaxPowerType = Matrix::ColumnType; using ReservoirLevelType = Matrix::ColumnType; @@ -99,8 +98,8 @@ struct DebugData std::array previousMonthWaste{0}; Solver::IResultWriter::Ptr pWriter; - const PerArea& data; - const VALEURS_GENEREES_PAR_PAYS& valgen; + const TmpDataByArea& data; + const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults; const InflowsType& srcinflows; const MaxPowerType& maxP; const MaxPowerType& maxE; @@ -109,8 +108,8 @@ struct DebugData const double reservoirCapacity; DebugData(Solver::IResultWriter::Ptr writer, - const PerArea& data, - const VALEURS_GENEREES_PAR_PAYS& valgen, + const TmpDataByArea& data, + const VENTILATION_HYDRO_RESULTS_BY_AREA& ventilationResults, const InflowsType& srcinflows, const MaxPowerType& maxP, const MaxPowerType& maxE, @@ -119,7 +118,7 @@ struct DebugData double reservoirCapacity) : pWriter(writer), data(data), - valgen(valgen), + ventilationResults(ventilationResults), srcinflows(srcinflows), maxP(maxP), maxE(maxE), @@ -145,7 +144,7 @@ struct DebugData buffer << "\tTurbine\t\t\tOPP\t\t\t\tTurbine Cible\tDLE\t\t\t\tDLN\n"; for (uint day = 0; day != 365; ++day) { - double value = valgen.HydrauliqueModulableQuotidien[day]; + double value = ventilationResults.HydrauliqueModulableQuotidien[day]; buffer << day << '\t' << value << '\t' << OPP[day] << '\t' << DailyTargetGen[day] << '\t' << data.DLE[day] << '\t' << data.DLN[day]; buffer << '\n'; @@ -189,9 +188,9 @@ struct DebugData uint dayMonth = 1; for (uint day = firstDay; day != endDay; ++day) { - double turbines = valgen.HydrauliqueModulableQuotidien[day] / reservoirCapacity; - double niveauDeb = valgen.NiveauxReservoirsDebutJours[day]; - double niveauFin = valgen.NiveauxReservoirsFinJours[day]; + double turbines = ventilationResults.HydrauliqueModulableQuotidien[day] / reservoirCapacity; + double niveauDeb = ventilationResults.NiveauxReservoirsDebutJours[day]; + double niveauFin = ventilationResults.NiveauxReservoirsFinJours[day]; double apports = srcinflows[day] / reservoirCapacity; double turbMax = maxP[day] * maxE[day] / reservoirCapacity; double turbCible = dailyTargetGen[day] / reservoirCapacity; @@ -226,11 +225,10 @@ struct DebugData inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::State& state, Data::Area& area, uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) + uint numSpace) { uint z = area.index; - assert(z < study.areas.size()); + assert(z < areas_.size()); auto& ptchro = NumeroChroniquesTireesParPays[numSpace][z]; @@ -239,7 +237,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St auto tsIndex = (uint)ptchro.Hydraulique; auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; auto& scratchpad = area.scratchpad[numSpace]; @@ -258,15 +256,15 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St auto const& maxP = maxPower[Data::PartHydro::genMaxP]; auto const& maxE = maxPower[Data::PartHydro::genMaxE]; - auto& valgen = valeursGenereesParPays[numSpace][z]; - + auto& ventilationResults = ventilationResults_[numSpace][z]; + std::shared_ptr debugData(nullptr); - if (study.parameters.hydroDebug && study.resultWriter) + if (parameters_.hydroDebug && resultWriter_) { - debugData = std::make_shared(study.resultWriter, + debugData = std::make_shared(resultWriter_, data, - valgen, + ventilationResults, srcinflows, maxP, maxE, @@ -277,7 +275,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St for (uint month = 0; month != 12; ++month) { - auto daysPerMonth = study.calendar.months[month].days; + auto daysPerMonth = calendar_.months[month].days; assert(daysPerMonth <= maxOPP); assert(daysPerMonth <= maxDailyTargetGen); assert(daysPerMonth + dayYear - 1 < maxPower.height); @@ -302,7 +300,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St dayYear = 0; for (uint month = 0; month != 12; ++month) { - auto daysPerMonth = study.calendar.months[month].days; + auto daysPerMonth = calendar_.months[month].days; for (uint day = 0; day != daysPerMonth; ++day) { dailyTargetGen[dayYear + day] = srcinflows[dayYear + day]; @@ -317,8 +315,8 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St dayYear = 0; for (uint month = 0; month != 12; ++month) { - uint realmonth = study.calendar.months[month].realmonth; - auto daysPerMonth = study.calendar.months[month].days; + uint realmonth = calendar_.months[month].realmonth; + auto daysPerMonth = calendar_.months[month].days; if (area.hydro.followLoadModulations) { @@ -369,7 +367,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St { for (uint month = 0; month != 12; ++month) { - auto daysPerMonth = study.calendar.months[month].days; + auto daysPerMonth = calendar_.months[month].days; for (uint day = 0; day != daysPerMonth; ++day) { @@ -384,11 +382,11 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St for (uint month = 0; month != 12; ++month) { uint realmonth = (initReservoirLvlMonth + month) % 12; - uint simulationMonth = study.calendar.mapping.months[realmonth]; + uint simulationMonth = calendar_.mapping.months[realmonth]; - auto daysPerMonth = study.calendar.months[simulationMonth].days; + auto daysPerMonth = calendar_.months[simulationMonth].days; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; uint endDay = firstDay + daysPerMonth; DONNEES_MENSUELLES problem = H2O_J_Instanciation(); @@ -412,7 +410,7 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St dayMonth = 0; for (uint day = firstDay; day != endDay; ++day) { - valgen.HydrauliqueModulableQuotidien[day] = problem.Turbine[dayMonth]; + ventilationResults.HydrauliqueModulableQuotidien[day] = problem.Turbine[dayMonth]; dayMonth++; } break; @@ -429,8 +427,8 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St #ifndef NDEBUG for (uint day = firstDay; day != endDay; ++day) { - assert(!Math::NaN(valgen.HydrauliqueModulableQuotidien[day])); - assert(!Math::Infinite(valgen.HydrauliqueModulableQuotidien[day])); + assert(!Math::NaN(ventilationResults.HydrauliqueModulableQuotidien[day])); + assert(!Math::Infinite(ventilationResults.HydrauliqueModulableQuotidien[day])); } #endif } @@ -447,16 +445,16 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St double monthInitialLevel = data.MOL[initReservoirLvlMonth]; double wasteFromPreviousMonth = 0.; - Hydro_problem_costs h2o2_optim_costs(study); + Hydro_problem_costs h2o2_optim_costs(parameters_); for (uint month = 0; month != 12; ++month) { uint realmonth = (initReservoirLvlMonth + month) % 12; - uint simulationMonth = study.calendar.mapping.months[realmonth]; + uint simulationMonth = calendar_.mapping.months[realmonth]; - auto daysPerMonth = study.calendar.months[simulationMonth].days; + auto daysPerMonth = calendar_.months[simulationMonth].days; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; uint endDay = firstDay + daysPerMonth; DONNEES_MENSUELLES_ETENDUES& problem = *H2O2_J_Instanciation(); @@ -506,10 +504,10 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St dayMonth = 0; for (uint day = firstDay; day != endDay; ++day) { - valgen.HydrauliqueModulableQuotidien[day] + ventilationResults.HydrauliqueModulableQuotidien[day] = problem.Turbine[dayMonth] * reservoirCapacity; - valgen.NiveauxReservoirsFinJours[day] = problem.niveauxFinJours[dayMonth]; + ventilationResults.NiveauxReservoirsFinJours[day] = problem.niveauxFinJours[dayMonth]; if (debugData) { @@ -521,10 +519,10 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St dayMonth++; } - valgen.NiveauxReservoirsDebutJours[firstDay] = monthInitialLevel; + ventilationResults.NiveauxReservoirsDebutJours[firstDay] = monthInitialLevel; for (uint day = firstDay + 1; day != endDay; ++day) - valgen.NiveauxReservoirsDebutJours[day] - = valgen.NiveauxReservoirsFinJours[day - 1]; + ventilationResults.NiveauxReservoirsDebutJours[day] + = ventilationResults.NiveauxReservoirsFinJours[day - 1]; monthInitialLevel = problem.niveauxFinJours[dayMonth - 1]; @@ -542,25 +540,24 @@ inline void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::St H2O2_J_Free(&problem); } - uint firstDaySimu = study.parameters.simulationDays.first; + uint firstDaySimu = parameters_.simulationDays.first; state.problemeHebdo->previousSimulationFinalLevel[z] - = valgen.NiveauxReservoirsDebutJours[firstDaySimu] * reservoirCapacity; + = ventilationResults.NiveauxReservoirsDebutJours[firstDaySimu] * reservoirCapacity; if (debugData) { - debugData->writeDailyDebugData(study.calendar, initReservoirLvlMonth, y, area.name); + debugData->writeDailyDebugData(calendar_, initReservoirLvlMonth, y, area.name); } } } void HydroManagement::prepareDailyOptimalGenerations(Solver::Variable::State& state, uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) + uint numSpace) { - study.areas.each( + areas_.each( [&](Data::Area& area) { - prepareDailyOptimalGenerations(state, area, y, numSpace, valeursGenereesParPays); + prepareDailyOptimalGenerations(state, area, y, numSpace); }); } diff --git a/src/solver/hydro/management/management.cpp b/src/solver/hydro/management/management.cpp index 54ad9e2666..8c5207dc16 100644 --- a/src/solver/hydro/management/management.cpp +++ b/src/solver/hydro/management/management.cpp @@ -46,8 +46,8 @@ double HydroManagement::GammaVariable(double r) 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.); @@ -78,28 +78,55 @@ inline double HydroManagement::BetaVariable(double a, double b) return y / (y + z); } -HydroManagement::HydroManagement(Data::Study& study) : study(study), parameters(study.parameters) +HydroManagement::HydroManagement(const Data::AreaList& areas, + const Data::Parameters& params, + const Date::Calendar& calendar, + unsigned int maxNbYearsInParallel, + Solver::IResultWriter::Ptr resultWriter) : + areas_(areas), + calendar_(calendar), + parameters_(params), + maxNbYearsInParallel_(maxNbYearsInParallel), + resultWriter_(resultWriter) { - pAreas = new PerArea*[study.maxNbYearsInParallel]; - for (uint numSpace = 0; numSpace < study.maxNbYearsInParallel; numSpace++) - pAreas[numSpace] = new PerArea[study.areas.size()]; + tmpDataByArea_ = new TmpDataByArea* [maxNbYearsInParallel_]; + for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) + tmpDataByArea_[numSpace] = new TmpDataByArea[areas_.size()]; - random.reset(study.parameters.seed[Data::seedHydroManagement]); + random_.reset(parameters_.seed[Data::seedHydroManagement]); + + // Ventilation results memory allocation + uint nbDaysPerYear = 365; + ventilationResults_.resize(maxNbYearsInParallel_); + for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) + { + ventilationResults_[numSpace].resize(areas_.size()); + for (uint areaIndex = 0; areaIndex < areas_.size(); ++areaIndex) + { + auto& area = *areas_.byIndex[areaIndex]; + size_t clusterCount = area.thermal.clusterCount(); + + ventilationResults_[numSpace][areaIndex].HydrauliqueModulableQuotidien.assign(nbDaysPerYear, 0); + + if (area.hydro.reservoirManagement) + { + ventilationResults_[numSpace][areaIndex].NiveauxReservoirsDebutJours.assign(nbDaysPerYear, 0.); + ventilationResults_[numSpace][areaIndex].NiveauxReservoirsFinJours.assign(nbDaysPerYear, 0.); + } + } + } } HydroManagement::~HydroManagement() { - for (uint numSpace = 0; numSpace < study.maxNbYearsInParallel; numSpace++) - delete[] pAreas[numSpace]; - delete[] pAreas; + for (uint numSpace = 0; numSpace < maxNbYearsInParallel_; numSpace++) + delete[] tmpDataByArea_[numSpace]; + delete[] tmpDataByArea_; } void HydroManagement::prepareInflowsScaling(uint numSpace) { - auto& calendar = study.calendar; - - study.areas.each( - [&](Data::Area& area) + areas_.each([&](Data::Area& area) { uint z = area.index; @@ -110,18 +137,18 @@ void HydroManagement::prepareInflowsScaling(uint numSpace) auto tsIndex = (uint)ptchro.Hydraulique; auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; double totalYearInflows = 0.0; for (uint month = 0; month != 12; ++month) { - uint realmonth = calendar.months[month].realmonth; + uint realmonth = calendar_.months[month].realmonth; double totalMonthInflows = 0.0; - uint firstDayOfMonth = calendar.months[month].daysYear.first; + uint firstDayOfMonth = calendar_.months[month].daysYear.first; - uint firstDayOfNextMonth = calendar.months[month].daysYear.end; + uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; for (uint d = firstDayOfMonth; d != firstDayOfNextMonth; ++d) totalMonthInflows += srcinflows[d]; @@ -152,10 +179,7 @@ void HydroManagement::prepareInflowsScaling(uint numSpace) void HydroManagement::minGenerationScaling(uint numSpace) { - const auto& calendar = study.calendar; - - study.areas.each( - [this, &numSpace, &calendar](Data::Area& area) + areas_.each([this, &numSpace](Data::Area& area) { uint z = area.index; @@ -164,14 +188,14 @@ void HydroManagement::minGenerationScaling(uint numSpace) auto tsIndex = (uint)ptchro.Hydraulique; auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; double totalYearMingen = 0.0; for (uint month = 0; month != 12; ++month) { - uint realmonth = calendar.months[month].realmonth; - uint firstDayOfMonth = calendar.months[month].daysYear.first; - uint firstDayOfNextMonth = calendar.months[month].daysYear.end; + uint realmonth = calendar_.months[month].realmonth; + uint firstDayOfMonth = calendar_.months[month].daysYear.first; + uint firstDayOfNextMonth = calendar_.months[month].daysYear.end; double totalMonthMingen = std::accumulate( srcmingen + firstDayOfMonth * 24, srcmingen + firstDayOfNextMonth * 24, 0.); @@ -198,9 +222,9 @@ void HydroManagement::minGenerationScaling(uint numSpace) } // Set daily mingen, used later for h2o_d - uint simulationMonth = study.calendar.mapping.months[realmonth]; - auto daysPerMonth = study.calendar.months[simulationMonth].days; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint simulationMonth = calendar_.mapping.months[realmonth]; + auto daysPerMonth = calendar_.months[simulationMonth].days; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; uint endDay = firstDay + daysPerMonth; for (uint day = firstDay; day != endDay; ++day) @@ -215,10 +239,10 @@ void HydroManagement::minGenerationScaling(uint numSpace) bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint tsIndex, const Data::Area& area) const { - const auto& data = pAreas[numSpace][area.index]; + const auto& data = tmpDataByArea_[numSpace][area.index]; for (uint month = 0; month != 12; ++month) { - uint realmonth = study.calendar.months[month].realmonth; + uint realmonth = calendar_.months[month].realmonth; // Monthly minimum generation <= Monthly inflows for each month if (area.hydro.followLoadModulations && !area.hydro.reservoirManagement && @@ -236,7 +260,7 @@ bool HydroManagement::checkMonthlyMinGeneration(uint numSpace, uint tsIndex, con bool HydroManagement::checkYearlyMinGeneration(uint numSpace, uint tsIndex, const Data::Area& area) const { - const auto& data = pAreas[numSpace][area.index]; + const auto& data = tmpDataByArea_[numSpace][area.index]; if (area.hydro.followLoadModulations && area.hydro.reservoirManagement && data.totalYearMingen > data.totalYearInflows) @@ -254,25 +278,24 @@ bool HydroManagement::checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) c { if (!area.hydro.followLoadModulations) { - const auto& calendar = study.calendar; auto& inflowsmatrix = area.hydro.series->storage; auto& mingenmatrix = area.hydro.series->mingen; auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; // Weekly minimum generation <= Weekly inflows for each week - for (uint week = 0; week < calendar.maxWeeksInYear - 1; ++week) + for (uint week = 0; week < calendar_.maxWeeksInYear - 1; ++week) { double totalWeekMingen = 0.0; double totalWeekInflows = 0.0; - for (uint hour = calendar.weeks[week].hours.first; - hour < calendar.weeks[week].hours.end && hour < HOURS_PER_YEAR; + for (uint hour = calendar_.weeks[week].hours.first; + hour < calendar_.weeks[week].hours.end && hour < HOURS_PER_YEAR; ++hour) { totalWeekMingen += srcmingen[hour]; } - for (uint day = calendar.weeks[week].daysYear.first; - day < calendar.weeks[week].daysYear.end; + for (uint day = calendar_.weeks[week].daysYear.first; + day < calendar_.weeks[week].daysYear.end; ++day) { totalWeekInflows += srcinflows[day]; @@ -293,7 +316,6 @@ bool HydroManagement::checkWeeklyMinGeneration(uint tsIndex, Data::Area& area) c bool HydroManagement::checkHourlyMinGeneration(uint tsIndex, Data::Area& area) const { // Hourly minimum generation <= hourly inflows for each hour - const auto& calendar = study.calendar; auto& mingenmatrix = area.hydro.series->mingen; auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; auto const& maxPower = area.hydro.maxPower; @@ -303,10 +325,10 @@ bool HydroManagement::checkHourlyMinGeneration(uint tsIndex, Data::Area& area) c { for (uint month = 0; month != 12; ++month) { - uint realmonth = calendar.months[month].realmonth; - uint simulationMonth = study.calendar.mapping.months[realmonth]; - auto daysPerMonth = study.calendar.months[simulationMonth].days; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint realmonth = calendar_.months[month].realmonth; + uint simulationMonth = calendar_.mapping.months[realmonth]; + auto daysPerMonth = calendar_.months[simulationMonth].days; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; uint endDay = firstDay + daysPerMonth; for (uint day = firstDay; day != endDay; ++day) @@ -333,7 +355,7 @@ bool HydroManagement::checkHourlyMinGeneration(uint tsIndex, Data::Area& area) c bool HydroManagement::checkMinGeneration(uint numSpace) { bool ret = true; - study.areas.each([this, &numSpace, &ret](Data::Area& area) + areas_.each([this, &numSpace, &ret](Data::Area& area) { uint z = area.index; const auto& ptchro = NumeroChroniquesTireesParPays[numSpace][z]; @@ -354,7 +376,7 @@ bool HydroManagement::checkMinGeneration(uint numSpace) template void HydroManagement::prepareNetDemand(uint numSpace) { - study.areas.each([&](Data::Area& area) { + areas_.each([&](Data::Area& area) { uint z = area.index; auto& scratchpad = area.scratchpad[numSpace]; @@ -365,16 +387,16 @@ void HydroManagement::prepareNetDemand(uint numSpace) auto tsIndex = (uint)ptchro.Hydraulique; auto& ror = rormatrix[tsIndex < rormatrix.width ? tsIndex : 0]; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; - for (uint hour = 0; hour != 8760; ++hour) + for (uint hour = 0; hour != HOURS_PER_YEAR; ++hour) { - auto dayYear = study.calendar.hours[hour].dayYear; + auto dayYear = calendar_.hours[hour].dayYear; double netdemand = 0; // Aggregated renewable production: wind & solar - if (parameters.renewableGeneration.isAggregated()) + if (parameters_.renewableGeneration.isAggregated()) { netdemand = +scratchpad.ts.load[ptchro.Consommation][hour] - scratchpad.ts.wind[ptchro.Eolien][hour] - scratchpad.miscGenSum[hour] @@ -384,7 +406,7 @@ void HydroManagement::prepareNetDemand(uint numSpace) } // Renewable clusters, if enabled - else if (parameters.renewableGeneration.isClusters()) + else if (parameters_.renewableGeneration.isClusters()) { netdemand = scratchpad.ts.load[ptchro.Consommation][hour] - scratchpad.miscGenSum[hour] - ror[hour] @@ -407,20 +429,20 @@ void HydroManagement::prepareNetDemand(uint numSpace) void HydroManagement::prepareEffectiveDemand(uint numSpace) { - study.areas.each([&](Data::Area& area) { + areas_.each([&](Data::Area& area) { auto z = area.index; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; for (uint day = 0; day != 365; ++day) { - auto month = study.calendar.days[day].month; + auto month = calendar_.days[day].month; assert(month < 12 && "Invalid month index"); - auto realmonth = study.calendar.months[month].realmonth; + auto realmonth = calendar_.months[month].realmonth; double effectiveDemand = 0; area.hydro.allocation.eachNonNull([&](unsigned areaindex, double value) { - effectiveDemand += (pAreas[numSpace][areaindex]).DLN[day] * value; + effectiveDemand += (tmpDataByArea_[numSpace][areaindex]).DLN[day] * value; }); assert(!Math::NaN(effectiveDemand) && "nan value detected for effectiveDemand"); @@ -437,8 +459,8 @@ void HydroManagement::prepareEffectiveDemand(uint numSpace) for (uint month = 0; month != 12; ++month) { auto minimumMonth = +std::numeric_limits::infinity(); - auto daysPerMonth = study.calendar.months[month].days; - auto realmonth = study.calendar.months[month].realmonth; + auto daysPerMonth = calendar_.months[month].days; + auto realmonth = calendar_.months[month].realmonth; for (uint d = 0; d != daysPerMonth; ++d) { @@ -493,13 +515,12 @@ double HydroManagement::randomReservoirLevel(double min, double avg, double max) return x * max + (1. - x) * min; } -void HydroManagement::operator()(double* randomReservoirLevel, - Solver::Variable::State& state, - uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) +void HydroManagement::makeVentilation(double* randomReservoirLevel, + Solver::Variable::State& state, + uint y, + uint numSpace) { - memset(pAreas[numSpace], 0, sizeof(PerArea) * study.areas.size()); + memset(tmpDataByArea_[numSpace], 0, sizeof(TmpDataByArea) * areas_.size()); prepareInflowsScaling(numSpace); minGenerationScaling(numSpace); @@ -508,7 +529,7 @@ void HydroManagement::operator()(double* randomReservoirLevel, throw FatalError("hydro management: invalid minimum generation"); } - if (parameters.adequacy()) + if (parameters_.adequacy()) prepareNetDemand(numSpace); else prepareNetDemand(numSpace); @@ -516,7 +537,7 @@ void HydroManagement::operator()(double* randomReservoirLevel, prepareEffectiveDemand(numSpace); prepareMonthlyOptimalGenerations(randomReservoirLevel, y, numSpace); - prepareDailyOptimalGenerations(state, y, numSpace, valeursGenereesParPays); + prepareDailyOptimalGenerations(state, y, numSpace); } } // namespace Antares diff --git a/src/solver/hydro/management/management.h b/src/solver/hydro/management/management.h index a8c96a3d25..30dda45bf8 100644 --- a/src/solver/hydro/management/management.h +++ b/src/solver/hydro/management/management.h @@ -42,39 +42,84 @@ class State; } } // namespace Solver +enum +{ + //! The maximum number of days in a year + dayYearCount = 366 +}; + +//! Temporary data +struct TmpDataByArea +{ + //! Monthly local effective demand + double MLE[12]; + //! Monthly optimal generation + double MOG[12]; + //! Monthly optimal level + double MOL[12]; + //! Monthly target generations + double MTG[12]; + //! inflows + double inflows[12]; + //! monthly minimal generation + std::array mingens; + + //! Net demand, for each day of the year, for each area + double DLN[dayYearCount]; + //! Daily local effective load + double DLE[dayYearCount]; + //! Daily optimized Generation + double DOG[dayYearCount]; + //! daily minimal generation + std::array dailyMinGen; + + // Data for minGen<->inflows preChecks + //! monthly total mingen + std::array totalMonthMingen; + //! monthly total inflows + std::array totalMonthInflows; + //! yearly total mingen + double totalYearMingen; + //! yearly total inflows + double totalYearInflows; + +}; // struct TmpDataByArea + +typedef struct +{ + std::vector HydrauliqueModulableQuotidien; /* indice par jour */ + std::vector NiveauxReservoirsDebutJours; //Niveaux (quotidiens) du reservoir de début + //de jour (en cas de gestion des reservoirs). + std::vector NiveauxReservoirsFinJours; //Niveaux (quotidiens) du reservoir de fin + //de jour (en cas de gestion des reservoirs). +} VENTILATION_HYDRO_RESULTS_BY_AREA; + +// vector of [numSpace][area] +using ALL_HYDRO_VENTILATION_RESULTS = std::vector>; + + class HydroManagement final { public: - //! \name Constructor & Destructor - //@{ - /*! - ** \brief Default constructor - */ - explicit HydroManagement(Data::Study& study); - //! Destructor + HydroManagement(const Data::AreaList& areas, + const Data::Parameters& params, + const Date::Calendar& calendar, + unsigned int maxNbYearsInParallel, + Solver::IResultWriter::Ptr resultWriter); + ~HydroManagement(); - //@} - //! Get an initial reservoir level double randomReservoirLevel(double min, double avg, double max); //! Perform the hydro ventilation - void operator()(double* randomReservoirLevel, - Solver::Variable::State& state, - uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays); - -public: - //! Random number generator - MersenneTwister random; + void makeVentilation(double* randomReservoirLevel, + Solver::Variable::State& state, + uint y, + uint numSpace); - // forward declaration - struct PerArea; + ALL_HYDRO_VENTILATION_RESULTS& ventilationResults() { return ventilationResults_; } private: - //! \name Steps - //@{ //! Prepare inflows scaling for each area void prepareInflowsScaling(uint numSpace); //! Prepare minimum generation scaling for each area @@ -100,18 +145,16 @@ class HydroManagement final //! Monthly target generations // note: inflows may have two different types, if in swap mode or not // \return The total inflow for the whole year - double prepareMonthlyTargetGenerations(Data::Area& area, PerArea& data); + double prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data); void prepareDailyOptimalGenerations(Solver::Variable::State& state, uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays); + uint numSpace); void prepareDailyOptimalGenerations(Solver::Variable::State& state, Data::Area& area, uint y, - uint numSpace, - VAL_GEN_PAR_PAYS& valeursGenereesParPays); + uint numSpace); //@} //! \name Utilities @@ -122,60 +165,17 @@ class HydroManagement final double GammaVariable(double a); //@} - enum - { - //! The maximum number of days in a year - dayYearCount = 366 - }; - -public: - //! Reference to the study - Data::Study& study; - //! General data - Data::Parameters& parameters; - - //! Temporary data - struct PerArea - { - //! Monthly local effective demand - double MLE[12]; - //! Monthly optimal generation - double MOG[12]; - //! Monthly optimal level - double MOL[12]; - //! Monthly target generations - double MTG[12]; - //! inflows - double inflows[12]; - //! monthly minimal generation - std::array mingens; - - //! Net demand, for each day of the year, for each area - double DLN[dayYearCount]; - //! Daily local effective load - double DLE[dayYearCount]; - //! Daily optimized Generation - double DOG[dayYearCount]; - //! daily minimal generation - std::array dailyMinGen; - - // Data for minGen<->inflows preChecks - //! monthly total mingen - std::array totalMonthMingen; - //! monthly total inflows - std::array totalMonthInflows; - //! yearly total mingen - double totalYearMingen; - //! yearly total inflows - double totalYearInflows; - - }; // struct PerArea - - //! Temporary data per area - PerArea** pAreas; - +private: + TmpDataByArea** tmpDataByArea_; + const Data::AreaList& areas_; + const Date::Calendar& calendar_; + const Data::Parameters& parameters_; + MersenneTwister random_; + unsigned int maxNbYearsInParallel_ = 0; + Solver::IResultWriter::Ptr resultWriter_; + + ALL_HYDRO_VENTILATION_RESULTS ventilationResults_; }; // class HydroManagement - } // namespace Antares #endif // __ANTARES_SOLVER_HYDRO_MANAGEMENT_MANAGEMENT_H__ diff --git a/src/solver/hydro/management/monthly.cpp b/src/solver/hydro/management/monthly.cpp index 2e631ae576..090f3e5c0c 100644 --- a/src/solver/hydro/management/monthly.cpp +++ b/src/solver/hydro/management/monthly.cpp @@ -87,7 +87,7 @@ static void CheckHydroAllocationProblem(Data::Area& area, } -double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, PerArea& data) +double HydroManagement::prepareMonthlyTargetGenerations(Data::Area& area, TmpDataByArea& data) { double total = 0; @@ -147,10 +147,10 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ uint numSpace) { uint indexArea = 0; - study.areas.each([&](Data::Area& area) { + areas_.each([&](Data::Area& area) { uint z = area.index; - auto& data = pAreas[numSpace][z]; + auto& data = tmpDataByArea_[numSpace][z]; auto& minLvl = area.hydro.reservoirLevel[Data::PartHydro::minimum]; auto& maxLvl = area.hydro.reservoirLevel[Data::PartHydro::maximum]; @@ -181,8 +181,8 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { uint realmonth = (initReservoirLvlMonth + month) % 12; - uint simulationMonth = study.calendar.mapping.months[realmonth]; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint simulationMonth = calendar_.mapping.months[realmonth]; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; problem.TurbineMax[month] = totalInflowsYear; problem.TurbineMin[month] = data.mingens[realmonth]; @@ -247,8 +247,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ assert(!Math::Infinite(data.MOL[realmonth]) && "infinite value detected for MOL"); } #endif - auto writer = study.resultWriter; - if (study.parameters.hydroDebug && writer) + if (parameters_.hydroDebug && resultWriter_) { std::ostringstream buffer, path; path << "debug" << SEP << "solver" << SEP << (1 + y) << SEP << "monthly." << area.name @@ -276,11 +275,11 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ { uint realmonth = (initReservoirLvlMonth + month) % 12; - uint simulationMonth = study.calendar.mapping.months[realmonth]; + uint simulationMonth = calendar_.mapping.months[realmonth]; - uint firstDay = study.calendar.months[simulationMonth].daysYear.first; + uint firstDay = calendar_.months[simulationMonth].daysYear.first; - auto monthName = study.calendar.text.months[simulationMonth].name; + auto monthName = calendar_.text.months[simulationMonth].name; buffer << monthName[0] << monthName[1] << monthName[2] << '\t'; buffer << '\t'; @@ -293,7 +292,7 @@ void HydroManagement::prepareMonthlyOptimalGenerations(double* random_reservoir_ buffer << '\n'; } auto content = buffer.str(); - writer->addEntryFromBuffer(path.str(), content); + resultWriter_->addEntryFromBuffer(path.str(), content); } }); } diff --git a/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp b/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp index a2212727a0..a1cd932a88 100644 --- a/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.cpp @@ -32,7 +32,6 @@ #include "../simulation/adequacy_patch_runtime_data.h" #include -#include "../study/area/scratchpad.h" using namespace Yuni; diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp index 0be004cc3f..21b7a0712e 100644 --- a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp +++ b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.cpp @@ -29,7 +29,6 @@ #include "../opt_fonctions.h" #include "../simulation/simulation.h" #include "../simulation/adequacy_patch_runtime_data.h" -#include "antares/study/area/scratchpad.h" #include "antares/study/fwd.h" using namespace Antares::Data::AdequacyPatch; @@ -42,10 +41,8 @@ AdequacyPatchOptimization::AdequacyPatchOptimization(const Antares::Data::Study& PROBLEME_HEBDO* problemeHebdo, AdqPatchParams& adqPatchParams, uint thread_number, - IResultWriter& writer, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) : - WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer), study_(study), - valeursGenereesParPays_(valeursGenereesParPays) + IResultWriter& writer) : + WeeklyOptimization(options, problemeHebdo, adqPatchParams, thread_number, writer), study_(study) { } @@ -65,11 +62,7 @@ void AdequacyPatchOptimization::solve(uint weekInTheYear, int hourInTheYear) std::fill(problemeHebdo_->ResultatsHoraires[pays].ValeursHorairesDENS.begin(), problemeHebdo_->ResultatsHoraires[pays].ValeursHorairesDENS.end(), 0); } - - // TODO check if we need to cut SIM_RenseignementProblemeHebdo and just pick out the - // part that we need - ::SIM_RenseignementProblemeHebdo(study_, *problemeHebdo_, weekInTheYear, thread_number_, - hourInTheYear, valeursGenereesParPays_); + OPT_OptimisationHebdomadaire(options_, problemeHebdo_, adqPatchParams_, writer_); } diff --git a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h index 74adcd0b2c..d62c53a10c 100644 --- a/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h +++ b/src/solver/optimisation/adequacy_patch_local_matching/adequacy_patch_weekly_optimization.h @@ -44,13 +44,11 @@ class AdequacyPatchOptimization : public WeeklyOptimization PROBLEME_HEBDO* problemeHebdo, Antares::Data::AdequacyPatch::AdqPatchParams&, uint numSpace, - IResultWriter& writer, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays); + IResultWriter& writer); ~AdequacyPatchOptimization() override = default; void solve(uint weekInTheYear, int hourInTheYear) override; private: const Antares::Data::Study& study_; - const VAL_GEN_PAR_PAYS& valeursGenereesParPays_; }; } // namespace Antares::Solver::Optimization diff --git a/src/solver/optimisation/base_weekly_optimization.cpp b/src/solver/optimisation/base_weekly_optimization.cpp index bd53942306..a808444861 100644 --- a/src/solver/optimisation/base_weekly_optimization.cpp +++ b/src/solver/optimisation/base_weekly_optimization.cpp @@ -53,11 +53,10 @@ std::unique_ptr WeeklyOptimization::create( AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemeHebdo, uint thread_number, - IResultWriter& writer, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) + IResultWriter& writer) { if (adqPatchParams.enabled && adqPatchParams.localMatching.enabled) - return std::make_unique(study, options, problemeHebdo, adqPatchParams, thread_number, writer, valeursGenereesParPays); + return std::make_unique(study, options, problemeHebdo, adqPatchParams, thread_number, writer); else return std::make_unique(options, problemeHebdo, adqPatchParams, thread_number, writer); } diff --git a/src/solver/optimisation/base_weekly_optimization.h b/src/solver/optimisation/base_weekly_optimization.h index cc47836b69..41fa3fa43d 100644 --- a/src/solver/optimisation/base_weekly_optimization.h +++ b/src/solver/optimisation/base_weekly_optimization.h @@ -44,8 +44,7 @@ class WeeklyOptimization Antares::Data::AdequacyPatch::AdqPatchParams& adqPatchParams, PROBLEME_HEBDO* problemesHebdo, uint numSpace, - IResultWriter& writer, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays); + IResultWriter& writer); protected: explicit WeeklyOptimization(const OptimizationOptions& options, diff --git a/src/solver/simulation/adequacy.cpp b/src/solver/simulation/adequacy.cpp index 2610ffc18a..a1ee2a9082 100644 --- a/src/solver/simulation/adequacy.cpp +++ b/src/solver/simulation/adequacy.cpp @@ -64,7 +64,7 @@ void Adequacy::initializeState(Variable::State& state, uint numSpace) } // valGen maybe_unused to match simulationBegin() declaration in economy.cpp -bool Adequacy::simulationBegin([[maybe_unused]] const VAL_GEN_PAR_PAYS& valeursGenereesParPays) +bool Adequacy::simulationBegin() { if (!preproOnly) { @@ -91,8 +91,9 @@ bool Adequacy::simulationBegin([[maybe_unused]] const VAL_GEN_PAR_PAYS& valeursG return true; } -bool Adequacy::simplexIsRequired(uint hourInTheYear, uint numSpace, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) const +bool Adequacy::simplexIsRequired(uint hourInTheYear, + uint numSpace, + const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) const { uint areaCount = study.areas.size(); uint indx = hourInTheYear; @@ -101,13 +102,13 @@ bool Adequacy::simplexIsRequired(uint hourInTheYear, uint numSpace, { uint dayInTheYear = study.calendar.hours[indx].dayYear; - for (uint k = 0; k != areaCount; ++k) + for (uint areaIdx = 0; areaIdx != areaCount; ++areaIdx) { - auto& valgen = valeursGenereesParPays[numSpace][k]; + auto& hydroVentilation = hydroVentilationResults[numSpace][areaIdx]; double quantity - = pProblemesHebdo[numSpace].ConsommationsAbattues[j].ConsommationAbattueDuPays[k] - - valgen.HydrauliqueModulableQuotidien[dayInTheYear] / 24.; + = pProblemesHebdo[numSpace].ConsommationsAbattues[j].ConsommationAbattueDuPays[areaIdx] + - hydroVentilation.HydrauliqueModulableQuotidien[dayInTheYear] / 24.; if (quantity > 0.) return true; // Call to the solver is required to find an optimal solution @@ -123,7 +124,7 @@ bool Adequacy::year(Progression::Task& progression, yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) + const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { // No failed week at year start failedWeekList.clear(); @@ -146,16 +147,18 @@ bool Adequacy::year(Progression::Task& progression, pProblemesHebdo[numSpace].weekInTheYear = state.weekInTheYear = w; pProblemesHebdo[numSpace].HeureDansLAnnee = hourInTheYear; - ::SIM_RenseignementProblemeHebdo(study, - pProblemesHebdo[numSpace], state.weekInTheYear, numSpace, hourInTheYear, - valeursGenereesParPays); + ::SIM_RenseignementProblemeHebdo(study, pProblemesHebdo[numSpace], state.weekInTheYear, + numSpace, hourInTheYear, hydroVentilationResults); + + BuildThermalPartOfWeeklyProblem(study, pProblemesHebdo[numSpace], + numSpace, hourInTheYear, randomForYear.pThermalNoisesByArea); // Reinit optimisation if needed pProblemesHebdo[numSpace].ReinitOptimisation = reinitOptim; reinitOptim = false; - state.simplexHasBeenRan = (w == 0) || simplexIsRequired(hourInTheYear, numSpace, valeursGenereesParPays); - if (state.simplexHasBeenRan) // Call to Solver is mandatory for the first week and optional + state.simplexRunNeeded = (w == 0) || simplexIsRequired(hourInTheYear, numSpace, hydroVentilationResults); + if (state.simplexRunNeeded) // Call to Solver is mandatory for the first week and optional // otherwise { uint nbAreas = study.areas.size(); @@ -289,14 +292,14 @@ bool Adequacy::year(Progression::Task& progression, { assert(k < state.resSpilled.width); assert(j < state.resSpilled.height); - auto& valgen = valeursGenereesParPays[numSpace][k]; + auto& hydroVentilation = hydroVentilationResults[numSpace][k]; auto& hourlyResults = pProblemesHebdo[numSpace].ResultatsHoraires[k]; hourlyResults.TurbinageHoraire[j] - = valgen.HydrauliqueModulableQuotidien[dayInTheYear] / 24.; + = hydroVentilation.HydrauliqueModulableQuotidien[dayInTheYear] / 24.; state.resSpilled[k][j] - = +valgen.HydrauliqueModulableQuotidien[dayInTheYear] / 24. + = +hydroVentilation.HydrauliqueModulableQuotidien[dayInTheYear] / 24. - pProblemesHebdo[numSpace] .ConsommationsAbattues[j] .ConsommationAbattueDuPays[k]; diff --git a/src/solver/simulation/adequacy.h b/src/solver/simulation/adequacy.h index cf53193aad..6e052eb5d6 100644 --- a/src/solver/simulation/adequacy.h +++ b/src/solver/simulation/adequacy.h @@ -73,7 +73,7 @@ class Adequacy protected: void setNbPerformedYearsInParallel(uint nbMaxPerformedYearsInParallel); - bool simulationBegin(const VAL_GEN_PAR_PAYS& valeursGenereesParPays); + bool simulationBegin(); bool year(Progression::Task& progression, Variable::State& state, @@ -81,7 +81,7 @@ class Adequacy yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays); + const ALL_HYDRO_VENTILATION_RESULTS&); void incrementProgression(Progression::Task& progression); @@ -95,8 +95,9 @@ class Adequacy void initializeState(Variable::State& state, uint numSpace); private: - bool simplexIsRequired(uint hourInTheYear, uint numSpace, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) const; + bool simplexIsRequired(uint hourInTheYear, + uint numSpace, + const ALL_HYDRO_VENTILATION_RESULTS&) const; uint pNbWeeks; uint pStartTime; diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp index 4b60eddeb7..4252bb33fc 100644 --- a/src/solver/simulation/common-eco-adq.cpp +++ b/src/solver/simulation/common-eco-adq.cpp @@ -190,13 +190,12 @@ bool ShouldUseQuadraticOptimisation(const Data::Study& study) if (!flowQuadEnabled) return false; - uint maxHours = study.runtime->nbHoursPerYear; for (uint j = 0; j < study.runtime->interconnectionsCount(); ++j) { auto& lnk = *(study.runtime->areaLink[j]); auto& impedances = lnk.parameters[Data::fhlImpedances]; - for (uint hour = 0; hour < maxHours; ++hour) + for (uint hour = 0; hour < HOURS_PER_YEAR; ++hour) { if (Math::Abs(impedances[hour]) >= 1e-100) { @@ -301,6 +300,44 @@ void PrepareRandomNumbers(Data::Study& study, } problem.CoutDeDefaillanceNegative[area.index] = area.thermal.spilledEnergyCost + alea; + + //----------------------------- + // Thermal noises + //----------------------------- + auto end = area.thermal.list.mapping.end(); + for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) + { + auto cluster = it->second; + if (!cluster->enabled) + continue; + uint clusterIndex = cluster->areaWideIndex; + double& rnd = randomForYear.pThermalNoisesByArea[indexArea][clusterIndex]; + double randomClusterProdCost(0.); + if (cluster->spreadCost == 0) // 5e-4 < |randomClusterProdCost| < 6e-4 + { + if (rnd < 0.5) + randomClusterProdCost = 1e-4 * (5 + 2 * rnd); + else + randomClusterProdCost = -1e-4 * (5 + 2 * (rnd - 0.5)); + } + else + { + randomClusterProdCost = (rnd - 0.5) * (cluster->spreadCost); + + if (Math::Abs(randomClusterProdCost) < 5.e-4) + { + if (Math::Abs(randomClusterProdCost) >= 0) + randomClusterProdCost += 5.e-4; + else + randomClusterProdCost -= 5.e-4; + } + } + rnd = randomClusterProdCost; + } + + //----------------------------- + // Hydro noises + //----------------------------- auto& noise = problem.BruitSurCoutHydraulique[area.index]; switch (study.parameters.power.fluctuations) { @@ -345,6 +382,57 @@ void PrepareRandomNumbers(Data::Study& study, }); } +void BuildThermalPartOfWeeklyProblem(Data::Study& study, + PROBLEME_HEBDO& problem, + uint numSpace, + const int PasDeTempsDebut, + double** thermalNoises) +{ + int hourInYear = PasDeTempsDebut; + const uint nbPays = study.areas.size(); + for (unsigned hourInWeek = 0; hourInWeek < problem.NombreDePasDeTemps; ++hourInWeek, ++hourInYear) + { + for (uint areaIdx = 0; areaIdx < nbPays; ++areaIdx) + { + auto& area = *study.areas.byIndex[areaIdx]; + auto& tsIndex = NumeroChroniquesTireesParPays[numSpace][areaIdx]; + area.thermal.list.each([&](const Data::ThermalCluster& cluster) + { + auto& Pt = problem.PaliersThermiquesDuPays[areaIdx] + .PuissanceDisponibleEtCout[cluster.index]; + + Pt.CoutHoraireDeProductionDuPalierThermique[hourInWeek] = + cluster.getMarketBidCost(tsIndex.ThermiqueParPalier[cluster.areaWideIndex], hourInYear) + + thermalNoises[areaIdx][cluster.areaWideIndex]; + + Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] + = cluster.series + ->timeSeries[tsIndex.ThermiqueParPalier[cluster.areaWideIndex]][hourInYear]; + + Pt.PuissanceMinDuPalierThermique[hourInWeek] + = (Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] < cluster.PthetaInf[hourInYear]) + ? Pt.PuissanceDisponibleDuPalierThermique[hourInWeek] + : cluster.PthetaInf[hourInYear]; + }); + } + } + + for (uint k = 0; k < nbPays; ++k) + { + auto& area = *study.areas.byIndex[k]; + + for (uint l = 0; l != area.thermal.list.size(); ++l) + { + problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[l] + .PuissanceDisponibleDuPalierThermiqueRef + = + problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[l] + .PuissanceDisponibleDuPalierThermique; + } + } + +} + int retrieveAverageNTC(const Data::Study& study, const Matrix<>& capacities, const Matrix& tsNumbers, diff --git a/src/solver/simulation/common-eco-adq.h b/src/solver/simulation/common-eco-adq.h index af5cf17de2..91b4a0b175 100644 --- a/src/solver/simulation/common-eco-adq.h +++ b/src/solver/simulation/common-eco-adq.h @@ -62,6 +62,12 @@ void PrepareRandomNumbers(Data::Study& study, PROBLEME_HEBDO& problem, yearRandomNumbers& randomForYear); +void BuildThermalPartOfWeeklyProblem(Data::Study& study, + PROBLEME_HEBDO& problem, + uint numSpace, + const int PasDeTempsDebut, + double** thermalNoises); + /*! ** \brief Prepare data from clusters in mustrun mode (eco+adq) */ diff --git a/src/solver/simulation/economy.cpp b/src/solver/simulation/economy.cpp index 06aa2ac5a1..62a9f0cc4e 100644 --- a/src/solver/simulation/economy.cpp +++ b/src/solver/simulation/economy.cpp @@ -66,7 +66,7 @@ void Economy::initializeState(Variable::State& state, uint numSpace) state.numSpace = numSpace; } -bool Economy::simulationBegin(const VAL_GEN_PAR_PAYS& valeursGenereesParPays) +bool Economy::simulationBegin() { if (!preproOnly) { @@ -92,8 +92,7 @@ bool Economy::simulationBegin(const VAL_GEN_PAR_PAYS& valeursGenereesParPays) study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], numSpace, - *study.resultWriter, - valeursGenereesParPays); + *study.resultWriter); postProcessesList_[numSpace] = interfacePostProcessList::create(study.parameters.adqPatchParams, &pProblemesHebdo[numSpace], @@ -120,7 +119,7 @@ bool Economy::year(Progression::Task& progression, yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - VAL_GEN_PAR_PAYS& valeursGenereesParPays) + const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { // No failed week at year start failedWeekList.clear(); @@ -143,9 +142,11 @@ bool Economy::year(Progression::Task& progression, pProblemesHebdo[numSpace].weekInTheYear = state.weekInTheYear = w; pProblemesHebdo[numSpace].HeureDansLAnnee = hourInTheYear; - ::SIM_RenseignementProblemeHebdo(state.study, - pProblemesHebdo[numSpace], state.weekInTheYear, numSpace, hourInTheYear, - valeursGenereesParPays); + ::SIM_RenseignementProblemeHebdo(study, pProblemesHebdo[numSpace], state.weekInTheYear, + numSpace, hourInTheYear, hydroVentilationResults); + + BuildThermalPartOfWeeklyProblem(study, pProblemesHebdo[numSpace], + numSpace, hourInTheYear, randomForYear.pThermalNoisesByArea); // Reinit optimisation if needed pProblemesHebdo[numSpace].ReinitOptimisation = reinitOptim; diff --git a/src/solver/simulation/economy.h b/src/solver/simulation/economy.h index 421b961524..3d4d92277a 100644 --- a/src/solver/simulation/economy.h +++ b/src/solver/simulation/economy.h @@ -74,7 +74,7 @@ class Economy protected: void setNbPerformedYearsInParallel(uint nbMaxPerformedYearsInParallel); - bool simulationBegin(const VAL_GEN_PAR_PAYS& valeursGenereesParPays); + bool simulationBegin(); bool year(Progression::Task& progression, Variable::State& state, @@ -82,7 +82,7 @@ class Economy yearRandomNumbers& randomForYear, std::list& failedWeekList, bool isFirstPerformedYearOfSimulation, - VAL_GEN_PAR_PAYS& valeursGenereesParPays); + const ALL_HYDRO_VENTILATION_RESULTS&); void incrementProgression(Progression::Task& progression); diff --git a/src/solver/simulation/sim_allocation_tableaux.cpp b/src/solver/simulation/sim_allocation_tableaux.cpp index e3405e62ef..ae4734862d 100644 --- a/src/solver/simulation/sim_allocation_tableaux.cpp +++ b/src/solver/simulation/sim_allocation_tableaux.cpp @@ -39,8 +39,7 @@ static void AllocateResultsForEconomicMode(const Data::Study& study) transitMoyenInterconnexionsRecalculQuadratique.resize(study.runtime->interconnectionsCount()); for (uint i = 0; i != study.runtime->interconnectionsCount(); i++) - transitMoyenInterconnexionsRecalculQuadratique[i] - .assign(study.runtime->nbHoursPerYear , 0.); + transitMoyenInterconnexionsRecalculQuadratique[i].assign(HOURS_PER_YEAR, 0.); } void SIM_AllocationTableaux(const Data::Study& study) diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index d4a9e5b504..75bba4aa43 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -314,7 +314,8 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, } void preparerBindingConstraint(const PROBLEME_HEBDO &problem, uint numSpace, int PasDeTempsDebut, - const BindingConstraintsRepository &bindingConstraints, const uint weekFirstDay, int pasDeTemps) { + const BindingConstraintsRepository &bindingConstraints, const uint weekFirstDay, int pasDeTemps) +{ auto activeContraints = bindingConstraints.activeContraints(); const auto constraintCount = activeContraints.size(); for (unsigned constraintIndex = 0; constraintIndex != constraintCount; ++constraintIndex) @@ -379,7 +380,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, uint weekInTheYear, uint numSpace, const int PasDeTempsDebut, - const VAL_GEN_PAR_PAYS& valeursGenereesParPays) + const ALL_HYDRO_VENTILATION_RESULTS& hydroVentilationResults) { const auto& parameters = study.parameters; auto& studyruntime = *study.runtime; @@ -388,8 +389,6 @@ void SIM_RenseignementProblemeHebdo(const Study& study, const uint weekFirstDay = study.calendar.hours[PasDeTempsDebut].dayYear; - int indx = PasDeTempsDebut; - for (int opt = 0; opt < 7; opt++) { problem.coutOptimalSolution1[opt] = 0.; @@ -538,9 +537,11 @@ void SIM_RenseignementProblemeHebdo(const Study& study, } } - for (unsigned j = 0; j < problem.NombreDePasDeTemps; ++j, ++indx) + int hourInYear = PasDeTempsDebut; + + for (unsigned hourInWeek = 0; hourInWeek < problem.NombreDePasDeTemps; ++hourInWeek, ++hourInYear) { - VALEURS_DE_NTC_ET_RESISTANCES& ntc = problem.ValeursDeNTC[j]; + VALEURS_DE_NTC_ET_RESISTANCES& ntc = problem.ValeursDeNTC[hourInWeek]; { uint linkCount = studyruntime.interconnectionsCount(); for (uint k = 0; k != linkCount; ++k) @@ -549,18 +550,18 @@ void SIM_RenseignementProblemeHebdo(const Study& study, const int tsIndex = NumeroChroniquesTireesParInterconnexion[numSpace][k].TransmissionCapacities; - assert((uint)indx < lnk.directCapacities.height); + assert((uint)hourInYear < lnk.directCapacities.height); assert((uint)tsIndex < lnk.directCapacities.width); assert((uint)tsIndex < lnk.indirectCapacities.width); - ntc.ValeurDeNTCOrigineVersExtremite[k] = lnk.directCapacities[tsIndex][indx]; - ntc.ValeurDeNTCExtremiteVersOrigine[k] = lnk.indirectCapacities[tsIndex][indx]; - ntc.ValeurDeLoopFlowOrigineVersExtremite[k] = lnk.parameters[fhlLoopFlow][indx]; + ntc.ValeurDeNTCOrigineVersExtremite[k] = lnk.directCapacities[tsIndex][hourInYear]; + ntc.ValeurDeNTCExtremiteVersOrigine[k] = lnk.indirectCapacities[tsIndex][hourInYear]; + ntc.ValeurDeLoopFlowOrigineVersExtremite[k] = lnk.parameters[fhlLoopFlow][hourInYear]; } } - preparerBindingConstraint(problem, numSpace, PasDeTempsDebut, study.bindingConstraints, weekFirstDay, j); + preparerBindingConstraint(problem, numSpace, PasDeTempsDebut, study.bindingConstraints, weekFirstDay, hourInWeek); - const uint dayInTheYear = study.calendar.hours[indx].dayYear; + const uint dayInTheYear = study.calendar.hours[hourInYear].dayYear; for (uint k = 0; k < nbPays; ++k) { @@ -570,88 +571,63 @@ void SIM_RenseignementProblemeHebdo(const Study& study, auto& ror = area.hydro.series->ror; assert(&scratchpad); - assert((uint)indx < scratchpad.ts.load.height); + assert((uint)hourInYear < scratchpad.ts.load.height); assert((uint)tsIndex.Consommation < scratchpad.ts.load.width); if (parameters.renewableGeneration.isAggregated()) { - assert((uint)indx < scratchpad.ts.solar.height); - assert((uint)indx < scratchpad.ts.wind.height); + assert((uint)hourInYear < scratchpad.ts.solar.height); + assert((uint)hourInYear < scratchpad.ts.wind.height); assert((uint)tsIndex.Eolien < scratchpad.ts.wind.width); assert((uint)tsIndex.Solar < scratchpad.ts.solar.width); } uint tsFatalIndex = (uint)tsIndex.Hydraulique < ror.width ? tsIndex.Hydraulique : 0; - double& mustRunGen = problem.AllMustRunGeneration[j].AllMustRunGenerationOfArea[k]; + double& mustRunGen = problem.AllMustRunGeneration[hourInWeek].AllMustRunGenerationOfArea[k]; if (parameters.renewableGeneration.isAggregated()) { - mustRunGen = scratchpad.ts.wind[tsIndex.Eolien][indx] - + scratchpad.ts.solar[tsIndex.Solar][indx] - + scratchpad.miscGenSum[indx] + ror[tsFatalIndex][indx] - + scratchpad.mustrunSum[indx]; + mustRunGen = scratchpad.ts.wind[tsIndex.Eolien][hourInYear] + + scratchpad.ts.solar[tsIndex.Solar][hourInYear] + + scratchpad.miscGenSum[hourInYear] + ror[tsFatalIndex][hourInYear] + + scratchpad.mustrunSum[hourInYear]; } // Renewable if (parameters.renewableGeneration.isClusters()) { - mustRunGen = scratchpad.miscGenSum[indx] + ror[tsFatalIndex][indx] - + scratchpad.mustrunSum[indx]; + mustRunGen = scratchpad.miscGenSum[hourInYear] + ror[tsFatalIndex][hourInYear] + + scratchpad.mustrunSum[hourInYear]; area.renewable.list.each([&](const RenewableCluster& cluster) { assert(cluster.series->timeSeries.jit == NULL && "No JIT data from the solver"); mustRunGen += cluster.valueAtTimeStep( - tsIndex.RenouvelableParPalier[cluster.areaWideIndex], (uint)indx); + tsIndex.RenouvelableParPalier[cluster.areaWideIndex], (uint)hourInYear); }); } assert( - !Math::NaN(problem.AllMustRunGeneration[j].AllMustRunGenerationOfArea[k]) + !Math::NaN(problem.AllMustRunGeneration[hourInWeek].AllMustRunGenerationOfArea[k]) && "NaN detected for 'AllMustRunGeneration', probably from miscGenSum/mustrunSum"); - problem.ConsommationsAbattues[j].ConsommationAbattueDuPays[k] - = +scratchpad.ts.load[tsIndex.Consommation][indx] - - problem.AllMustRunGeneration[j].AllMustRunGenerationOfArea[k]; - - area.thermal.list.each([&](const Data::ThermalCluster& cluster) { - assert((uint)tsIndex.ThermiqueParPalier[cluster.areaWideIndex] - < cluster.series->timeSeries.width); - assert((uint)indx < cluster.series->timeSeries.height); - assert(cluster.series->timeSeries.jit == NULL && "No JIT data from the solver"); - - auto& Pt - = problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[cluster.index]; - auto& PtValGen = valeursGenereesParPays[numSpace][k]; - - Pt.PuissanceDisponibleDuPalierThermique[j] - = cluster.series - ->timeSeries[tsIndex.ThermiqueParPalier[cluster.areaWideIndex]][indx]; - - Pt.CoutHoraireDeProductionDuPalierThermique[j] - = cluster.getMarketBidCost(tsIndex.ThermiqueParPalier[cluster.areaWideIndex], - indx) - + PtValGen.AleaCoutDeProductionParPalier[cluster.areaWideIndex]; - - Pt.PuissanceMinDuPalierThermique[j] - = (Pt.PuissanceDisponibleDuPalierThermique[j] < cluster.PthetaInf[indx]) - ? Pt.PuissanceDisponibleDuPalierThermique[j] - : cluster.PthetaInf[indx]; - }); + problem.ConsommationsAbattues[hourInWeek].ConsommationAbattueDuPays[k] + = +scratchpad.ts.load[tsIndex.Consommation][hourInYear] + - problem.AllMustRunGeneration[hourInWeek].AllMustRunGenerationOfArea[k]; if (problem.CaracteristiquesHydrauliques[k].PresenceDHydrauliqueModulable > 0) { - problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxHydrauliqueHoraire[j] + problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxHydrauliqueHoraire[hourInWeek] = scratchpad.optimalMaxPower[dayInTheYear] * problem.CaracteristiquesHydrauliques[k].WeeklyGeneratingModulation; } if (problem.CaracteristiquesHydrauliques[k].PresenceDePompageModulable) { - problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxPompageHoraire[j] + problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxPompageHoraire[hourInWeek] = scratchpad.pumpingMaxPower[dayInTheYear] * problem.CaracteristiquesHydrauliques[k].WeeklyPumpingModulation; } - problem.ReserveJMoins1[k].ReserveHoraireJMoins1[j] - = area.reserves[fhrDayBefore][PasDeTempsDebut + j]; + problem.ReserveJMoins1[k].ReserveHoraireJMoins1[hourInWeek] + = area.reserves[fhrDayBefore][PasDeTempsDebut + hourInWeek]; } } @@ -664,15 +640,12 @@ void SIM_RenseignementProblemeHebdo(const Study& study, uint tsIndex = (NumeroChroniquesTireesParPays[numSpace][k]).Hydraulique; auto& inflowsmatrix = area.hydro.series->storage; auto const& srcinflows = inflowsmatrix[tsIndex < inflowsmatrix.width ? tsIndex : 0]; - { auto& mingenmatrix = area.hydro.series->mingen; - auto const& srcmingen - = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; - for (uint j = 0; j < problem.NombreDePasDeTemps; ++j) - { - problem.CaracteristiquesHydrauliques[k].MingenHoraire[j] - = srcmingen[PasDeTempsDebut + j]; - } + auto const& srcmingen = mingenmatrix[tsIndex < mingenmatrix.width ? tsIndex : 0]; + for (uint j = 0; j < problem.NombreDePasDeTemps; ++j) + { + problem.CaracteristiquesHydrauliques[k].MingenHoraire[j] + = srcmingen[PasDeTempsDebut + j]; } if (area.hydro.reservoirManagement) @@ -709,7 +682,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, .MinEnergieHydrauParIntervalleOptimise; const std::vector& DNT - = valeursGenereesParPays[numSpace][k].HydrauliqueModulableQuotidien; + = hydroVentilationResults[numSpace][k].HydrauliqueModulableQuotidien; double WSL = problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir; @@ -798,7 +771,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 += valeursGenereesParPays[numSpace][k] + weekTarget_tmp += hydroVentilationResults[numSpace][k] .HydrauliqueModulableQuotidien[day]; } @@ -819,7 +792,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, uint day = study.calendar.hours[PasDeTempsDebut + j * 24].dayYear; problem.CaracteristiquesHydrauliques[k] .CntEnergieH2OParIntervalleOptimise[j] - = valeursGenereesParPays[numSpace][k].HydrauliqueModulableQuotidien[day] + = hydroVentilationResults[numSpace][k].HydrauliqueModulableQuotidien[day] * problem.CaracteristiquesHydrauliques[k].WeeklyGeneratingModulation * marginGen / weekGenerationTarget; } @@ -933,17 +906,6 @@ void SIM_RenseignementProblemeHebdo(const Study& study, for (uint k = 0; k < nbPays; ++k) { - auto& area = *study.areas.byIndex[k]; - - for (uint l = 0; l != area.thermal.list.size(); ++l) - { - problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[l] - .PuissanceDisponibleDuPalierThermiqueRef - = - problem.PaliersThermiquesDuPays[k].PuissanceDisponibleEtCout[l] - .PuissanceDisponibleDuPalierThermique; - } - problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxHydrauliqueHoraireRef = problem.CaracteristiquesHydrauliques[k].ContrainteDePmaxHydrauliqueHoraire; } diff --git a/src/solver/simulation/sim_structure_donnees.h b/src/solver/simulation/sim_structure_donnees.h index d9883410d1..5356732f63 100644 --- a/src/solver/simulation/sim_structure_donnees.h +++ b/src/solver/simulation/sim_structure_donnees.h @@ -44,16 +44,6 @@ typedef struct int TransmissionCapacities; } NUMERO_CHRONIQUES_TIREES_PAR_INTERCONNEXION; -typedef struct -{ - std::vector HydrauliqueModulableQuotidien; /* indice par jour */ - std::vector AleaCoutDeProductionParPalier; /* epsilon sur le cout de production */ - std::vector NiveauxReservoirsDebutJours; //Niveaux (quotidiens) du reservoir de début - //de jour (en cas de gestion des reservoirs). - std::vector NiveauxReservoirsFinJours; //Niveaux (quotidiens) du reservoir de fin - //de jour (en cas de gestion des reservoirs). -} VALEURS_GENEREES_PAR_PAYS; - typedef struct { double* Horaire; @@ -64,9 +54,6 @@ typedef struct double* ParLigne; } MATRICE_2D; -// vector of [numSpace][area] -using VAL_GEN_PAR_PAYS = std::vector>; - /* Old define */ #define DEFINITION_STRUCTURES_DONNEES diff --git a/src/solver/simulation/simulation.h b/src/solver/simulation/simulation.h index 147aac51b5..b105059bc3 100644 --- a/src/solver/simulation/simulation.h +++ b/src/solver/simulation/simulation.h @@ -30,6 +30,7 @@ #include "../config.h" #include "sim_structure_donnees.h" #include +#include "../solver/hydro/management.h" struct PROBLEME_HEBDO; @@ -57,7 +58,7 @@ void SIM_RenseignementProblemeHebdo(const Antares::Data::Study& study, uint weekInTheYear, uint numSpace, const int, - const VAL_GEN_PAR_PAYS&); + const ALL_HYDRO_VENTILATION_RESULTS&); void SIM_RenseignementProblemeHoraireAdequation(uint); diff --git a/src/solver/simulation/solver.h b/src/solver/simulation/solver.h index 426026a6c5..96d0b9d74b 100644 --- a/src/solver/simulation/solver.h +++ b/src/solver/simulation/solver.h @@ -157,7 +157,7 @@ class ISimulation : public Impl //! Year by year output results bool pYearByYear; //! Hydro management - HydroManagement pHydroManagement; + HydroManagement hydroManagement; //! Hydro hot start bool pHydroHotStart; //! The first set of parallel year(s) with a performed year was already run ? @@ -169,8 +169,6 @@ class ISimulation : public Impl // Collecting durations inside the simulation Benchmarking::IDurationCollector& pDurationCollector; - VAL_GEN_PAR_PAYS valeursGenereesParPays; - public: //! The queue service that runs every set of parallel years std::shared_ptr pQueueService = nullptr; diff --git a/src/solver/simulation/solver.hxx b/src/solver/simulation/solver.hxx index 8e24899a11..9ec95d06a1 100644 --- a/src/solver/simulation/solver.hxx +++ b/src/solver/simulation/solver.hxx @@ -47,11 +47,12 @@ namespace Antares::Solver::Simulation { + template class yearJob final : public Yuni::Job::IJob { public: - yearJob(ISimulation* pSimulationObj, + yearJob(ISimulation* simulation, unsigned int pY, std::map& pYearFailed, std::map& pIsFirstPerformedYearOfASet, @@ -63,7 +64,7 @@ public: std::vector& pState, bool pYearByYear, Benchmarking::IDurationCollector& durationCollector) : - simulationObj(pSimulationObj), + simulation_(simulation), y(pY), yearFailed(pYearFailed), isFirstPerformedYearOfASet(pIsFirstPerformedYearOfASet), @@ -80,7 +81,7 @@ public: } private: - ISimulation* simulationObj; + ISimulation* simulation_; unsigned int y; std::map& yearFailed; std::map& isFirstPerformedYearOfASet; @@ -141,9 +142,9 @@ private: // Getting random tables for this year yearRandomNumbers& randomForCurrentYear = randomForParallelYears.pYears[indexYear]; - double const* const* thermalNoisesByArea = randomForCurrentYear.pThermalNoisesByArea; double* randomReservoirLevel = nullptr; + // 1 - Applying random levels for current year if (hydroHotStart && firstSetParallelWithAPerformedYearWasRun) randomReservoirLevel = state[numSpace].problemeHebdo->previousYearFinalLevels.data(); else @@ -151,17 +152,18 @@ private: // 2 - Preparing the Time-series numbers // We want to draw lots of numbers for time-series - ALEA_TirageAuSortChroniques(study, thermalNoisesByArea, numSpace, - simulationObj->valeursGenereesParPays); + ApplyRandomTSnumbers(study, y, numSpace); // 3 - Preparing data related to Clusters in 'must-run' mode - simulationObj->prepareClustersInMustRunMode(numSpace); + simulation_->prepareClustersInMustRunMode(numSpace); // 4 - Hydraulic ventilation { Benchmarking::Timer timer; - simulationObj->pHydroManagement(randomReservoirLevel, state[numSpace], y, - numSpace, simulationObj->valeursGenereesParPays); + simulation_->hydroManagement.makeVentilation(randomReservoirLevel, + state[numSpace], + y, + numSpace); timer.stop(); pDurationCollector.addDuration("hydro_ventilation", timer.get_duration()); } @@ -170,52 +172,51 @@ private: state[numSpace].year = y; // 5 - Resetting all variables for the output - simulationObj->variables.yearBegin(y, numSpace); + simulation_->variables.yearBegin(y, numSpace); // 6 - The Solver itself bool isFirstPerformedYearOfSimulation = isFirstPerformedYearOfASet[y] && not firstSetParallelWithAPerformedYearWasRun; std::list failedWeekList; - yearFailed[y] = !simulationObj->year(progression, - state[numSpace], - numSpace, - randomForCurrentYear, - failedWeekList, - isFirstPerformedYearOfSimulation, - simulationObj->valeursGenereesParPays); + yearFailed[y] = !simulation_->year(progression, + state[numSpace], + numSpace, + randomForCurrentYear, + failedWeekList, + isFirstPerformedYearOfSimulation, + simulation_->hydroManagement.ventilationResults()); // Log failing weeks logFailedWeek(y, study, failedWeekList); - simulationObj->variables.yearEndBuild(state[numSpace], y, numSpace); + simulation_->variables.yearEndBuild(state[numSpace], y, numSpace); // 7 - End of the year, this is the last stade where the variables can retrieve // their data for this year. - simulationObj->variables.yearEnd(y, numSpace); + simulation_->variables.yearEnd(y, numSpace); // 8 - Spatial clusters // Notifying all variables to perform spatial aggregates. // This must be done only when all variables have finished to compute their // data for the year. - simulationObj->variables.yearEndSpatialAggregates( - simulationObj->variables, y, numSpace); + simulation_->variables.yearEndSpatialAggregates(simulation_->variables, y, numSpace); // 9 - Write results for the current year if (yearByYear) { Benchmarking::Timer timerYear; // Before writing, some variable may require minor modifications - simulationObj->variables.beforeYearByYearExport(y, numSpace); + simulation_->variables.beforeYearByYearExport(y, numSpace); // writing the results for the current year into the output - simulationObj->writeResults(false, y, numSpace); // false for synthesis + simulation_->writeResults(false, y, numSpace); // false for synthesis timerYear.stop(); pDurationCollector.addDuration("yby_export", timerYear.get_duration()); } } else { - simulationObj->incrementProgression(progression); + simulation_->incrementProgression(progression); logs.info() << " playlist: ignoring the year " << (y + 1); @@ -228,19 +229,23 @@ private: template inline ISimulation::ISimulation(Data::Study& study, - const ::Settings& settings, - Benchmarking::IDurationCollector& duration_collector) : - ImplementationType(study), - study(study), - settings(settings), - pNbYearsReallyPerformed(0), - pNbMaxPerformedYearsInParallel(0), - pYearByYear(study.parameters.yearByYear), - pHydroManagement(study), - pFirstSetParallelWithAPerformedYearWasRun(false), - pDurationCollector(duration_collector), - pQueueService(study.pQueueService), - pResultWriter(study.resultWriter) + const ::Settings& settings, + Benchmarking::IDurationCollector& duration_collector) : + ImplementationType(study), + study(study), + settings(settings), + pNbYearsReallyPerformed(0), + pNbMaxPerformedYearsInParallel(0), + pYearByYear(study.parameters.yearByYear), + hydroManagement(study.areas, + study.parameters, + study.calendar, + study.maxNbYearsInParallel, + study.resultWriter), + pFirstSetParallelWithAPerformedYearWasRun(false), + pDurationCollector(duration_collector), + pQueueService(study.pQueueService), + pResultWriter(study.resultWriter) { // Ask to the interface to show the messages logs.info(); @@ -276,33 +281,6 @@ inline ISimulation::~ISimulation() { } -static void allocateValeursGenereesParPays(VAL_GEN_PAR_PAYS& val, - const Data::Study& study) -{ - val.resize(study.maxNbYearsInParallel); - for (uint numSpace = 0; numSpace < study.maxNbYearsInParallel; numSpace++) - { - val[numSpace].resize(study.areas.size()); - for (uint areaIndex = 0; areaIndex < study.areas.size(); ++areaIndex) - { - auto& area = *study.areas.byIndex[areaIndex]; - - val[numSpace][areaIndex].HydrauliqueModulableQuotidien - .assign(study.runtime->nbDaysPerYear,0 ); - val[numSpace][areaIndex].AleaCoutDeProductionParPalier - .assign(area.thermal.clusterCount(), 0.); - - if (area.hydro.reservoirManagement) - { - val[numSpace][areaIndex].NiveauxReservoirsDebutJours - .assign(study.runtime->nbDaysPerYear, 0.); - val[numSpace][areaIndex].NiveauxReservoirsFinJours - .assign(study.runtime->nbDaysPerYear, 0.); - } - } - } -} - template void ISimulation::run() { @@ -326,8 +304,6 @@ void ISimulation::run() // The general data auto& parameters = *(study.runtime->parameters); - allocateValeursGenereesParPays(valeursGenereesParPays, study); - // Preprocessors // Determine if we have to use the preprocessors at least one time. pData.initialize(parameters); @@ -352,7 +328,7 @@ void ISimulation::run() } else { - if (not ImplementationType::simulationBegin(valeursGenereesParPays)) + if (not ImplementationType::simulationBegin()) return; // Allocating the memory ImplementationType::variables.simulationBegin(); @@ -705,8 +681,6 @@ void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, if (isPerformed) randomForYears.yearNumberToIndex[y] = indexYear; - // logs.info() << "Year : " << y << " ------------"; - // General const unsigned int nbAreas = study.areas.size(); @@ -715,17 +689,14 @@ void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, { // logs.info() << " area : " << a << " :"; auto& area = *(study.areas.byIndex[a]); - size_t nbClusters = area.thermal.list.mapping.size(); - for (uint c = 0; c != nbClusters; ++c) + auto end = area.thermal.list.mapping.end(); + for (auto it = area.thermal.list.mapping.begin(); it != end; ++it) { + uint clusterIndex = it->second->areaWideIndex; + double thermalNoise = runtime.random[Data::seedThermalCosts].next(); if (isPerformed) - randomForYears.pYears[indexYear].pThermalNoisesByArea[a][c] - = runtime.random[Data::seedThermalCosts].next(); - else - runtime.random[Data::seedThermalCosts].next(); - // logs.info() << " cluster : " << c << ", value : " << - // randomForYears.pYears[indexYear].pThermalNoisesByArea[a][c]; + randomForYears.pYears[indexYear].pThermalNoisesByArea[a][clusterIndex] = thermalNoise; } } @@ -748,8 +719,9 @@ void ISimulation::computeRandomNumbers(randomNumbers& randomForYears, // Previous month's first day in the year int firstDayOfMonth = study.calendar.months[initResLevelOnSimMonth].daysYear.first; - double randomLevel = pHydroManagement.randomReservoirLevel( - min[firstDayOfMonth], avg[firstDayOfMonth], max[firstDayOfMonth]); + double randomLevel = hydroManagement.randomReservoirLevel(min[firstDayOfMonth], + avg[firstDayOfMonth], + max[firstDayOfMonth]); // Possibly update the intial level from scenario builder if (study.parameters.useCustomScenario) @@ -1007,7 +979,6 @@ void ISimulation::loopThroughYears(uint firstYear, { yearPerformed = true; numSpace = set_it->performedYearToSpace[y]; - study.runtime->timeseriesNumberYear[numSpace] = y; } // If the year has not to be rerun, we skip the computation of the year. diff --git a/src/solver/ts-generator/thermal.cpp b/src/solver/ts-generator/thermal.cpp index e6d16eb6d2..af5fd2c0a5 100644 --- a/src/solver/ts-generator/thermal.cpp +++ b/src/solver/ts-generator/thermal.cpp @@ -90,9 +90,8 @@ class GeneratorTempData final const T& duration); private: - uint nbHoursPerYear; - - const uint daysPerYear; + const uint nbHoursPerYear = HOURS_PER_YEAR; + const uint daysPerYear = DAYS_PER_YEAR; MersenneTwister& rndgenerator; @@ -137,12 +136,10 @@ class GeneratorTempData final GeneratorTempData::GeneratorTempData(Data::Study& study, Solver::Progression::Task& progr, IResultWriter::Ptr writer) : - study(study), - nbHoursPerYear(study.runtime->nbHoursPerYear), - daysPerYear(study.runtime->nbDaysPerYear), - rndgenerator(study.runtime->random[Data::seedTsGenThermal]), - pProgression(progr), - pWriter(writer) + study(study), + rndgenerator(study.runtime->random[Data::seedTsGenThermal]), + pProgression(progr), + pWriter(writer) { auto& parameters = study.parameters; diff --git a/src/solver/variable/economy/max-mrg.cpp b/src/solver/variable/economy/max-mrg.cpp index 8cf6170685..80f0bbcfb7 100644 --- a/src/solver/variable/economy/max-mrg.cpp +++ b/src/solver/variable/economy/max-mrg.cpp @@ -176,7 +176,7 @@ inline void PrepareMaxMRGFor(const State& state, double* opmrg, uint numSpace) void PrepareMaxMRG(const State& state, double* opmrg, uint numSpace) { - if (state.simplexHasBeenRan) + if (state.simplexRunNeeded) PrepareMaxMRGFor(state, opmrg, numSpace); else PrepareMaxMRGFor(state, opmrg, numSpace); diff --git a/src/solver/variable/economy/max-mrg.h b/src/solver/variable/economy/max-mrg.h index 564bcfb24f..fb912d0cfc 100644 --- a/src/solver/variable/economy/max-mrg.h +++ b/src/solver/variable/economy/max-mrg.h @@ -245,10 +245,9 @@ class Marge : public Variable::IVariable, NextT, VCardMARGE> void weekForEachArea(State& state, unsigned int numSpace) { - { - double* rawhourly = Memory::RawPointer(pValuesForTheCurrentYear[numSpace].hour); - PrepareMaxMRG(state, rawhourly + state.hourInTheYear, numSpace); - } + double* rawhourly = Memory::RawPointer(pValuesForTheCurrentYear[numSpace].hour); + PrepareMaxMRG(state, rawhourly + state.hourInTheYear, numSpace); + // next NextType::weekForEachArea(state, numSpace); } diff --git a/src/solver/variable/state.cpp b/src/solver/variable/state.cpp index 38202fc052..ba85ab103d 100644 --- a/src/solver/variable/state.cpp +++ b/src/solver/variable/state.cpp @@ -67,7 +67,7 @@ State::State(Data::Study& s) : unitCommitmentMode(s.parameters.unitCommitment.ucMode), study(s), thermal(s.areas), - simplexHasBeenRan(true), + simplexRunNeeded(true), annualSystemCost(0.), optimalSolutionCost1(0.), optimalSolutionCost2(0.), diff --git a/src/solver/variable/state.h b/src/solver/variable/state.h index 58ebb24635..1a66522607 100644 --- a/src/solver/variable/state.h +++ b/src/solver/variable/state.h @@ -221,7 +221,7 @@ class State /*! ** \brief Flag to know if the simplex has been used for the current week */ - bool simplexHasBeenRan; + bool simplexRunNeeded; // Annual costs to be printed in output into separate files // ----------------------------------------------------------------- diff --git a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp index bfabcd1ba7..940a8b28fa 100644 --- a/src/tests/src/solver/simulation/test-store-timeseries-number.cpp +++ b/src/tests/src/solver/simulation/test-store-timeseries-number.cpp @@ -23,7 +23,7 @@ namespace fs = std::filesystem; void initializeStudy(Study &study) { study.parameters.derated = false; - study.runtime = new StudyRuntimeInfos(1); + study.runtime = new StudyRuntimeInfos(); study.runtime->rangeLimits.year[rangeBegin] = 0; study.runtime->rangeLimits.year[rangeEnd] = 0; study.runtime->rangeLimits.year[rangeCount] = 1; diff --git a/src/tests/src/solver/simulation/test-time_series.cpp b/src/tests/src/solver/simulation/test-time_series.cpp index 5896169521..00357c5299 100644 --- a/src/tests/src/solver/simulation/test-time_series.cpp +++ b/src/tests/src/solver/simulation/test-time_series.cpp @@ -19,7 +19,7 @@ void initializeStudy(Study& study) { study.parameters.derated = false; - study.runtime = new StudyRuntimeInfos(1); + study.runtime = new StudyRuntimeInfos(); study.runtime->rangeLimits.year[rangeBegin] = 0; study.runtime->rangeLimits.year[rangeEnd] = 0; study.runtime->rangeLimits.year[rangeCount] = 1; diff --git a/src/tests/src/solver/simulation/tests-ts-numbers.cpp b/src/tests/src/solver/simulation/tests-ts-numbers.cpp index 11a6a344c8..13cd2a187f 100644 --- a/src/tests/src/solver/simulation/tests-ts-numbers.cpp +++ b/src/tests/src/solver/simulation/tests-ts-numbers.cpp @@ -18,7 +18,7 @@ void initializeStudy(Study::Ptr study) { study->parameters.derated = false; - study->runtime = new StudyRuntimeInfos(1); + study->runtime = new StudyRuntimeInfos(); study->runtime->rangeLimits.year[rangeBegin] = 0; study->runtime->rangeLimits.year[rangeEnd] = 0; study->runtime->rangeLimits.year[rangeCount] = 1;