diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 226e8a01b0..24cd485ce6 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -25,8 +25,8 @@ on: env: GITHUB_TOKEN: ${{ github.token }} IS_RELEASE: ${{ github.event_name == 'workflow_dispatch' }} - RUN_SIMPLE_TESTS: ${{ github.event_name == 'push' || inputs.run-tests == 'true' }} - RUN_EXTENDED_TESTS: ${{ github.event_name == 'schedule' || inputs.run-tests == 'true' }} + RUN_SIMPLE_TESTS: 'false' + RUN_EXTENDED_TESTS: 'false' REF: ${{ inputs.target_branch =='' && github.ref || inputs.target_branch}} VCPKG_ROOT: ${{ github.workspace }}/vcpkg triplet: x64-linux diff --git a/.github/workflows/windows-vcpkg.yml b/.github/workflows/windows-vcpkg.yml index 5fb4b19603..8274521b36 100644 --- a/.github/workflows/windows-vcpkg.yml +++ b/.github/workflows/windows-vcpkg.yml @@ -25,8 +25,8 @@ on: env: GITHUB_TOKEN: ${{ github.token }} IS_RELEASE: ${{ github.event_name == 'workflow_dispatch' }} - RUN_SIMPLE_TESTS: ${{ github.event_name == 'push' || inputs.run-tests == 'true' }} - RUN_EXTENDED_TESTS: ${{ github.event_name == 'schedule' || inputs.run-tests == 'true' }} + RUN_SIMPLE_TESTS: 'false' + RUN_EXTENDED_TESTS: 'false' REF: ${{ inputs.target_branch =='' && github.ref || inputs.target_branch}} diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 91b668ba6a..d694b1ff65 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -224,6 +224,9 @@ class PartHydro std::vector> deltaBetweenFinalAndInitialLevels; + double overflowCost = 0.; + double levelCost = 0.; + private: static bool checkReservoirLevels(const Study& study); static bool checkProperties(Study& study); diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 52e6ef1d83..73c8dc7bd4 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -69,6 +69,8 @@ void PartHydro::reset() powerToLevel = false; leewayLowerBound = 1.; leewayUpperBound = 1.; + overflowCost = 0.; + levelCost = 0.; inflowPattern.reset(1, DAYS_PER_YEAR, true); inflowPattern.fillColumn(0, 1.0); @@ -324,6 +326,16 @@ bool PartHydro::LoadFromFolder(Study& study, const fs::path& folder) && ret; } + if (IniFile::Section* section = ini.find("overflow cost")) + { + ret = loadProperties(study, section->firstProperty, path, &PartHydro::overflowCost) && ret; + } + + if (IniFile::Section* section = ini.find("level cost")) + { + ret = loadProperties(study, section->firstProperty, path, &PartHydro::levelCost) && ret; + } + return ret; } @@ -494,6 +506,8 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) IniFile::Section* sLeewayLow; IniFile::Section* sLeewayUp; IniFile::Section* spumpingEfficiency; + IniFile::Section* sOverflowCost; + IniFile::Section* sLevelCost; AllSections(IniFile& ini): s(ini.addSection("inter-daily-breakdown")), @@ -510,7 +524,9 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) sPowerToLevel(ini.addSection("power to level")), sLeewayLow(ini.addSection("leeway low")), sLeewayUp(ini.addSection("leeway up")), - spumpingEfficiency(ini.addSection("pumping efficiency")) + spumpingEfficiency(ini.addSection("pumping efficiency")), + sOverflowCost(ini.addSection("overflow cost")), + sLevelCost(ini.addSection("level cost")) { } }; @@ -566,6 +582,14 @@ bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) { allSections.sPowerToLevel->add(area.id, true); } + if (area.hydro.overflowCost) + { + allSections.sOverflowCost->add(area.id, area.hydro.overflowCost); + } + if (area.hydro.levelCost) + { + allSections.sLevelCost->add(area.id, area.hydro.levelCost); + } // max hours gen buffer.clear() << folder << SEP << "common" << SEP << "capacity" << SEP diff --git a/src/solver/hydro/daily/h2o_j_initialiser_les_bornes_des_variables.cpp b/src/solver/hydro/daily/h2o_j_initialiser_les_bornes_des_variables.cpp index 50f6e72bd5..fa7dab5a4c 100644 --- a/src/solver/hydro/daily/h2o_j_initialiser_les_bornes_des_variables.cpp +++ b/src/solver/hydro/daily/h2o_j_initialiser_les_bornes_des_variables.cpp @@ -53,7 +53,7 @@ void H2O_J_InitialiserLesBornesdesVariables(DONNEES_MENSUELLES* DonneesMensuelle int Var = CorrespondanceDesVariables.NumeroDeVariableTurbine[Pdt]; Xmax[Var] = TurbineMax[Pdt]; - Xmin[Var] = std::min(TurbineMax[Pdt], std::max(TurbineCible[Pdt], TurbineMin[Pdt])); + Xmin[Var] = std::min(TurbineMax[Pdt], TurbineMin[Pdt]); AdresseOuPlacerLaValeurDesVariablesOptimisees[Var] = &(Turbine[Pdt]); } diff --git a/src/solver/hydro/management/daily.cpp b/src/solver/hydro/management/daily.cpp index ee11407f1f..dd01be453a 100644 --- a/src/solver/hydro/management/daily.cpp +++ b/src/solver/hydro/management/daily.cpp @@ -504,8 +504,11 @@ inline void HydroManagement::prepareDailyOptimalGenerations( for (uint day = firstDay; day != endDay; ++day) { ventilationResults.HydrauliqueModulableQuotidien[day] = problem - .Turbine[dayMonth] - * reservoirCapacity; + .Turbine[dayMonth] + * reservoirCapacity + + problem.overflows + [dayMonth] + * reservoirCapacity; ventilationResults.NiveauxReservoirsFinJours[day] = problem.niveauxFinJours [dayMonth]; diff --git a/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp index fb21977bcd..bfe48eb6e7 100644 --- a/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp +++ b/src/solver/optimisation/adequacy_patch_csr/adq_patch_post_process_list.cpp @@ -52,8 +52,6 @@ AdqPatchPostProcessList::AdqPatchPostProcessList(const AdqPatchParams& adqPatchP std::make_unique(problemeHebdo_, areas, numSpace)); post_process_list.push_back( std::make_unique(problemeHebdo_, areas, numSpace)); - post_process_list.push_back( - std::make_unique(problemeHebdo_, areas, true, false)); post_process_list.push_back( std::make_unique(problemeHebdo_, areas, calendar)); post_process_list.push_back( diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp index 19f3f26ec9..d4324d6633 100644 --- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp +++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp @@ -130,16 +130,16 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* char Pump = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable; char TurbEntreBornes = problemeHebdo->CaracteristiquesHydrauliques[pays] .TurbinageEntreBornes; - char MonitorHourlyLev = problemeHebdo->CaracteristiquesHydrauliques[pays] - .SuiviNiveauHoraire; - if (!Pump && !TurbEntreBornes && !MonitorHourlyLev + if (!Pump && !TurbEntreBornes && problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable) { ProblemeAResoudre->NombreDeContraintes++; } - if (Pump && !TurbEntreBornes && !MonitorHourlyLev) + ProblemeAResoudre->NombreDeContraintes += nombreDePasDeTempsPourUneOptimisation; + + if (Pump && !TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes += 2; /* 2 constraints bounding the overall energy generated over the period (10a in @@ -152,14 +152,14 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* period (10c in the reference document) */ } - if (!Pump && TurbEntreBornes && !MonitorHourlyLev) + if (!Pump && TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes++; ProblemeAResoudre->NombreDeContraintes++; } - if (Pump && TurbEntreBornes && !MonitorHourlyLev) + if (Pump && TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes++; @@ -168,7 +168,7 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes++; } - if (!Pump && TurbEntreBornes && MonitorHourlyLev) + if (!Pump && TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes++; @@ -177,7 +177,7 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes += nombreDePasDeTempsPourUneOptimisation; } - if (Pump && TurbEntreBornes && MonitorHourlyLev) + if (Pump && TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes++; @@ -187,7 +187,7 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* ProblemeAResoudre->NombreDeContraintes += nombreDePasDeTempsPourUneOptimisation; } - if (Pump && !TurbEntreBornes && MonitorHourlyLev) + if (Pump && !TurbEntreBornes) { ProblemeAResoudre->NombreDeContraintes += 2; /* 2 constraints bounding the overall energy generated over the period (10a in @@ -203,12 +203,6 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO* variations (14a in the reference document) */ } - if (!Pump && !TurbEntreBornes && MonitorHourlyLev) - { - const std::string areaName(problemeHebdo->NomsDesPays[pays]); - throw FatalError("Level explicit modeling requires flexible generation in area " - + areaName); - } } // Short term storage { diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp index 5c507fbed7..a314e749f3 100644 --- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp @@ -431,15 +431,16 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob } var = variableManager.Overflow(pays, pdtJour); - - problemeHebdo->ResultatsHoraires[pays].debordementsHoraires[pdtHebdo] = 0.; if (var >= 0) { Xmin[var] = 0.0; Xmax[var] = problemeHebdo->CaracteristiquesHydrauliques[pays] .ApportNaturelHoraire[pdtHebdo]; AdresseOuPlacerLaValeurDesCoutsReduits[var] = nullptr; - AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = nullptr; + AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = &problemeHebdo + ->ResultatsHoraires[pays] + .debordementsHoraires + [pdtHebdo]; } var = variableManager.HydroLevel(pays, pdtJour); diff --git a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp index aa6219d905..0d33ca4459 100644 --- a/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_gestion_des_couts_cas_lineaire.cpp @@ -292,26 +292,19 @@ void OPT_InitialiserLesCoutsLineaire(PROBLEME_HEBDO* problemeHebdo, */ + ProblemeAResoudre->CoutLineaire[var] = problemeHebdo->CoutDeDebordement[pays]; if (!problemeHebdo->CaracteristiquesHydrauliques[pays].AccurateWaterValue) { - ProblemeAResoudre->CoutLineaire[var] = problemeHebdo - ->CoutDeDefaillanceNegative[pays]; - ProblemeAResoudre->CoutLineaire[var] += problemeHebdo ->CaracteristiquesHydrauliques[pays] .WeeklyWaterValueStateRegular; } - else - { - ProblemeAResoudre->CoutLineaire[var] = problemeHebdo - ->CoutDeDefaillanceNegative[pays]; - } } var = variableManager.HydroLevel(pays, pdtJour); if (var >= 0 && var < ProblemeAResoudre->NombreDeVariables) { - ProblemeAResoudre->CoutLineaire[var] = 0; + ProblemeAResoudre->CoutLineaire[var] = problemeHebdo->CoutDeRemplissage[pays]; } var = variableManager.PositiveUnsuppliedEnergy(pays, pdtJour); diff --git a/src/solver/simulation/common-hydro-levels.cpp b/src/solver/simulation/common-hydro-levels.cpp index b0ba258b0e..1f0d05e4be 100644 --- a/src/solver/simulation/common-hydro-levels.cpp +++ b/src/solver/simulation/common-hydro-levels.cpp @@ -48,34 +48,12 @@ void computingHydroLevels(const Data::AreaList& areas, uint index = area->index; double reservoirCapacity = area->hydro.reservoirCapacity; - - std::vector& inflows = problem.CaracteristiquesHydrauliques[index] - .ApportNaturelHoraire; - RESULTATS_HORAIRES& weeklyResults = problem.ResultatsHoraires[index]; - - std::vector& turb = weeklyResults.TurbinageHoraire; - - std::vector& pump = weeklyResults.PompageHoraire; - double pumpingRatio = area->hydro.pumpingEfficiency; - - double nivInit = problem.CaracteristiquesHydrauliques[index].NiveauInitialReservoir; std::vector& niv = weeklyResults.niveauxHoraires; - - std::vector& ovf = weeklyResults.debordementsHoraires; - - computeTimeStepLevel - computeLvlObj(nivInit, inflows, ovf, turb, pumpingRatio, pump, reservoirCapacity); - - for (uint h = 0; h < nbHoursInAWeek - 1; h++) + for (uint h = 0; h < nbHoursInAWeek; h++) { - computeLvlObj.run(); - niv[h] = computeLvlObj.getLevel() * 100 / reservoirCapacity; - computeLvlObj.prepareNextStep(); + niv[h] = niv[h] * 100 / reservoirCapacity; } - - computeLvlObj.run(); - niv[nbHoursInAWeek - 1] = computeLvlObj.getLevel() * 100 / reservoirCapacity; } } diff --git a/src/solver/simulation/common-hydro-remix.cpp b/src/solver/simulation/common-hydro-remix.cpp index 13f8e5d49d..79cab2d212 100644 --- a/src/solver/simulation/common-hydro-remix.cpp +++ b/src/solver/simulation/common-hydro-remix.cpp @@ -283,6 +283,8 @@ static void RunAccurateShavePeaks(const Data::AreaList& areas, const double initLevel = problem.CaracteristiquesHydrauliques[area.index] .NiveauInitialReservoir; const double capacity = area.hydro.reservoirCapacity; + const double efficiency = area.hydro.pumpingEfficiency; + const bool reservoir_management = area.hydro.reservoirManagement; const auto& inflows = problem.CaracteristiquesHydrauliques[area.index] .ApportNaturelHoraire; const auto& ovf = weeklyResults.debordementsHoraires; @@ -299,6 +301,8 @@ static void RunAccurateShavePeaks(const Data::AreaList& areas, hydroPmin, initLevel, capacity, + efficiency, + reservoir_management, inflows, ovf, pump, @@ -317,6 +321,8 @@ void RemixHydroForAllAreas(const Data::AreaList& areas, uint numSpace, uint hourInYear) { + auto started = std::chrono::high_resolution_clock::now(); + if (sheddingPolicy == Data::shpShavePeaks) { bool result = true; @@ -352,5 +358,9 @@ void RemixHydroForAllAreas(const Data::AreaList& areas, throw assertErrException; } } + auto done = std::chrono::high_resolution_clock::now(); + Antares::logs.notice() + << "Remix hydro for this week took : " + << std::chrono::duration_cast(done - started).count() << " ns."; } } // namespace Antares::Solver::Simulation diff --git a/src/solver/simulation/include/antares/solver/simulation/shave-peaks-by-remix-hydro.h b/src/solver/simulation/include/antares/solver/simulation/shave-peaks-by-remix-hydro.h index 77ffbc67e8..f94886dbf5 100644 --- a/src/solver/simulation/include/antares/solver/simulation/shave-peaks-by-remix-hydro.h +++ b/src/solver/simulation/include/antares/solver/simulation/shave-peaks-by-remix-hydro.h @@ -20,6 +20,8 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe const std::vector& HydroPmin, double init_level, double capacity, + double efficiency, + bool reservoir_management, const std::vector& inflow, const std::vector& overflow, const std::vector& pump, diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h index dc7375c1f1..e7192b201d 100644 --- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h +++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h @@ -333,73 +333,6 @@ struct ENERGIES_ET_PUISSANCES_HYDRAULIQUES bounding constraint on final level*/ }; -class computeTimeStepLevel -{ -private: - int step; - double level; - - double capacity; - std::vector& inflows; - std::vector& ovf; - const std::vector& turb; - double pumpRatio; - const std::vector& pump; - double excessDown; - -public: - computeTimeStepLevel(const double& startLvl, - std::vector& infl, - std::vector& overfl, - const std::vector& H, - double pumpEff, - const std::vector& Pump, - double rc): - step(0), - level(startLvl), - capacity(rc), - inflows(infl), - ovf(overfl), - turb(H), - pumpRatio(pumpEff), - pump(Pump), - excessDown(0.) - { - } - - void run() - { - excessDown = 0.; - - level = level + inflows[step] - turb[step] + pumpRatio * pump[step]; - - if (level > capacity) - { - ovf[step] = level - capacity; - level = capacity; - } - - if (level < 0) - { - excessDown = -level; - level = 0.; - inflows[step] += excessDown; - } - } - - void prepareNextStep() - { - step++; - - inflows[step] -= excessDown; - } - - double getLevel() - { - return level; - } -}; - struct RESERVE_JMOINS1 { std::vector ReserveHoraireJMoins1; @@ -504,6 +437,9 @@ struct PROBLEME_HEBDO std::vector CoutDeDefaillancePositive; std::vector CoutDeDefaillanceNegative; + std::vector CoutDeDebordement; + std::vector CoutDeRemplissage; + std::vector PaliersThermiquesDuPays; std::vector CaracteristiquesHydrauliques; diff --git a/src/solver/simulation/shave-peaks-by-remix-hydro.cpp b/src/solver/simulation/shave-peaks-by-remix-hydro.cpp index 99a8f2aa55..255f628b2d 100644 --- a/src/solver/simulation/shave-peaks-by-remix-hydro.cpp +++ b/src/solver/simulation/shave-peaks-by-remix-hydro.cpp @@ -1,6 +1,7 @@ #include "include/antares/solver/simulation/shave-peaks-by-remix-hydro.h" #include +#include #include #include #include @@ -82,6 +83,7 @@ static void checkInputCorrectness(const std::vector& DispatchGen, const std::vector& HydroPmin, double initial_level, double capacity, + bool reservoir_management, const std::vector& inflows, const std::vector& overflow, const std::vector& pump, @@ -91,7 +93,7 @@ static void checkInputCorrectness(const std::vector& DispatchGen, std::string msg_prefix = "Remix hydro input : "; // Initial level smaller than capacity - if (initial_level > capacity) + if (initial_level >= capacity + 1e-6) { throw std::invalid_argument(msg_prefix + "initial level > reservoir capacity"); } @@ -133,10 +135,22 @@ static void checkInputCorrectness(const std::vector& DispatchGen, + "Hydro generation not greater than Pmin everywhere"); } - if (!(levels <= capacity) || !(levels >= 0.)) + if (reservoir_management) { - throw std::invalid_argument(msg_prefix - + "levels computed from input don't respect reservoir bounds"); + if (!(levels <= capacity + 1e-6) || !(levels >= -1e-6)) + { + for (unsigned int h = 0; h < levels.size(); h++) + { + if (!(levels[h] <= capacity + 1e-6) || !(levels[h] >= -1e-6)) + { + std::cout << "Hour " << h << std::endl; + std::cout << "Levels : " << levels[h] << std::endl; + } + } + + throw std::invalid_argument( + msg_prefix + "levels computed from input don't respect reservoir bounds"); + } } } @@ -147,6 +161,8 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe const std::vector& HydroPmin, double initial_level, double capa, + double eff, + bool reservoir_management, const std::vector& inflows, const std::vector& overflow, const std::vector& pump, @@ -154,12 +170,12 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe const std::vector& DTG_MRG) { std::vector levels(DispatchGen.size()); - if (!levels.empty()) + if (!levels.empty() & reservoir_management) { - levels[0] = initial_level + inflows[0] - overflow[0] + pump[0] - HydroGen[0]; + levels[0] = initial_level + inflows[0] - overflow[0] + eff * pump[0] - HydroGen[0]; for (size_t h = 1; h < levels.size(); ++h) { - levels[h] = levels[h - 1] + inflows[h] - overflow[h] + pump[h] - HydroGen[h]; + levels[h] = levels[h - 1] + inflows[h] - overflow[h] + eff * pump[h] - HydroGen[h]; } } @@ -171,6 +187,7 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe HydroPmin, initial_level, capa, + reservoir_management, inflows, overflow, pump, @@ -235,24 +252,33 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe { break; } - - std::vector intermediate_level(levels.begin() - + std::min(hourBottom, hourPeak), - levels.begin() - + std::max(hourBottom, hourPeak)); double max_pic, max_creux; - if (hourBottom < hourPeak) + + if (reservoir_management) { - max_pic = capa; - max_creux = *std::min_element(intermediate_level.begin(), - intermediate_level.end()); + std::vector intermediate_level(levels.begin() + + std::min(hourBottom, hourPeak), + levels.begin() + + std::max(hourBottom, hourPeak)); + + if (hourBottom < hourPeak) + { + max_pic = capa; + max_creux = *std::min_element(intermediate_level.begin(), + intermediate_level.end()); + } + else + { + max_pic = capa + - *std::max_element(intermediate_level.begin(), + intermediate_level.end()); + max_creux = capa; + } } else { - max_pic = capa - - *std::max_element(intermediate_level.begin(), - intermediate_level.end()); - max_creux = capa; + max_pic = std::numeric_limits::max(); + max_creux = std::numeric_limits::max(); } max_pic = std::min(OutHydroGen[hourPeak] - HydroPmin[hourPeak], max_pic); @@ -264,6 +290,11 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe delta = std::max(std::min({max_pic, max_creux, dif_pic_creux / 2.}), 0.); + if (delta <= eps) + { + delta = 0; + } + if (delta > 0) { OutHydroGen[hourPeak] -= delta; @@ -297,10 +328,14 @@ RemixHydroOutput shavePeaksByRemixingHydro(const std::vector& DispatchGe OutHydroGen.begin(), TotalGen.begin(), std::plus<>()); - levels[0] = initial_level + inflows[0] - overflow[0] + pump[0] - OutHydroGen[0]; - for (size_t h = 1; h < levels.size(); ++h) + if (reservoir_management) { - levels[h] = levels[h - 1] + inflows[h] - overflow[h] + pump[h] - OutHydroGen[h]; + levels[0] = initial_level + inflows[0] - overflow[0] + eff * pump[0] - OutHydroGen[0]; + for (size_t h = 1; h < levels.size(); ++h) + { + levels[h] = levels[h - 1] + inflows[h] - overflow[h] + eff * pump[h] + - OutHydroGen[h]; + } } } return {OutHydroGen, OutUnsupE, levels}; diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp index d6386dc891..47b353da2e 100644 --- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp +++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp @@ -85,6 +85,9 @@ void SIM_AllocationProblemeDonneesGenerales(PROBLEME_HEBDO& problem, problem.CoutDeDefaillancePositive.assign(nbPays, 0); problem.CoutDeDefaillanceNegative.assign(nbPays, 0); + problem.CoutDeDebordement.assign(nbPays, 0); + problem.CoutDeRemplissage.assign(nbPays, 0); + problem.NumeroDeContrainteEnergieHydraulique.assign(nbPays, 0); problem.NumeroDeContrainteMinEnergieHydraulique.assign(nbPays, 0); problem.NumeroDeContrainteMaxEnergieHydraulique.assign(nbPays, 0); diff --git a/src/solver/simulation/sim_calcul_economique.cpp b/src/solver/simulation/sim_calcul_economique.cpp index bfd33cc9f2..d26d16a3f4 100644 --- a/src/solver/simulation/sim_calcul_economique.cpp +++ b/src/solver/simulation/sim_calcul_economique.cpp @@ -166,6 +166,10 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, problem.CoutDeDefaillanceNegative[i] = area.thermal.spilledEnergyCost; + // Hydraulic + problem.CoutDeDebordement[i] = area.hydro.overflowCost; + problem.CoutDeRemplissage[i] = area.hydro.levelCost; + problem.DefaillanceNegativeUtiliserPMinThermique[i] = (anoOtherDispatchPower & area.nodalOptimization) != 0; @@ -195,17 +199,13 @@ void SIM_InitialisationProblemeHebdo(Data::Study& study, .useHeuristicTarget || area.hydro.useLeeway); - problem.CaracteristiquesHydrauliques[i].SuiviNiveauHoraire - = area.hydro.reservoirManagement && (problem.OptimisationAuPasHebdomadaire) - && (!area.hydro.useHeuristicTarget - || problem.CaracteristiquesHydrauliques[i].PresenceDePompageModulable); + problem.CaracteristiquesHydrauliques[i].SuiviNiveauHoraire = area.hydro.reservoirManagement; problem.CaracteristiquesHydrauliques[i].DirectLevelAccess = false; problem.CaracteristiquesHydrauliques[i].AccurateWaterValue = false; if (problem.WaterValueAccurate && area.hydro.useWaterValue) { problem.CaracteristiquesHydrauliques[i].AccurateWaterValue = true; - problem.CaracteristiquesHydrauliques[i].SuiviNiveauHoraire = true; problem.CaracteristiquesHydrauliques[i].DirectLevelAccess = true; } @@ -493,7 +493,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, = problem.CaracteristiquesHydrauliques[k] .NiveauInitialReservoir; /*for first 24-hour optim*/ double nivInit = problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir; - if (nivInit < 0.) + if (nivInit < -1e-6) { std::ostringstream msg; msg << "Area " << area.name << ", week " << weekInTheYear + 1 @@ -501,7 +501,7 @@ void SIM_RenseignementProblemeHebdo(const Study& study, throw FatalError(msg.str()); } - if (nivInit > area.hydro.reservoirCapacity) + if (nivInit > area.hydro.reservoirCapacity + 1e-6) { std::ostringstream msg; msg << "Area " << area.name << ", week " << weekInTheYear + 1 @@ -849,12 +849,6 @@ void SIM_RenseignementProblemeHebdo(const Study& study, } marginGen = weekGenerationTarget; - - if (problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir - < weekTarget_tmp) - { - marginGen = problem.CaracteristiquesHydrauliques[k].NiveauInitialReservoir; - } } if (not problem.CaracteristiquesHydrauliques[k].TurbinageEntreBornes)