From a9062f8ebabba1f18f2a88e9ab076e59b1aef4db Mon Sep 17 00:00:00 2001 From: abdoulbari zakir <32519851+a-zakir@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:45:20 +0200 Subject: [PATCH] Refactor constraint building (#1607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * start * add FictitiousLoad * shortTermStorageLevel * flowDissociation * bindingConstraintHour * ghost * this is not only about constraint builder * pay attention to the time step * specific issue * bug free * smooth green? * M&M * Max Pumping ok? * Area Hydro Level (_-_) * finally * basic * tiny * clean code * add {PMin,PMax}DispatchableGeneration * clean code * ConsistenceNODU ok * NbUnitsOutageLessThanNbUnitsStop * NbDispUnitsMinBoundSinceMinUpTime * MinDownTime * setup Access Control * remove comments * remove comments * treat major code smells * treat major code smells 2 * more on major code smells * update after review * about objects lifetime * (does not compile) cut into small pieces * Revert "(does not compile) cut into small pieces" This reverts commit 5a047c0a68288b574b9464c8eb360bf016dacab0. * aesthetic * remove comment * smart move * **** move * shallow * customize error exception * test new variable construction design * refactor * update build for NODU * clean deprecated code * update build for NumberStoppingDispatchableUnits * on NumberStartingDispatchableUnits * on NumberBreakingDownDispatchableUnits * new build NTCDirect * missing file NTCDirect * Interco Direct/Indirect Cost * ShortTermStorageInjection * ShortTermStorageWithdrawal * ShortTermStorageLevel * HydProd * HydProdDown * HydProdUp * Pumping * HydroLevel * Overflow * FinalStorage * fix * LayerStorage * Psitive/Negative UnsuppliedEnergy * remove old code * remove code * fix * move * clarity matters thanks to @sylvlecl * There is no need for repetition * it makes sense: Constraint->ConstraintFactory * update * remove redundant check * rename things * unused * debug * fiiiiiiiix * add explicit keyword * inspect unique_ptr * resolve conflicts * quick fix * suggestion by @flomnes Co-authored-by: Florian Omnès * add docs * docs for new constraint classes * update * complete new classes documentation * update * update * small changes * small changes 2 * remove comment * default value for constraint op * clean code * smell code * smell code * fix * pretty * typo --------- Co-authored-by: Florian Omnès --- src/solver/optimisation/CMakeLists.txt | 50 + .../optimisation/constraints/AreaBalance.cpp | 52 + .../optimisation/constraints/AreaBalance.h | 18 + .../constraints/AreaHydroLevel.cpp | 32 + .../optimisation/constraints/AreaHydroLevel.h | 18 + .../constraints/BindingConstraintDay.cpp | 69 ++ .../constraints/BindingConstraintDay.h | 17 + .../constraints/BindingConstraintHour.cpp | 53 + .../constraints/BindingConstraintHour.h | 18 + .../constraints/BindingConstraintWeek.cpp | 59 ++ .../constraints/BindingConstraintWeek.h | 17 + .../ConsistenceNumberOfDispatchableUnits.cpp | 47 + .../ConsistenceNumberOfDispatchableUnits.h | 20 + .../constraints/ConstraintBuilder.cpp | 244 +++++ .../constraints/ConstraintBuilder.h | 383 +++++++ .../constraints/FictitiousLoad.cpp | 24 + .../optimisation/constraints/FictitiousLoad.h | 19 + .../constraints/FinalStockEquivalent.cpp | 25 + .../constraints/FinalStockEquivalent.h | 17 + .../constraints/FinalStockExpression.cpp | 25 + .../constraints/FinalStockExpression.h | 17 + .../constraints/FlowDissociation.cpp | 31 + .../constraints/FlowDissociation.h | 18 + .../optimisation/constraints/HydroPower.cpp | 47 + .../optimisation/constraints/HydroPower.h | 17 + ...droPowerSmoothingUsingVariationMaxDown.cpp | 22 + ...HydroPowerSmoothingUsingVariationMaxDown.h | 18 + ...HydroPowerSmoothingUsingVariationMaxUp.cpp | 22 + .../HydroPowerSmoothingUsingVariationMaxUp.h | 18 + .../HydroPowerSmoothingUsingVariationSum.cpp | 33 + .../HydroPowerSmoothingUsingVariationSum.h | 17 + .../constraints/MaxHydroPower.cpp | 35 + .../optimisation/constraints/MaxHydroPower.h | 17 + .../optimisation/constraints/MaxPumping.cpp | 28 + .../optimisation/constraints/MaxPumping.h | 17 + .../optimisation/constraints/MinDownTime.cpp | 50 + .../optimisation/constraints/MinDownTime.h | 20 + .../constraints/MinHydroPower.cpp | 34 + .../optimisation/constraints/MinHydroPower.h | 18 + .../NbDispUnitsMinBoundSinceMinUpTime.cpp | 59 ++ .../NbDispUnitsMinBoundSinceMinUpTime.h | 21 + .../NbUnitsOutageLessThanNbUnitsStop.cpp | 41 + .../NbUnitsOutageLessThanNbUnitsStop.h | 21 + .../PMaxDispatchableGeneration.cpp | 38 + .../constraints/PMaxDispatchableGeneration.h | 21 + .../PMinDispatchableGeneration.cpp | 38 + .../constraints/PMinDispatchableGeneration.h | 21 + .../constraints/ShortTermStorageLevel.cpp | 31 + .../constraints/ShortTermStorageLevel.h | 9 + ...nstruction_contraintes_couts_demarrage.cpp | 425 +------- ...n_matrice_des_contraintes_cas_lineaire.cpp | 980 ++---------------- src/solver/optimisation/opt_rename_problem.h | 9 +- 52 files changed, 2082 insertions(+), 1318 deletions(-) create mode 100644 src/solver/optimisation/constraints/AreaBalance.cpp create mode 100644 src/solver/optimisation/constraints/AreaBalance.h create mode 100644 src/solver/optimisation/constraints/AreaHydroLevel.cpp create mode 100644 src/solver/optimisation/constraints/AreaHydroLevel.h create mode 100644 src/solver/optimisation/constraints/BindingConstraintDay.cpp create mode 100644 src/solver/optimisation/constraints/BindingConstraintDay.h create mode 100644 src/solver/optimisation/constraints/BindingConstraintHour.cpp create mode 100644 src/solver/optimisation/constraints/BindingConstraintHour.h create mode 100644 src/solver/optimisation/constraints/BindingConstraintWeek.cpp create mode 100644 src/solver/optimisation/constraints/BindingConstraintWeek.h create mode 100644 src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.cpp create mode 100644 src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.h create mode 100644 src/solver/optimisation/constraints/ConstraintBuilder.cpp create mode 100644 src/solver/optimisation/constraints/ConstraintBuilder.h create mode 100644 src/solver/optimisation/constraints/FictitiousLoad.cpp create mode 100644 src/solver/optimisation/constraints/FictitiousLoad.h create mode 100644 src/solver/optimisation/constraints/FinalStockEquivalent.cpp create mode 100644 src/solver/optimisation/constraints/FinalStockEquivalent.h create mode 100644 src/solver/optimisation/constraints/FinalStockExpression.cpp create mode 100644 src/solver/optimisation/constraints/FinalStockExpression.h create mode 100644 src/solver/optimisation/constraints/FlowDissociation.cpp create mode 100644 src/solver/optimisation/constraints/FlowDissociation.h create mode 100644 src/solver/optimisation/constraints/HydroPower.cpp create mode 100644 src/solver/optimisation/constraints/HydroPower.h create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.cpp create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.h create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.cpp create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.h create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.cpp create mode 100644 src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.h create mode 100644 src/solver/optimisation/constraints/MaxHydroPower.cpp create mode 100644 src/solver/optimisation/constraints/MaxHydroPower.h create mode 100644 src/solver/optimisation/constraints/MaxPumping.cpp create mode 100644 src/solver/optimisation/constraints/MaxPumping.h create mode 100644 src/solver/optimisation/constraints/MinDownTime.cpp create mode 100644 src/solver/optimisation/constraints/MinDownTime.h create mode 100644 src/solver/optimisation/constraints/MinHydroPower.cpp create mode 100644 src/solver/optimisation/constraints/MinHydroPower.h create mode 100644 src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.cpp create mode 100644 src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.h create mode 100644 src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.cpp create mode 100644 src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.h create mode 100644 src/solver/optimisation/constraints/PMaxDispatchableGeneration.cpp create mode 100644 src/solver/optimisation/constraints/PMaxDispatchableGeneration.h create mode 100644 src/solver/optimisation/constraints/PMinDispatchableGeneration.cpp create mode 100644 src/solver/optimisation/constraints/PMinDispatchableGeneration.h create mode 100644 src/solver/optimisation/constraints/ShortTermStorageLevel.cpp create mode 100644 src/solver/optimisation/constraints/ShortTermStorageLevel.h diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt index 6257274414..4d23d3ef89 100644 --- a/src/solver/optimisation/CMakeLists.txt +++ b/src/solver/optimisation/CMakeLists.txt @@ -70,6 +70,56 @@ set(RTESOLVER_OPT opt_period_string_generator_base.h opt_rename_problem.h opt_rename_problem.cpp + + constraints/ConstraintBuilder.cpp + constraints/ConstraintBuilder.h + constraints/AreaBalance.h + constraints/AreaBalance.cpp + constraints/FictitiousLoad.h + constraints/FictitiousLoad.cpp + constraints/ShortTermStorageLevel.h + constraints/ShortTermStorageLevel.cpp + constraints/FlowDissociation.h + constraints/FlowDissociation.cpp + constraints/BindingConstraintHour.h + constraints/BindingConstraintHour.cpp + constraints/BindingConstraintDay.h + constraints/BindingConstraintDay.cpp + constraints/BindingConstraintWeek.h + constraints/BindingConstraintWeek.cpp + constraints/HydroPower.h + constraints/HydroPower.cpp + constraints/HydroPowerSmoothingUsingVariationSum.h + constraints/HydroPowerSmoothingUsingVariationSum.cpp + constraints/HydroPowerSmoothingUsingVariationMaxDown.h + constraints/HydroPowerSmoothingUsingVariationMaxDown.cpp + constraints/HydroPowerSmoothingUsingVariationMaxUp.h + constraints/HydroPowerSmoothingUsingVariationMaxUp.cpp + constraints/MinHydroPower.h + constraints/MinHydroPower.cpp + constraints/MaxHydroPower.h + constraints/MaxHydroPower.cpp + constraints/MaxPumping.h + constraints/MaxPumping.cpp + constraints/AreaHydroLevel.h + constraints/AreaHydroLevel.cpp + constraints/FinalStockEquivalent.h + constraints/FinalStockEquivalent.cpp + constraints/FinalStockExpression.h + constraints/FinalStockExpression.cpp + constraints/PMaxDispatchableGeneration.h + constraints/PMaxDispatchableGeneration.cpp + constraints/PMinDispatchableGeneration.h + constraints/PMinDispatchableGeneration.cpp + constraints/ConsistenceNumberOfDispatchableUnits.h + constraints/ConsistenceNumberOfDispatchableUnits.cpp + constraints/NbUnitsOutageLessThanNbUnitsStop.h + constraints/NbUnitsOutageLessThanNbUnitsStop.cpp + constraints/NbDispUnitsMinBoundSinceMinUpTime.h + constraints/NbDispUnitsMinBoundSinceMinUpTime.cpp + constraints/MinDownTime.h + constraints/MinDownTime.cpp + ) diff --git a/src/solver/optimisation/constraints/AreaBalance.cpp b/src/solver/optimisation/constraints/AreaBalance.cpp new file mode 100644 index 0000000000..2a39f3be83 --- /dev/null +++ b/src/solver/optimisation/constraints/AreaBalance.cpp @@ -0,0 +1,52 @@ +#include "AreaBalance.h" + +static void shortTermStorageBalance(const ::ShortTermStorage::AREA_INPUT& shortTermStorageInput, + ConstraintBuilder& constraintBuilder) +{ + for (const auto& storage : shortTermStorageInput) + { + unsigned index = storage.clusterGlobalIndex; + constraintBuilder.ShortTermStorageInjection(index, 1.0) + .ShortTermStorageWithdrawal(index, -1.0); + } +} + +void AreaBalance::add(int pdt, int pays) +{ + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesBilansPays[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.AreaBalance(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt); + + int interco = problemeHebdo->IndexDebutIntercoOrigine[pays]; + while (interco >= 0) + { + builder.NTCDirect(interco, 1.0); + interco = problemeHebdo->IndexSuivantIntercoOrigine[interco]; + } + + interco = problemeHebdo->IndexDebutIntercoExtremite[pays]; + while (interco >= 0) + { + builder.NTCDirect(interco, -1.0); + interco = problemeHebdo->IndexSuivantIntercoExtremite[interco]; + } + + exportPaliers(*problemeHebdo, builder, pays); + builder.HydProd(pays, -1.0) + .Pumping(pays, 1.0) + .PositiveUnsuppliedEnergy(pays, -1.0) + .NegativeUnsuppliedEnergy(pays, 1.0); + + shortTermStorageBalance(problemeHebdo->ShortTermStorage[pays], builder); + + builder.equalTo(); + builder.build(); +} diff --git a/src/solver/optimisation/constraints/AreaBalance.h b/src/solver/optimisation/constraints/AreaBalance.h new file mode 100644 index 0000000000..a800a288ed --- /dev/null +++ b/src/solver/optimisation/constraints/AreaBalance.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Area Balance' constraint type + */ +class AreaBalance : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param pays : area + */ + void add(int pdt, int pays); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/AreaHydroLevel.cpp b/src/solver/optimisation/constraints/AreaHydroLevel.cpp new file mode 100644 index 0000000000..228620b519 --- /dev/null +++ b/src/solver/optimisation/constraints/AreaHydroLevel.cpp @@ -0,0 +1,32 @@ +#include "AreaHydroLevel.h" + +void AreaHydroLevel::add(int pays, int pdt) +{ + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesNiveauxPays[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + if (problemeHebdo->CaracteristiquesHydrauliques[pays].SuiviNiveauHoraire) + { + builder.updateHourWithinWeek(pdt).HydroLevel(pays, 1.0); + if (pdt > 0) + { + builder.updateHourWithinWeek(pdt - 1).HydroLevel(pays, -1.0); + } + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.AreaHydroLevel(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesNiveauxPays[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + builder.updateHourWithinWeek(pdt) + .HydProd(pays, 1.0) + .Pumping(pays, -problemeHebdo->CaracteristiquesHydrauliques[pays].PumpingRatio) + .Overflow(pays, 1.) + .equalTo() + .build(); + } + else + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesNiveauxPays[pays] = -1; +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/AreaHydroLevel.h b/src/solver/optimisation/constraints/AreaHydroLevel.h new file mode 100644 index 0000000000..2af93b076c --- /dev/null +++ b/src/solver/optimisation/constraints/AreaHydroLevel.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Area Hydraulic Level' constraint type + */ +class AreaHydroLevel : private ConstraintFactory +{ + public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param pays : area + */ + void add(int pays, int pdt); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/BindingConstraintDay.cpp b/src/solver/optimisation/constraints/BindingConstraintDay.cpp new file mode 100644 index 0000000000..d55a7edb15 --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintDay.cpp @@ -0,0 +1,69 @@ +#include "BindingConstraintDay.h" + +void BindingConstraintDay::add(int cntCouplante) +{ + const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes + = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; + if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante != CONTRAINTE_JOURNALIERE) + return; + + const int nbInterco + = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; + const int nbClusters + = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; + + const int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + const int NombreDePasDeTempsDUneJournee = problemeHebdo->NombreDePasDeTempsDUneJournee; + int pdtDebut = 0; + while (pdtDebut < NombreDePasDeTempsPourUneOptimisation) + { + int jour = problemeHebdo->NumeroDeJourDuPasDeTemps[pdtDebut]; + CORRESPONDANCES_DES_CONTRAINTES_JOURNALIERES& CorrespondanceCntNativesCntOptimJournalieres + = problemeHebdo->CorrespondanceCntNativesCntOptimJournalieres[jour]; + + for (int index = 0; index < nbInterco; index++) + { + int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; + double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; + int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; + + for (int pdt = pdtDebut; pdt < pdtDebut + NombreDePasDeTempsDUneJournee; pdt++) + { + builder.updateHourWithinWeek(pdt).NTCDirect( + interco, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + } + + for (int index = 0; index < nbClusters; index++) + { + int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + const int palier + = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques + [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; + double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; + int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; + + for (int pdt = pdtDebut; pdt < pdtDebut + NombreDePasDeTempsDUneJournee; pdt++) + { + builder.updateHourWithinWeek(pdt).DispatchableProduction( + palier, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + } + + CorrespondanceCntNativesCntOptimJournalieres + .NumeroDeContrainteDesContraintesCouplantes[cntCouplante] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + char op = MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante; + builder.SetOperator(op); + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateTimeStep(jour); + namer.BindingConstraintDay(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); + builder.build(); + pdtDebut += problemeHebdo->NombreDePasDeTempsDUneJournee; + } +} diff --git a/src/solver/optimisation/constraints/BindingConstraintDay.h b/src/solver/optimisation/constraints/BindingConstraintDay.h new file mode 100644 index 0000000000..1fff7b54a7 --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintDay.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Daily Binding Constraint' type + */ +class BindingConstraintDay : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param cntCouplante : the binding constraint number + */ + void add(int cntCouplante); +}; diff --git a/src/solver/optimisation/constraints/BindingConstraintHour.cpp b/src/solver/optimisation/constraints/BindingConstraintHour.cpp new file mode 100644 index 0000000000..d6dfe999ac --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintHour.cpp @@ -0,0 +1,53 @@ +#include "BindingConstraintHour.h" + +void BindingConstraintHour::add(int pdt, int cntCouplante) +{ + const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes + = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesContraintesCouplantes[cntCouplante] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante != CONTRAINTE_HORAIRE) + return; + + builder.updateHourWithinWeek(pdt); + // Links + const int nbInterco + = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; + for (int index = 0; index < nbInterco; index++) + { + const int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; + const double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; + const int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; + + builder.updateHourWithinWeek(pdt).NTCDirect( + interco, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + + // Thermal clusters + const int nbClusters + = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; + for (int index = 0; index < nbClusters; index++) + { + const int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + const int palier = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques + [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; + const double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; + const int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; + + builder.updateHourWithinWeek(pdt).DispatchableProduction( + palier, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + + char op = MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante; + builder.SetOperator(op); + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.BindingConstraintHour(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); + builder.build(); +} diff --git a/src/solver/optimisation/constraints/BindingConstraintHour.h b/src/solver/optimisation/constraints/BindingConstraintHour.h new file mode 100644 index 0000000000..bad823047d --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintHour.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hourly Binding Constraint' type + */ +class BindingConstraintHour : private ConstraintFactory +{ + public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param cntCouplante : the binding constraint number + */ + void add(int pdt, int cntCouplante); +}; diff --git a/src/solver/optimisation/constraints/BindingConstraintWeek.cpp b/src/solver/optimisation/constraints/BindingConstraintWeek.cpp new file mode 100644 index 0000000000..4524c2702b --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintWeek.cpp @@ -0,0 +1,59 @@ +#include "BindingConstraintWeek.h" + +void BindingConstraintWeek::add(int cntCouplante) +{ + const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes + = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; + int semaine = problemeHebdo->weekInTheYear; + CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondanceCntNativesCntOptimHebdomadaires + = problemeHebdo->CorrespondanceCntNativesCntOptimHebdomadaires; + if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante != CONTRAINTE_HEBDOMADAIRE) + return; + + const int nbInterco + = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; + const int nbClusters + = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; + + for (int index = 0; index < nbInterco; index++) + { + int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; + double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; + int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; + for (int pdt = 0; pdt < problemeHebdo->NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt).NTCDirect( + interco, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + } + + for (int index = 0; index < nbClusters; index++) + { + int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + const int palier + = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques + [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; + double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; + int offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; + for (int pdt = 0; pdt < problemeHebdo->NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt).DispatchableProduction( + palier, poids, offset, problemeHebdo->NombreDePasDeTemps); + } + } + + char op = MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante; + builder.SetOperator(op); + + CorrespondanceCntNativesCntOptimHebdomadaires + .NumeroDeContrainteDesContraintesCouplantes[cntCouplante] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateTimeStep(semaine); + namer.BindingConstraintWeek(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); + builder.build(); +} diff --git a/src/solver/optimisation/constraints/BindingConstraintWeek.h b/src/solver/optimisation/constraints/BindingConstraintWeek.h new file mode 100644 index 0000000000..b94698e5d0 --- /dev/null +++ b/src/solver/optimisation/constraints/BindingConstraintWeek.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hourly Binding Constraint' type + */ +class BindingConstraintWeek : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param cntCouplante : the binding constraint number + */ + void add(int cntCouplante); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.cpp b/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.cpp new file mode 100644 index 0000000000..432d84414a --- /dev/null +++ b/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.cpp @@ -0,0 +1,47 @@ +#include "ConsistenceNumberOfDispatchableUnits.h" + +void ConsistenceNumberOfDispatchableUnits::add(int pays, + int cluster, + int clusterIndex, + int pdt, + bool Simulation) +{ + if (!Simulation) + { + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + + int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + int Pdtmoins1 = pdt - 1; + if (Pdtmoins1 < 0) + Pdtmoins1 = NombreDePasDeTempsPourUneOptimisation + Pdtmoins1; + + builder.updateHourWithinWeek(pdt) + .NumberOfDispatchableUnits(cluster, 1.0) + .updateHourWithinWeek(Pdtmoins1) + .NumberOfDispatchableUnits(cluster, -1) + .updateHourWithinWeek(pdt) + .NumberStartingDispatchableUnits(cluster, -1) + .NumberStoppingDispatchableUnits(cluster, 1) + .equalTo(); + + if (builder.NumberOfVariables() > 0) + { + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.ConsistenceNODU(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + + builder.build(); + } + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage += 4; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.h b/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.h new file mode 100644 index 0000000000..ae3b1341b8 --- /dev/null +++ b/src/solver/optimisation/constraints/ConsistenceNumberOfDispatchableUnits.h @@ -0,0 +1,20 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Consistence Number Of Dispatchable Units Constraint' type + */ +class ConsistenceNumberOfDispatchableUnits : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/ConstraintBuilder.cpp b/src/solver/optimisation/constraints/ConstraintBuilder.cpp new file mode 100644 index 0000000000..195d8dad30 --- /dev/null +++ b/src/solver/optimisation/constraints/ConstraintBuilder.cpp @@ -0,0 +1,244 @@ +#include "ConstraintBuilder.h" + +void ConstraintBuilder::build() +{ + std::vector& Pi = problemeAResoudre.Pi; + std::vector& Colonne = problemeAResoudre.Colonne; + + if (nombreDeTermes_ > 0) + { + OPT_ChargerLaContrainteDansLaMatriceDesContraintes( + &problemeAResoudre, Pi, Colonne, nombreDeTermes_, operator_); + } + nombreDeTermes_ = 0; +} + +int ConstraintBuilder::GetShiftedTimeStep(int offset, int delta) const +{ + int pdt = hourInWeek_ + offset; + const int nbTimeSteps = problemeHebdo.NombreDePasDeTempsPourUneOptimisation; + + if (const bool shifted_timestep = offset != 0; shifted_timestep) + { + if (offset >= 0) + { + pdt = pdt % nbTimeSteps; + } + else + { + pdt = (pdt + delta) % nbTimeSteps; + } + } + return pdt; +} + +void ConstraintBuilder::AddVariable(int varIndex, double coeff) +{ + std::vector& Pi = problemeAResoudre.Pi; + std::vector& Colonne = problemeAResoudre.Colonne; + if (varIndex >= 0) + { + Pi[nombreDeTermes_] = coeff; + Colonne[nombreDeTermes_] = varIndex; + nombreDeTermes_++; + } +} + +Variable::VariableManager ConstraintBuilder::GetVariableManager(int offset, int delta) const +{ + auto pdt = GetShiftedTimeStep(offset, delta); + return Variable::VariableManager(varNative[pdt], + problemeHebdo.NumeroDeVariableStockFinal, + problemeHebdo.NumeroDeVariableDeTrancheDeStock); +} + +ConstraintBuilder& ConstraintBuilder::DispatchableProduction(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).DispatchableProduction(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NumberOfDispatchableUnits(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NumberOfDispatchableUnits(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NumberStoppingDispatchableUnits(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NumberStoppingDispatchableUnits(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NumberStartingDispatchableUnits(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NumberStartingDispatchableUnits(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NumberBreakingDownDispatchableUnits(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NumberBreakingDownDispatchableUnits(index), + coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NTCDirect(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NTCDirect(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::IntercoDirectCost(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).IntercoDirectCost(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::IntercoIndirectCost(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).IntercoIndirectCost(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::ShortTermStorageInjection(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).ShortTermStorageInjection(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::ShortTermStorageWithdrawal(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).ShortTermStorageWithdrawal(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::ShortTermStorageLevel(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).ShortTermStorageLevel(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::HydProd(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).HydProd(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::HydProdDown(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).HydProdDown(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::HydProdUp(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).HydProdUp(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::Pumping(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).Pumping(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::HydroLevel(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).HydroLevel(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::Overflow(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).Overflow(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::FinalStorage(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).FinalStorage(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::PositiveUnsuppliedEnergy(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).PositiveUnsuppliedEnergy(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::NegativeUnsuppliedEnergy(unsigned int index, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).NegativeUnsuppliedEnergy(index), coeff); + return *this; +} + +ConstraintBuilder& ConstraintBuilder::LayerStorage(unsigned area, + unsigned layer, + double coeff, + int offset, + int delta) +{ + AddVariable(GetVariableManager(offset, delta).LayerStorage(area, layer), coeff); + return *this; +} diff --git a/src/solver/optimisation/constraints/ConstraintBuilder.h b/src/solver/optimisation/constraints/ConstraintBuilder.h new file mode 100644 index 0000000000..0ef7bf5675 --- /dev/null +++ b/src/solver/optimisation/constraints/ConstraintBuilder.h @@ -0,0 +1,383 @@ +#pragma once + +#include +#include "../opt_structure_probleme_a_resoudre.h" +#include "../opt_rename_problem.h" +#include "../opt_fonctions.h" +#include "../../simulation/sim_structure_probleme_economique.h" + +#include + +namespace Variable +{ + +/*! +Factory class that hold variables indices +*/ +class VariableManager +{ +public: + VariableManager(const CORRESPONDANCES_DES_VARIABLES& nativeOptimVar, + const std::vector& NumeroDeVariableStockFinal, + const std::vector>& NumeroDeVariableDeTrancheDeStock) : + nativeOptimVar(nativeOptimVar), + NumeroDeVariableStockFinal(NumeroDeVariableStockFinal), + NumeroDeVariableDeTrancheDeStock(NumeroDeVariableDeTrancheDeStock) + { + } + + int DispatchableProduction(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDuPalierThermique[index]; + } + + int NumberOfDispatchableUnits(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[index]; + } + + int NumberStoppingDispatchableUnits(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDuNombreDeGroupesQuiSArretentDuPalierThermique[index]; + } + + int NumberStartingDispatchableUnits(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDuNombreDeGroupesQuiDemarrentDuPalierThermique[index]; + } + + int NumberBreakingDownDispatchableUnits(unsigned int index) const + { + return nativeOptimVar + .NumeroDeVariableDuNombreDeGroupesQuiTombentEnPanneDuPalierThermique[index]; + } + + int NTCDirect(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDeLInterconnexion[index]; + } + + int IntercoDirectCost(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableCoutOrigineVersExtremiteDeLInterconnexion[index]; + } + + int IntercoIndirectCost(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableCoutExtremiteVersOrigineDeLInterconnexion[index]; + } + + int ShortTermStorageInjection(unsigned int index) const + { + return nativeOptimVar.SIM_ShortTermStorage.InjectionVariable[index]; + } + + int ShortTermStorageWithdrawal(unsigned int index) const + { + return nativeOptimVar.SIM_ShortTermStorage.WithdrawalVariable[index]; + } + + int ShortTermStorageLevel(unsigned int index) const + { + return nativeOptimVar.SIM_ShortTermStorage.LevelVariable[index]; + } + + int HydProd(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesDeLaProdHyd[index]; + } + + int HydProdDown(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesVariationHydALaBaisse[index]; + } + + int HydProdUp(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesVariationHydALaHausse[index]; + } + + int Pumping(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesDePompage[index]; + } + + int HydroLevel(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesDeNiveau[index]; + } + + int Overflow(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariablesDeDebordement[index]; + } + + int FinalStorage(unsigned int index) const + { + return NumeroDeVariableStockFinal[index]; + } + + int LayerStorage(unsigned area, unsigned layer) const + { + return NumeroDeVariableDeTrancheDeStock[area][layer]; + } + + int PositiveUnsuppliedEnergy(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDefaillancePositive[index]; + } + + int NegativeUnsuppliedEnergy(unsigned int index) const + { + return nativeOptimVar.NumeroDeVariableDefaillanceNegative[index]; + } + +private: + const CORRESPONDANCES_DES_VARIABLES& nativeOptimVar; + const std::vector& NumeroDeVariableStockFinal; + const std::vector>& NumeroDeVariableDeTrancheDeStock; +}; + +} // namespace Variable + +/*! \verbatim +this class build up the business object 'Constraint', +Math: +|coeff11 coeff12 .. coeff1n||var1| |sign_1| |rhs1| |constraint1||sign_1||rhs1| +|.. .. ...||....| |......| |....| <===> |...........||......||....| +|coeffn1 coeffn2 .. coeffnn||varn| |sign_n| |rhsn| |constraintn||sign_n||rhsn| + +it propose a set of methods to attach 'Variables' to the Constraint +ex: calling NTCDirect() implies adding Direct NTC Variable to the current Constraint +finally the build() method gather all variables and put them into the matrix +\endverbatim +*/ +class ConstraintBuilder +{ +public: + ConstraintBuilder( + PROBLEME_HEBDO& problemeHebdo, + const std::vector& CorrespondanceVarNativesVarOptim) : + problemeHebdo(problemeHebdo), + problemeAResoudre(*problemeHebdo.ProblemeAResoudre), + varNative(CorrespondanceVarNativesVarOptim) + { + } + + ConstraintBuilder& updateHourWithinWeek(unsigned hour) + { + hourInWeek_ = hour; + return *this; + } + + /** @name variables_method + * @brief Documentation for non obvious methods + * @param index: local index of the variable + * @param offset: offset from the current time step + * @param delta: number of time steps for the variable + * @return reference of *this + */ + //@{ + ConstraintBuilder& DispatchableProduction(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& NumberOfDispatchableUnits(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& NumberStoppingDispatchableUnits(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& NumberStartingDispatchableUnits(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& NumberBreakingDownDispatchableUnits(unsigned int index, + double coeff, + int offset = 0, + + int delta = 0); + + ConstraintBuilder& NTCDirect(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& IntercoDirectCost(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& IntercoIndirectCost(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& ShortTermStorageInjection(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& ShortTermStorageWithdrawal(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& ShortTermStorageLevel(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& HydProd(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& HydProdDown(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& HydProdUp(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& Pumping(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& HydroLevel(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& Overflow(unsigned int index, double coeff, int offset = 0, int delta = 0); + + ConstraintBuilder& FinalStorage(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& PositiveUnsuppliedEnergy(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + ConstraintBuilder& NegativeUnsuppliedEnergy(unsigned int index, + double coeff, + int offset = 0, + int delta = 0); + + ConstraintBuilder& LayerStorage(unsigned area, + unsigned layer, + double coeff, + int offset = 0, + int delta = 0); + //@} + + class ConstraintBuilderInvalidOperator : public std::runtime_error + { + public: + using std::runtime_error::runtime_error; + }; + + /*! + @brief set the operator of the constraint (sign) + @param op: the operator of the constraint + @return reference of *this + */ + ConstraintBuilder& SetOperator(char op) + { + if (op == '<' || op == '=' || op == '>') + { + operator_ = op; + } + else + throw ConstraintBuilderInvalidOperator(std::string("Invalid operator: ") + op); + + return *this; + } + + /*! + @brief set the sign of the constraint to '=', + building a constraint equal to rhs + @return reference of *this + */ + ConstraintBuilder& equalTo() + { + operator_ = '='; + return *this; + } + + /*! + @brief set the sign of the constraint to '<', + building a constraint less than rhs + @return reference of *this + */ + ConstraintBuilder& lessThan() + { + operator_ = '<'; + return *this; + } + + /*! + @brief set the sign of the constraint to '>', + building a constraint greather than rhs + @return reference of *this + */ + ConstraintBuilder& greaterThan() + { + operator_ = '>'; + return *this; + } + + /*! + @brief add the constraint in the matrix + @return + */ + void build(); + + int NumberOfVariables() const + { + return nombreDeTermes_; + } + +private: + PROBLEME_HEBDO& problemeHebdo; + PROBLEME_ANTARES_A_RESOUDRE& problemeAResoudre; + const std::vector& varNative; + + unsigned int hourInWeek_ = 0; + + char operator_ = '='; + int nombreDeTermes_ = 0; + + int GetShiftedTimeStep(int offset, int delta) const; + void AddVariable(int index, double coeff); + + /*! + * @brief + * @param offset: offset from the current time step + * @param delta: number of time steps for the variable + * @return VariableManager object + */ + Variable::VariableManager GetVariableManager(int offset = 0, int delta = 0) const; +}; + +/*! factory class to build a Constraint */ +class ConstraintFactory +{ +public: + explicit ConstraintFactory(PROBLEME_HEBDO* problemeHebdo) : + problemeHebdo(problemeHebdo), + builder(*problemeHebdo, problemeHebdo->CorrespondanceVarNativesVarOptim) + { + } + + PROBLEME_HEBDO* problemeHebdo; + ConstraintBuilder builder; +}; + +// Helper functions +inline void exportPaliers(const PROBLEME_HEBDO& problemeHebdo, + ConstraintBuilder& constraintBuilder, + int pays) +{ + const PALIERS_THERMIQUES& PaliersThermiquesDuPays = problemeHebdo.PaliersThermiquesDuPays[pays]; + + for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) + { + const int palier + = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index]; + constraintBuilder.DispatchableProduction(palier, -1.0); + } +} diff --git a/src/solver/optimisation/constraints/FictitiousLoad.cpp b/src/solver/optimisation/constraints/FictitiousLoad.cpp new file mode 100644 index 0000000000..2a818dbed9 --- /dev/null +++ b/src/solver/optimisation/constraints/FictitiousLoad.cpp @@ -0,0 +1,24 @@ + +#include "FictitiousLoad.h" + +void FictitiousLoad::add(int pdt, int pays) +{ + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContraintePourEviterLesChargesFictives[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.FictiveLoads(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt); + exportPaliers(*problemeHebdo, builder, pays); + auto coeff = problemeHebdo->DefaillanceNegativeUtiliserHydro[pays] ? -1 : 0; + builder.HydProd(pays, coeff).NegativeUnsuppliedEnergy(pays, 1.0); + + builder.lessThan(); + builder.build(); +} diff --git a/src/solver/optimisation/constraints/FictitiousLoad.h b/src/solver/optimisation/constraints/FictitiousLoad.h new file mode 100644 index 0000000000..077f3cfba5 --- /dev/null +++ b/src/solver/optimisation/constraints/FictitiousLoad.h @@ -0,0 +1,19 @@ + +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Fictitious Load' constraint type + */ +class FictitiousLoad : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param pays : area + */ + void add(int pdt, int pays); +}; diff --git a/src/solver/optimisation/constraints/FinalStockEquivalent.cpp b/src/solver/optimisation/constraints/FinalStockEquivalent.cpp new file mode 100644 index 0000000000..a00c9bd55a --- /dev/null +++ b/src/solver/optimisation/constraints/FinalStockEquivalent.cpp @@ -0,0 +1,25 @@ +#include "FinalStockEquivalent.h" + +void FinalStockEquivalent::add(int pays) +{ + const auto pdt = problemeHebdo->NombreDePasDeTempsPourUneOptimisation - 1; + if (problemeHebdo->CaracteristiquesHydrauliques[pays].AccurateWaterValue + && problemeHebdo->CaracteristiquesHydrauliques[pays].DirectLevelAccess) + { /* equivalence constraint : StockFinal- Niveau[T]= 0*/ + + problemeHebdo->NumeroDeContrainteEquivalenceStockFinal[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.FinalStockEquivalent(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt) + .FinalStorage(pays, 1.0) + .updateHourWithinWeek(problemeHebdo->NombreDePasDeTempsPourUneOptimisation - 1) + .HydroLevel(pays, -1.0) + .equalTo() + .build(); + } +} diff --git a/src/solver/optimisation/constraints/FinalStockEquivalent.h b/src/solver/optimisation/constraints/FinalStockEquivalent.h new file mode 100644 index 0000000000..19eb89985f --- /dev/null +++ b/src/solver/optimisation/constraints/FinalStockEquivalent.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Final Stock Equivalent' constraint type + */ +class FinalStockEquivalent : private ConstraintFactory +{ + public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; diff --git a/src/solver/optimisation/constraints/FinalStockExpression.cpp b/src/solver/optimisation/constraints/FinalStockExpression.cpp new file mode 100644 index 0000000000..083936ae9b --- /dev/null +++ b/src/solver/optimisation/constraints/FinalStockExpression.cpp @@ -0,0 +1,25 @@ +#include "FinalStockExpression.h" + +void FinalStockExpression::add(int pays) +{ + const auto pdt = problemeHebdo->NombreDePasDeTempsPourUneOptimisation - 1; + + if (problemeHebdo->CaracteristiquesHydrauliques[pays].AccurateWaterValue) + /* expression constraint : - StockFinal +sum (stocklayers) = 0*/ + { + builder.updateHourWithinWeek(pdt).FinalStorage(pays, -1.0); + for (int layerindex = 0; layerindex < 100; layerindex++) + { + builder.LayerStorage(pays, layerindex, 1.0); + } + problemeHebdo->NumeroDeContrainteExpressionStockFinal[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.FinalStockExpression(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + builder.equalTo().build(); + } +} diff --git a/src/solver/optimisation/constraints/FinalStockExpression.h b/src/solver/optimisation/constraints/FinalStockExpression.h new file mode 100644 index 0000000000..ea96c0319e --- /dev/null +++ b/src/solver/optimisation/constraints/FinalStockExpression.h @@ -0,0 +1,17 @@ +#pragma once + +#include "ConstraintBuilder.h" + +/*! + * represent 'Final Stock Expression' constraint type + */ +class FinalStockExpression : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; diff --git a/src/solver/optimisation/constraints/FlowDissociation.cpp b/src/solver/optimisation/constraints/FlowDissociation.cpp new file mode 100644 index 0000000000..af172ffd11 --- /dev/null +++ b/src/solver/optimisation/constraints/FlowDissociation.cpp @@ -0,0 +1,31 @@ +#include "FlowDissociation.h" + +void FlowDissociation::add(int pdt, int interco) +{ + if (const COUTS_DE_TRANSPORT& CoutDeTransport = problemeHebdo->CoutDeTransport[interco]; + CoutDeTransport.IntercoGereeAvecDesCouts) + { + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDeDissociationDeFlux[interco] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + const auto origin + = problemeHebdo->NomsDesPays[problemeHebdo->PaysOrigineDeLInterconnexion[interco]]; + const auto destination + = problemeHebdo->NomsDesPays[problemeHebdo->PaysExtremiteDeLInterconnexion[interco]]; + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.FlowDissociation( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes, origin, destination); + + builder.updateHourWithinWeek(pdt); + builder.NTCDirect(interco, 1.0) + .IntercoDirectCost(interco, -1.0) + .IntercoIndirectCost(interco, 1.0); + + builder.equalTo(); + + builder.build(); + } +} diff --git a/src/solver/optimisation/constraints/FlowDissociation.h b/src/solver/optimisation/constraints/FlowDissociation.h new file mode 100644 index 0000000000..27d30af947 --- /dev/null +++ b/src/solver/optimisation/constraints/FlowDissociation.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Flow Dissociation' constraint type + */ +class FlowDissociation : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param interco : interconnection number + */ + void add(int pdt, int interco); +}; diff --git a/src/solver/optimisation/constraints/HydroPower.cpp b/src/solver/optimisation/constraints/HydroPower.cpp new file mode 100644 index 0000000000..abc04f52bc --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPower.cpp @@ -0,0 +1,47 @@ +#include "HydroPower.h" + +void HydroPower::add(int pays) +{ + bool presenceHydro + = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable; + bool TurbEntreBornes = problemeHebdo->CaracteristiquesHydrauliques[pays].TurbinageEntreBornes; + + const int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + if (presenceHydro && !TurbEntreBornes) + { + if (bool presencePompage + = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable) + { + problemeHebdo->NumeroDeContrainteEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + const double pumpingRatio + = problemeHebdo->CaracteristiquesHydrauliques[pays].PumpingRatio; + for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt); + builder.HydProd(pays, 1.0).Pumping(pays, -pumpingRatio); + } + } + else + { + for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt); + builder.HydProd(pays, 1.0); + } + } + problemeHebdo->NumeroDeContrainteEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + builder.equalTo(); + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear); + namer.HydroPower(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + builder.build(); + } + else + problemeHebdo->NumeroDeContrainteEnergieHydraulique[pays] = -1; +} diff --git a/src/solver/optimisation/constraints/HydroPower.h b/src/solver/optimisation/constraints/HydroPower.h new file mode 100644 index 0000000000..50ecc1de14 --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPower.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hydraulic Power' constraint type + */ +class HydroPower : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.cpp b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.cpp new file mode 100644 index 0000000000..dbe0760d92 --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.cpp @@ -0,0 +1,22 @@ +#include "HydroPowerSmoothingUsingVariationMaxDown.h" + +void HydroPowerSmoothingUsingVariationMaxDown::add(int pays, int pdt) +{ + if (!problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable) + { + return; + } + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.HydroPowerSmoothingUsingVariationMaxDown( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt) + .HydProd(pays, 1.0) + .updateHourWithinWeek(0) + .HydProdDown(pays, -1.0) + .lessThan() + .build(); +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.h b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.h new file mode 100644 index 0000000000..a802cf76af --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxDown.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hydraulic Power Smoothing Using Variation Max Down' constraint type + */ +class HydroPowerSmoothingUsingVariationMaxDown : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param pays : area + */ + void add(int pays, int pdt); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.cpp b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.cpp new file mode 100644 index 0000000000..5692ba998c --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.cpp @@ -0,0 +1,22 @@ +#include "HydroPowerSmoothingUsingVariationMaxUp.h" + +void HydroPowerSmoothingUsingVariationMaxUp::add(int pays, int pdt) +{ + if (!problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable) + { + return; + } + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.HydroPowerSmoothingUsingVariationMaxUp( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt) + .HydProd(pays, 1.0) + .updateHourWithinWeek(0) + .HydProdUp(pays, -1.0) + .greaterThan() + .build(); +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.h b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.h new file mode 100644 index 0000000000..d1d6300c81 --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationMaxUp.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hydraulic Power Smoothing Using Variation Max Up' constraint type + */ +class HydroPowerSmoothingUsingVariationMaxUp : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pdt : timestep + * @param pays : area + */ + void add(int pays, int pdt); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.cpp b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.cpp new file mode 100644 index 0000000000..898f55dfda --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.cpp @@ -0,0 +1,33 @@ +#include "HydroPowerSmoothingUsingVariationSum.h" + +void HydroPowerSmoothingUsingVariationSum::add(int pays) +{ + if (!problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable) + { + return; + } + + const int nombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) + { + int pdt1 = pdt + 1; + if (pdt1 >= nombreDePasDeTempsPourUneOptimisation) + pdt1 = 0; + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.HydroPowerSmoothingUsingVariationSum( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.updateHourWithinWeek(pdt) + .HydProd(pays, 1.0) + .updateHourWithinWeek(pdt1) + .HydProd(pays, -1.0) + .updateHourWithinWeek(pdt) + .HydProdDown(pays, -1.0) + .HydProdUp(pays, 1.0) + .equalTo() + .build(); + } +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.h b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.h new file mode 100644 index 0000000000..1a671b27fd --- /dev/null +++ b/src/solver/optimisation/constraints/HydroPowerSmoothingUsingVariationSum.h @@ -0,0 +1,17 @@ + +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Hydraulic Power Smoothing Using Variation Sum' constraint type + */ +class HydroPowerSmoothingUsingVariationSum : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MaxHydroPower.cpp b/src/solver/optimisation/constraints/MaxHydroPower.cpp new file mode 100644 index 0000000000..80edf424a6 --- /dev/null +++ b/src/solver/optimisation/constraints/MaxHydroPower.cpp @@ -0,0 +1,35 @@ +#include "MaxHydroPower.h" + +void MaxHydroPower::add(int pays) +{ + bool presenceHydro + = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable; + bool TurbEntreBornes = problemeHebdo->CaracteristiquesHydrauliques[pays].TurbinageEntreBornes; + if (presenceHydro + && (TurbEntreBornes + || problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable)) + { + problemeHebdo->NumeroDeContrainteMaxEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + const int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt); + builder.HydProd(pays, 1.0); + } + problemeHebdo->NumeroDeContrainteMaxEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear); + namer.MaxHydroPower(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + + builder.lessThan().build(); + } + else + problemeHebdo->NumeroDeContrainteMaxEnergieHydraulique[pays] = -1; +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MaxHydroPower.h b/src/solver/optimisation/constraints/MaxHydroPower.h new file mode 100644 index 0000000000..f89ae370f4 --- /dev/null +++ b/src/solver/optimisation/constraints/MaxHydroPower.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Max Hydraulic Power' constraint type + */ +class MaxHydroPower : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MaxPumping.cpp b/src/solver/optimisation/constraints/MaxPumping.cpp new file mode 100644 index 0000000000..94e68f6ed4 --- /dev/null +++ b/src/solver/optimisation/constraints/MaxPumping.cpp @@ -0,0 +1,28 @@ +#include "MaxPumping.h" + +void MaxPumping::add(int pays) +{ + if (problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable) + { + problemeHebdo->NumeroDeContrainteMaxPompage[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + const int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt); + builder.Pumping(pays, 1.0); + } + problemeHebdo->NumeroDeContrainteMaxPompage[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear); + namer.MaxPumping(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + builder.lessThan().build(); + } + else + problemeHebdo->NumeroDeContrainteMaxPompage[pays] = -1; +} \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MaxPumping.h b/src/solver/optimisation/constraints/MaxPumping.h new file mode 100644 index 0000000000..6e1a9f4809 --- /dev/null +++ b/src/solver/optimisation/constraints/MaxPumping.h @@ -0,0 +1,17 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Max Pumping' constraint type + */ +class MaxPumping : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MinDownTime.cpp b/src/solver/optimisation/constraints/MinDownTime.cpp new file mode 100644 index 0000000000..e70e220e54 --- /dev/null +++ b/src/solver/optimisation/constraints/MinDownTime.cpp @@ -0,0 +1,50 @@ +#include "MinDownTime.h" + +void MinDownTime::add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation) +{ + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + const int DureeMinimaleDArretDUnGroupeDuPalierThermique + = PaliersThermiquesDuPays.DureeMinimaleDArretDUnGroupeDuPalierThermique[clusterIndex]; + + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesContraintesDeDureeMinDArret[cluster] = -1; + if (!Simulation) + { + int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + builder.updateHourWithinWeek(pdt).NumberOfDispatchableUnits(cluster, 1.0); + + for (int k = pdt - DureeMinimaleDArretDUnGroupeDuPalierThermique + 1; k <= pdt; k++) + { + int t1 = k; + if (t1 < 0) + t1 = NombreDePasDeTempsPourUneOptimisation + t1; + + builder.updateHourWithinWeek(t1).NumberStoppingDispatchableUnits(cluster, 1.0); + } + builder.lessThan(); + if (builder.NumberOfVariables() > 1) + { + CorrespondanceCntNativesCntOptim + .NumeroDeContrainteDesContraintesDeDureeMinDArret[cluster] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.MinDownTime(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + + builder.build(); + } + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage + += 1 + DureeMinimaleDArretDUnGroupeDuPalierThermique; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/MinDownTime.h b/src/solver/optimisation/constraints/MinDownTime.h new file mode 100644 index 0000000000..5d24da5058 --- /dev/null +++ b/src/solver/optimisation/constraints/MinDownTime.h @@ -0,0 +1,20 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'MinDownTime' Constraint type + */ +class MinDownTime : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/MinHydroPower.cpp b/src/solver/optimisation/constraints/MinHydroPower.cpp new file mode 100644 index 0000000000..025542f9ba --- /dev/null +++ b/src/solver/optimisation/constraints/MinHydroPower.cpp @@ -0,0 +1,34 @@ +#include "MinHydroPower.h" + +void MinHydroPower::add(int pays) +{ + bool presenceHydro + = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable; + bool TurbEntreBornes = problemeHebdo->CaracteristiquesHydrauliques[pays].TurbinageEntreBornes; + if (presenceHydro + && (TurbEntreBornes + || problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable)) + { + problemeHebdo->NumeroDeContrainteMinEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + const int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear); + namer.MinHydroPower(problemeHebdo->ProblemeAResoudre->NombreDeContraintes); + for (int pdt = 0; pdt < NombreDePasDeTempsPourUneOptimisation; pdt++) + { + builder.updateHourWithinWeek(pdt); + builder.HydProd(pays, 1.0); + } + + problemeHebdo->NumeroDeContrainteMinEnergieHydraulique[pays] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + builder.greaterThan().build(); + } + else + problemeHebdo->NumeroDeContrainteMinEnergieHydraulique[pays] = -1; +} diff --git a/src/solver/optimisation/constraints/MinHydroPower.h b/src/solver/optimisation/constraints/MinHydroPower.h new file mode 100644 index 0000000000..8b7dfb1892 --- /dev/null +++ b/src/solver/optimisation/constraints/MinHydroPower.h @@ -0,0 +1,18 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Min Hydraulic Power' constraint type + */ +class MinHydroPower : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + */ + void add(int pays); +}; + diff --git a/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.cpp b/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.cpp new file mode 100644 index 0000000000..31c23ac290 --- /dev/null +++ b/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.cpp @@ -0,0 +1,59 @@ +#include "NbDispUnitsMinBoundSinceMinUpTime.h" + +void NbDispUnitsMinBoundSinceMinUpTime::add(int pays, + int cluster, + int clusterIndex, + int pdt, + bool Simulation) +{ + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + const int DureeMinimaleDeMarcheDUnGroupeDuPalierThermique + = PaliersThermiquesDuPays.DureeMinimaleDeMarcheDUnGroupeDuPalierThermique[clusterIndex]; + + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesContraintesDeDureeMinDeMarche[cluster] + = -1; + if (!Simulation) + { + int NombreDePasDeTempsPourUneOptimisation + = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; + + builder.updateHourWithinWeek(pdt).NumberOfDispatchableUnits(cluster, 1.0); + + for (int k = pdt - DureeMinimaleDeMarcheDUnGroupeDuPalierThermique + 1; k <= pdt; k++) + { + int t1 = k; + if (t1 < 0) + t1 = NombreDePasDeTempsPourUneOptimisation + t1; + + builder.updateHourWithinWeek(t1) + .NumberStartingDispatchableUnits(cluster, -1.0) + .NumberBreakingDownDispatchableUnits(cluster, 1.0); + } + + builder.greaterThan(); + if (builder.NumberOfVariables() > 1) + { + CorrespondanceCntNativesCntOptim + .NumeroDeContrainteDesContraintesDeDureeMinDeMarche[cluster] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.NbDispUnitsMinBoundSinceMinUpTime( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + builder.build(); + } + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage + += 1 + 2 * DureeMinimaleDeMarcheDUnGroupeDuPalierThermique; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.h b/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.h new file mode 100644 index 0000000000..ec0c1afd7f --- /dev/null +++ b/src/solver/optimisation/constraints/NbDispUnitsMinBoundSinceMinUpTime.h @@ -0,0 +1,21 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'Number of Dispatchable Units Min Bound Since Min Up Time' type + */ +class NbDispUnitsMinBoundSinceMinUpTime : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.cpp b/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.cpp new file mode 100644 index 0000000000..1a7e0f3a7f --- /dev/null +++ b/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.cpp @@ -0,0 +1,41 @@ +#include "NbUnitsOutageLessThanNbUnitsStop.h" + +void NbUnitsOutageLessThanNbUnitsStop::add(int pays, + int cluster, + int clusterIndex, + int pdt, + bool Simulation) +{ + if (!Simulation) + { + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesContraintesDeDureeMinDeMarche[cluster] + = -1; + + builder.updateHourWithinWeek(pdt) + .NumberBreakingDownDispatchableUnits(cluster, 1.0) + .NumberStoppingDispatchableUnits(cluster, -1.0) + .lessThan(); + + if (builder.NumberOfVariables() > 0) + { + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.NbUnitsOutageLessThanNbUnitsStop( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + + builder.build(); + } + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage += 4; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.h b/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.h new file mode 100644 index 0000000000..fb8035324c --- /dev/null +++ b/src/solver/optimisation/constraints/NbUnitsOutageLessThanNbUnitsStop.h @@ -0,0 +1,21 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'NbUnitsOutageLessThanNbUnitsStop' type + */ +class NbUnitsOutageLessThanNbUnitsStop : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/PMaxDispatchableGeneration.cpp b/src/solver/optimisation/constraints/PMaxDispatchableGeneration.cpp new file mode 100644 index 0000000000..c41448bd45 --- /dev/null +++ b/src/solver/optimisation/constraints/PMaxDispatchableGeneration.cpp @@ -0,0 +1,38 @@ +#include "PMaxDispatchableGeneration.h" + +void PMaxDispatchableGeneration::add(int pays, + int cluster, + int clusterIndex, + int pdt, + bool Simulation) +{ + if (!Simulation) + { + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + double pmaxDUnGroupeDuPalierThermique + = PaliersThermiquesDuPays.PmaxDUnGroupeDuPalierThermique[clusterIndex]; + + builder.updateHourWithinWeek(pdt) + .DispatchableProduction(cluster, 1.0) + .NumberOfDispatchableUnits(cluster, -pmaxDUnGroupeDuPalierThermique) + .lessThan(); + if (builder.NumberOfVariables() > 0) + { + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + namer.PMaxDispatchableGeneration( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + } + builder.build(); + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage += 2; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/PMaxDispatchableGeneration.h b/src/solver/optimisation/constraints/PMaxDispatchableGeneration.h new file mode 100644 index 0000000000..58f14c8223 --- /dev/null +++ b/src/solver/optimisation/constraints/PMaxDispatchableGeneration.h @@ -0,0 +1,21 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'PMaxDispatchableGeneration' Constraint type + */ +class PMaxDispatchableGeneration : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/PMinDispatchableGeneration.cpp b/src/solver/optimisation/constraints/PMinDispatchableGeneration.cpp new file mode 100644 index 0000000000..faa7e53d80 --- /dev/null +++ b/src/solver/optimisation/constraints/PMinDispatchableGeneration.cpp @@ -0,0 +1,38 @@ +#include "PMinDispatchableGeneration.h" + +void PMinDispatchableGeneration::add(int pays, + int cluster, + int clusterIndex, + int pdt, + bool Simulation) +{ + if (!Simulation) + { + const PALIERS_THERMIQUES& PaliersThermiquesDuPays + = problemeHebdo->PaliersThermiquesDuPays[pays]; + double pminDUnGroupeDuPalierThermique + = PaliersThermiquesDuPays.pminDUnGroupeDuPalierThermique[clusterIndex]; + + builder.updateHourWithinWeek(pdt) + .DispatchableProduction(cluster, 1.0) + .NumberOfDispatchableUnits(cluster, -pminDUnGroupeDuPalierThermique) + .greaterThan(); + /*consider Adding naming constraint inside the builder*/ + if (builder.NumberOfVariables() > 0) + { + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + namer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); + namer.PMinDispatchableGeneration( + problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + PaliersThermiquesDuPays.NomsDesPaliersThermiques[clusterIndex]); + } + builder.build(); + } + else + { + nbTermesContraintesPourLesCoutsDeDemarrage += 2; + problemeHebdo->ProblemeAResoudre->NombreDeContraintes++; + } +} diff --git a/src/solver/optimisation/constraints/PMinDispatchableGeneration.h b/src/solver/optimisation/constraints/PMinDispatchableGeneration.h new file mode 100644 index 0000000000..0d9acf6373 --- /dev/null +++ b/src/solver/optimisation/constraints/PMinDispatchableGeneration.h @@ -0,0 +1,21 @@ +#pragma once +#include "ConstraintBuilder.h" + +/*! + * represent 'PMinDispatchableGeneration' Constraint type + */ +class PMinDispatchableGeneration : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + + /*! + * @brief Add variables to the constraint and update constraints Matrix + * @param pays : area + * @param cluster : global index of the cluster + * @param pdt : timestep + * @param Simulation : --- + */ + void add(int pays, int cluster, int clusterIndex, int pdt, bool Simulation); + int nbTermesContraintesPourLesCoutsDeDemarrage = 0; +}; \ No newline at end of file diff --git a/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp b/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp new file mode 100644 index 0000000000..46165a9f79 --- /dev/null +++ b/src/solver/optimisation/constraints/ShortTermStorageLevel.cpp @@ -0,0 +1,31 @@ +#include "ShortTermStorageLevel.h" + +void ShortTermStorageLevel::add(int pdt, int pays) +{ + ConstraintNamer namer(problemeHebdo->ProblemeAResoudre->NomDesContraintes); + CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim + = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; + + const int hourInTheYear = problemeHebdo->weekInTheYear * 168 + pdt; + namer.UpdateTimeStep(hourInTheYear); + namer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + + builder.updateHourWithinWeek(pdt); + for (const auto& storage : problemeHebdo->ShortTermStorage[pays]) + { + // L[h] - L[h-1] - efficiency * injection[h] + withdrawal[h] = inflows[h] + namer.ShortTermStorageLevel(problemeHebdo->ProblemeAResoudre->NombreDeContraintes, + storage.name); + const auto index = storage.clusterGlobalIndex; + CorrespondanceCntNativesCntOptim.ShortTermStorageLevelConstraint[index] + = problemeHebdo->ProblemeAResoudre->NombreDeContraintes; + + builder.ShortTermStorageLevel(index, 1.0) + .ShortTermStorageLevel( + index, -1.0, -1, problemeHebdo->NombreDePasDeTempsPourUneOptimisation) + .ShortTermStorageInjection(index, -1.0 * storage.efficiency) + .ShortTermStorageWithdrawal(index, 1.0) + .equalTo() + .build(); + } +} diff --git a/src/solver/optimisation/constraints/ShortTermStorageLevel.h b/src/solver/optimisation/constraints/ShortTermStorageLevel.h new file mode 100644 index 0000000000..c5377a97ce --- /dev/null +++ b/src/solver/optimisation/constraints/ShortTermStorageLevel.h @@ -0,0 +1,9 @@ +#pragma once +#include "ConstraintBuilder.h" + +class ShortTermStorageLevel : private ConstraintFactory +{ +public: + using ConstraintFactory::ConstraintFactory; + void add(int pdt, int pays); +}; diff --git a/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp b/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp index 42da4c6329..da4c2f573b 100644 --- a/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp +++ b/src/solver/optimisation/opt_construction_contraintes_couts_demarrage.cpp @@ -32,6 +32,12 @@ #include "opt_fonctions.h" #include "opt_rename_problem.h" +#include "constraints/PMaxDispatchableGeneration.h" +#include "constraints/PMinDispatchableGeneration.h" +#include "constraints/ConsistenceNumberOfDispatchableUnits.h" +#include "constraints/NbUnitsOutageLessThanNbUnitsStop.h" +#include "constraints/NbDispUnitsMinBoundSinceMinUpTime.h" +#include "constraints/MinDownTime.h" using namespace Antares::Data; @@ -44,8 +50,6 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( int nombreDePasDeTempsPourUneOptimisation = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; - std::vector& Pi = ProblemeAResoudre->Pi; - std::vector& Colonne = ProblemeAResoudre->Colonne; ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes); int nbTermesContraintesPourLesCoutsDeDemarrage = 0; for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) @@ -55,109 +59,20 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) { - double pminDUnGroupeDuPalierThermique - = PaliersThermiquesDuPays.pminDUnGroupeDuPalierThermique[index]; - double pmaxDUnGroupeDuPalierThermique - = PaliersThermiquesDuPays.PmaxDUnGroupeDuPalierThermique[index]; + PMaxDispatchableGeneration pMaxDispatchableGeneration(problemeHebdo); + PMinDispatchableGeneration pMinDispatchableGeneration(problemeHebdo); const int palier = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index]; for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - auto timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; + pMaxDispatchableGeneration.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += pMaxDispatchableGeneration.nbTermesContraintesPourLesCoutsDeDemarrage; - int nombreDeTermes = 0; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim.NumeroDeVariableDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -pmaxDUnGroupeDuPalierThermique; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - if (nombreDeTermes > 0) - { - constraintNamer.PMaxDispatchableGeneration( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; - - nombreDeTermes = 0; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim.NumeroDeVariableDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -pminDUnGroupeDuPalierThermique; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - if (nombreDeTermes > 0) - { - constraintNamer.PMinDispatchableGeneration( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '>'); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; + pMinDispatchableGeneration.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += pMinDispatchableGeneration.nbTermesContraintesPourLesCoutsDeDemarrage; } } } @@ -174,91 +89,12 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - auto timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - - int Pdtmoins1 = pdt - 1; - if (Pdtmoins1 < 0) - Pdtmoins1 = nombreDePasDeTempsPourUneOptimisation + Pdtmoins1; - CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptimTmoins1 - = problemeHebdo->CorrespondanceVarNativesVarOptim[Pdtmoins1]; - - int nombreDeTermes = 0; - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptimTmoins1 - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesQuiDemarrentDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesQuiSArretentDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - if (nombreDeTermes > 0) - { - constraintNamer.ConsistenceNODU( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; + ConsistenceNumberOfDispatchableUnits consistenceNumberOfDispatchableUnits( + problemeHebdo); + consistenceNumberOfDispatchableUnits.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += consistenceNumberOfDispatchableUnits + .nbTermesContraintesPourLesCoutsDeDemarrage; } } } @@ -267,6 +103,7 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( { const PALIERS_THERMIQUES& PaliersThermiquesDuPays = problemeHebdo->PaliersThermiquesDuPays[pays]; + NbUnitsOutageLessThanNbUnitsStop nbUnitsOutageLessThanNbUnitsStop(problemeHebdo); constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) @@ -276,59 +113,9 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - auto timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim - = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesDeDureeMinDeMarche[palier] - = -1; - - int nombreDeTermes = 0; - if (!Simulation) - { - int var - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariableDuNombreDeGroupesQuiTombentEnPanneDuPalierThermique - [palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariableDuNombreDeGroupesQuiSArretentDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - if (nombreDeTermes > 0) - { - constraintNamer.NbUnitsOutageLessThanNbUnitsStop( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; + nbUnitsOutageLessThanNbUnitsStop.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += nbUnitsOutageLessThanNbUnitsStop.nbTermesContraintesPourLesCoutsDeDemarrage; } } } @@ -337,99 +124,20 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( { const PALIERS_THERMIQUES& PaliersThermiquesDuPays = problemeHebdo->PaliersThermiquesDuPays[pays]; - + NbDispUnitsMinBoundSinceMinUpTime nbDispUnitsMinBoundSinceMinUpTime(problemeHebdo); constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) { - int DureeMinimaleDeMarcheDUnGroupeDuPalierThermique - = PaliersThermiquesDuPays.DureeMinimaleDeMarcheDUnGroupeDuPalierThermique[index]; - if (DureeMinimaleDeMarcheDUnGroupeDuPalierThermique <= 0) + if (PaliersThermiquesDuPays.DureeMinimaleDeMarcheDUnGroupeDuPalierThermique[index] <= 0) continue; const int palier = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index]; for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - auto timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim - = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesDeDureeMinDeMarche[palier] - = -1; - - int nombreDeTermes = 0; - if (!Simulation) - { - int var - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - for (int k = pdt - DureeMinimaleDeMarcheDUnGroupeDuPalierThermique + 1; k <= pdt; - k++) - { - int t1 = k; - if (t1 < 0) - t1 = nombreDePasDeTempsPourUneOptimisation + t1; - - if (!Simulation) - { - int var = problemeHebdo->CorrespondanceVarNativesVarOptim[t1] - .NumeroDeVariableDuNombreDeGroupesQuiDemarrentDuPalierThermique - [palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - if (!Simulation) - { - int var - = problemeHebdo->CorrespondanceVarNativesVarOptim[t1] - .NumeroDeVariableDuNombreDeGroupesQuiTombentEnPanneDuPalierThermique - [palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - } - - if (!Simulation) - { - if (nombreDeTermes > 1) - { - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesDeDureeMinDeMarche[palier] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.NbDispUnitsMinBoundSinceMinUpTime( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '>'); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; + nbDispUnitsMinBoundSinceMinUpTime.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += nbDispUnitsMinBoundSinceMinUpTime.nbTermesContraintesPourLesCoutsDeDemarrage; } } } @@ -438,84 +146,17 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaireCoutsDeDemarrage( { const PALIERS_THERMIQUES& PaliersThermiquesDuPays = problemeHebdo->PaliersThermiquesDuPays[pays]; - - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + MinDownTime minDownTime(problemeHebdo); for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) { - int DureeMinimaleDArretDUnGroupeDuPalierThermique - = PaliersThermiquesDuPays.DureeMinimaleDArretDUnGroupeDuPalierThermique[index]; const int palier = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index]; for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - auto timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim - = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesDeDureeMinDArret[palier] - = -1; - - CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - - int nombreDeTermes = 0; - if (!Simulation) - { - int var - = CorrespondanceVarNativesVarOptim - .NumeroDeVariableDuNombreDeGroupesEnMarcheDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - - for (int k = pdt - DureeMinimaleDArretDUnGroupeDuPalierThermique + 1; k <= pdt; k++) - { - int t1 = k; - if (t1 < 0) - t1 = nombreDePasDeTempsPourUneOptimisation + t1; - - const auto& CorrespondanceVarNativesVarOptim_t1 - = problemeHebdo->CorrespondanceVarNativesVarOptim[t1]; - if (!Simulation) - { - int var = CorrespondanceVarNativesVarOptim_t1 - .NumeroDeVariableDuNombreDeGroupesQuiSArretentDuPalierThermique - [palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - else - nbTermesContraintesPourLesCoutsDeDemarrage++; - } - if (!Simulation) - { - if (nombreDeTermes > 1) - { - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesDeDureeMinDArret[palier] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.MinDownTime( - ProblemeAResoudre->NombreDeContraintes, - PaliersThermiquesDuPays.NomsDesPaliersThermiques[index]); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - } - } - else - ProblemeAResoudre->NombreDeContraintes += 1; + minDownTime.add(pays, palier, index, pdt, Simulation); + nbTermesContraintesPourLesCoutsDeDemarrage + += minDownTime.nbTermesContraintesPourLesCoutsDeDemarrage; } } } diff --git a/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp b/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp index 8085974654..d9fae6948b 100644 --- a/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp +++ b/src/solver/optimisation/opt_construction_matrice_des_contraintes_cas_lineaire.cpp @@ -30,673 +30,106 @@ #include "opt_fonctions.h" #include "opt_rename_problem.h" #include "sim_structure_probleme_economique.h" +#include "constraints/AreaBalance.h" +#include "constraints/FictitiousLoad.h" +#include "constraints/ShortTermStorageLevel.h" +#include "constraints/FlowDissociation.h" +#include "constraints/BindingConstraintHour.h" +#include "constraints/BindingConstraintDay.h" +#include "constraints/BindingConstraintWeek.h" +#include "constraints/HydroPower.h" +#include "constraints/HydroPowerSmoothingUsingVariationSum.h" +#include "constraints/HydroPowerSmoothingUsingVariationMaxDown.h" +#include "constraints/HydroPowerSmoothingUsingVariationMaxUp.h" +#include "constraints/MinHydroPower.h" +#include "constraints/MaxHydroPower.h" +#include "constraints/MaxPumping.h" +#include "constraints/AreaHydroLevel.h" +#include "constraints/FinalStockEquivalent.h" +#include "constraints/FinalStockExpression.h" #include using namespace Antares::Data; -void exportPaliers(const PROBLEME_HEBDO& problemeHebdo, - const CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim, - int pays, - int& nombreDeTermes, - std::vector& Pi, - std::vector& Colonne) -{ - const PALIERS_THERMIQUES& PaliersThermiquesDuPays = problemeHebdo.PaliersThermiquesDuPays[pays]; - - for (int index = 0; index < PaliersThermiquesDuPays.NombreDePaliersThermiques; index++) - { - const int palier - = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques[index]; - int var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } -} - -static void shortTermStorageBalance( - const ::ShortTermStorage::AREA_INPUT& shortTermStorageInput, - const CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim, - int& nombreDeTermes, - std::vector& Pi, - std::vector& Colonne) -{ - for (const auto& storage : shortTermStorageInput) - { - const int clusterGlobalIndex = storage.clusterGlobalIndex; - if (const int varInjection = CorrespondanceVarNativesVarOptim.SIM_ShortTermStorage - .InjectionVariable[clusterGlobalIndex]; - varInjection >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = varInjection; - nombreDeTermes++; - } - - if (const int varWithdrawal = CorrespondanceVarNativesVarOptim.SIM_ShortTermStorage - .WithdrawalVariable[clusterGlobalIndex]; - varWithdrawal >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = varWithdrawal; - nombreDeTermes++; - } - } -} - -static void shortTermStorageLevels( - const ::ShortTermStorage::AREA_INPUT& shortTermStorageInput, - PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre, - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim, - std::vector& CorrespondanceVarNativesVarOptim, - std::vector& Pi, - std::vector& Colonne, - int nombreDePasDeTempsPourUneOptimisation, - int pdt, - ConstraintNamer& constraintNamer) -{ - const auto& VarOptimCurrent = CorrespondanceVarNativesVarOptim[pdt]; - // Cycle over the simulation period - const int timestepPrevious - = (pdt - 1 + nombreDePasDeTempsPourUneOptimisation) % nombreDePasDeTempsPourUneOptimisation; - const auto& VarOptimPrevious = CorrespondanceVarNativesVarOptim[timestepPrevious]; - for (auto& storage : shortTermStorageInput) - { - int nombreDeTermes = 0; - const int clusterGlobalIndex = storage.clusterGlobalIndex; - // L[h] - L[h-1] - efficiency * injection[h] + withdrawal[h] = inflows[h] - if (const int varLevel - = VarOptimCurrent.SIM_ShortTermStorage.LevelVariable[clusterGlobalIndex]; - varLevel >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = varLevel; - nombreDeTermes++; - } - - if (const int varLevel_previous - = VarOptimPrevious.SIM_ShortTermStorage.LevelVariable[clusterGlobalIndex]; - varLevel_previous >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = varLevel_previous; - nombreDeTermes++; - } - - if (const int varInjection - = VarOptimCurrent.SIM_ShortTermStorage.InjectionVariable[clusterGlobalIndex]; - varInjection >= 0) - { - Pi[nombreDeTermes] = -1.0 * storage.efficiency; - Colonne[nombreDeTermes] = varInjection; - nombreDeTermes++; - } - - if (const int varWithdrawal - = VarOptimCurrent.SIM_ShortTermStorage.WithdrawalVariable[clusterGlobalIndex]; - varWithdrawal >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = varWithdrawal; - nombreDeTermes++; - } - CorrespondanceCntNativesCntOptim.ShortTermStorageLevelConstraint[clusterGlobalIndex] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.ShortTermStorageLevel(ProblemeAResoudre->NombreDeContraintes, storage.name); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } -} - void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaire(PROBLEME_HEBDO* problemeHebdo, Solver::IResultWriter& writer) { - int var; - - const bool exportStructure = problemeHebdo->ExportStructure; - const bool firstWeekOfSimulation = problemeHebdo->firstWeekOfSimulation; - PROBLEME_ANTARES_A_RESOUDRE* ProblemeAResoudre = problemeHebdo->ProblemeAResoudre.get(); int nombreDePasDeTempsDUneJournee = problemeHebdo->NombreDePasDeTempsDUneJournee; int nombreDePasDeTempsPourUneOptimisation = problemeHebdo->NombreDePasDeTempsPourUneOptimisation; - std::vector& Pi = ProblemeAResoudre->Pi; - std::vector& Colonne = ProblemeAResoudre->Colonne; - ProblemeAResoudre->NombreDeContraintes = 0; ProblemeAResoudre->NombreDeTermesDansLaMatriceDesContraintes = 0; ConstraintNamer constraintNamer(ProblemeAResoudre->NomDesContraintes); + AreaBalance areaBalance(problemeHebdo); + FictitiousLoad fictitiousLoad(problemeHebdo); + ShortTermStorageLevel shortTermStorageLevel(problemeHebdo); + FlowDissociation flowDissociation(problemeHebdo); + BindingConstraintHour bindingConstraintHour(problemeHebdo); + BindingConstraintDay bindingConstraintDay(problemeHebdo); + BindingConstraintWeek bindingConstraintWeek(problemeHebdo); + HydroPower hydroPower(problemeHebdo); + HydroPowerSmoothingUsingVariationSum hydroPowerSmoothingUsingVariationSum(problemeHebdo); + HydroPowerSmoothingUsingVariationMaxDown hydroPowerSmoothingUsingVariationMaxDown( + problemeHebdo); + HydroPowerSmoothingUsingVariationMaxUp hydroPowerSmoothingUsingVariationMaxUp(problemeHebdo); + + MinHydroPower minHydroPower(problemeHebdo); + MaxHydroPower maxHydroPower(problemeHebdo); + + MaxPumping maxPumping(problemeHebdo); + + AreaHydroLevel areaHydroLevel(problemeHebdo); + + FinalStockEquivalent finalStockEquivalent(problemeHebdo); + FinalStockExpression finalStockExpression(problemeHebdo); + for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { int timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; constraintNamer.UpdateTimeStep(timeStepInYear); - CORRESPONDANCES_DES_VARIABLES& CorrespondanceVarNativesVarOptim = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim - = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - int nombreDeTermes = 0; + areaBalance.add(pdt, pays); - int interco = problemeHebdo->IndexDebutIntercoOrigine[pays]; - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); + fictitiousLoad.add(pdt, pays); - while (interco >= 0) - { - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - interco = problemeHebdo->IndexSuivantIntercoOrigine[interco]; - } - interco = problemeHebdo->IndexDebutIntercoExtremite[pays]; - while (interco >= 0) - { - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - interco = problemeHebdo->IndexSuivantIntercoExtremite[interco]; - } - - exportPaliers( - *problemeHebdo, CorrespondanceVarNativesVarOptim, pays, nombreDeTermes, Pi, Colonne); - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDePompage[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDefaillancePositive[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDefaillanceNegative[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - shortTermStorageBalance(problemeHebdo->ShortTermStorage[pays], - CorrespondanceVarNativesVarOptim, - nombreDeTermes, - Pi, - Colonne); - - CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesBilansPays[pays] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.AreaBalance(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - nombreDeTermes = 0; - - exportPaliers( - *problemeHebdo, CorrespondanceVarNativesVarOptim, pays, nombreDeTermes, Pi, Colonne); - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = -problemeHebdo->DefaillanceNegativeUtiliserHydro[pays]; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDefaillanceNegative[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - CorrespondanceCntNativesCntOptim.NumeroDeContraintePourEviterLesChargesFictives[pays] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.FictiveLoads(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - // Short term storage - shortTermStorageLevels(problemeHebdo->ShortTermStorage[pays], - ProblemeAResoudre, - CorrespondanceCntNativesCntOptim, - problemeHebdo->CorrespondanceVarNativesVarOptim, - Pi, - Colonne, - nombreDePasDeTempsPourUneOptimisation, - pdt, - constraintNamer); + shortTermStorageLevel.add(pdt, pays); } for (uint32_t interco = 0; interco < problemeHebdo->NombreDInterconnexions; interco++) { - if (problemeHebdo->CoutDeTransport[interco].IntercoGereeAvecDesCouts) - { - int nombreDeTermes = 0; - var = CorrespondanceVarNativesVarOptim.NumeroDeVariableDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var = CorrespondanceVarNativesVarOptim - .NumeroDeVariableCoutOrigineVersExtremiteDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var = CorrespondanceVarNativesVarOptim - .NumeroDeVariableCoutExtremiteVersOrigineDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - CorrespondanceCntNativesCntOptim.NumeroDeContrainteDeDissociationDeFlux[interco] - = ProblemeAResoudre->NombreDeContraintes; - const auto origin - = problemeHebdo - ->NomsDesPays[problemeHebdo->PaysOrigineDeLInterconnexion[interco]]; - const auto destination - = problemeHebdo - ->NomsDesPays[problemeHebdo->PaysExtremiteDeLInterconnexion[interco]]; - constraintNamer.FlowDissociation( - ProblemeAResoudre->NombreDeContraintes, origin, destination); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } + flowDissociation.add(pdt, interco); } - for (uint32_t cntCouplante = 0; cntCouplante < problemeHebdo->NombreDeContraintesCouplantes; cntCouplante++) { - const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes - = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; - - if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante != CONTRAINTE_HORAIRE) - continue; - - int nbInterco - = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; - int nombreDeTermes = 0; - for (int index = 0; index < nbInterco; index++) - { - int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; - double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; - int Offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; - int pdt1; - - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDeLInterconnexion[interco]; - - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - - int nbClusters - = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; - for (int index = 0; index < nbClusters; index++) - { - int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; - const PALIERS_THERMIQUES& PaliersThermiquesDuPays - = problemeHebdo->PaliersThermiquesDuPays[pays]; - const int palier - = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques - [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; - double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; - int Offset - = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; - int pdt1; - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDuPalierThermique[palier]; - - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - CorrespondanceCntNativesCntOptim - .NumeroDeContrainteDesContraintesCouplantes[cntCouplante] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.BindingConstraintHour( - ProblemeAResoudre->NombreDeContraintes, - MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, - Pi, - Colonne, - nombreDeTermes, - MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante); + bindingConstraintHour.add(pdt, cntCouplante); } } for (uint32_t cntCouplante = 0; cntCouplante < problemeHebdo->NombreDeContraintesCouplantes; cntCouplante++) { - const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes - = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; - if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante != CONTRAINTE_JOURNALIERE) - continue; - - int nbInterco - = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; - int nbClusters - = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; - int pdtDebut = 0; - while (pdtDebut < nombreDePasDeTempsPourUneOptimisation) - { - int jour = problemeHebdo->NumeroDeJourDuPasDeTemps[pdtDebut]; - CORRESPONDANCES_DES_CONTRAINTES_JOURNALIERES& - CorrespondanceCntNativesCntOptimJournalieres - = problemeHebdo->CorrespondanceCntNativesCntOptimJournalieres[jour]; - int nombreDeTermes = 0; - - for (int index = 0; index < nbInterco; index++) - { - int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; - double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; - int Offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; - - for (int pdt = pdtDebut; pdt < pdtDebut + nombreDePasDeTempsDUneJournee; pdt++) - { - int pdt1; - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - - for (int index = 0; index < nbClusters; index++) - { - int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; - const PALIERS_THERMIQUES& PaliersThermiquesDuPays - = problemeHebdo->PaliersThermiquesDuPays[pays]; - const int palier - = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques - [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; - double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; - int Offset - = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; - - for (int pdt = pdtDebut; pdt < pdtDebut + nombreDePasDeTempsDUneJournee; pdt++) - { - int pdt1; - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - - CorrespondanceCntNativesCntOptimJournalieres - .NumeroDeContrainteDesContraintesCouplantes[cntCouplante] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.UpdateTimeStep(jour); - constraintNamer.BindingConstraintDay( - ProblemeAResoudre->NombreDeContraintes, - MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, - Pi, - Colonne, - nombreDeTermes, - MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante); - pdtDebut += nombreDePasDeTempsDUneJournee; - } + bindingConstraintDay.add(cntCouplante); } if (nombreDePasDeTempsPourUneOptimisation > nombreDePasDeTempsDUneJournee) { - int semaine = problemeHebdo->weekInTheYear; - CORRESPONDANCES_DES_CONTRAINTES_HEBDOMADAIRES& CorrespondanceCntNativesCntOptimHebdomadaires - = problemeHebdo->CorrespondanceCntNativesCntOptimHebdomadaires; for (uint32_t cntCouplante = 0; cntCouplante < problemeHebdo->NombreDeContraintesCouplantes; cntCouplante++) { - const CONTRAINTES_COUPLANTES& MatriceDesContraintesCouplantes - = problemeHebdo->MatriceDesContraintesCouplantes[cntCouplante]; - if (MatriceDesContraintesCouplantes.TypeDeContrainteCouplante - != CONTRAINTE_HEBDOMADAIRE) - continue; - - int nbInterco - = MatriceDesContraintesCouplantes.NombreDInterconnexionsDansLaContrainteCouplante; - int nombreDeTermes = 0; - for (int index = 0; index < nbInterco; index++) - { - int interco = MatriceDesContraintesCouplantes.NumeroDeLInterconnexion[index]; - double poids = MatriceDesContraintesCouplantes.PoidsDeLInterconnexion[index]; - int Offset = MatriceDesContraintesCouplantes.OffsetTemporelSurLInterco[index]; - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - int pdt1; - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDeLInterconnexion[interco]; - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - - int nbClusters - = MatriceDesContraintesCouplantes.NombreDePaliersDispatchDansLaContrainteCouplante; - for (int index = 0; index < nbClusters; index++) - { - int pays = MatriceDesContraintesCouplantes.PaysDuPalierDispatch[index]; - const PALIERS_THERMIQUES& PaliersThermiquesDuPays - = problemeHebdo->PaliersThermiquesDuPays[pays]; - const int palier - = PaliersThermiquesDuPays.NumeroDuPalierDansLEnsembleDesPaliersThermiques - [MatriceDesContraintesCouplantes.NumeroDuPalierDispatch[index]]; - double poids = MatriceDesContraintesCouplantes.PoidsDuPalierDispatch[index]; - int Offset - = MatriceDesContraintesCouplantes.OffsetTemporelSurLePalierDispatch[index]; - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - int pdt1; - if (Offset >= 0) - { - pdt1 = (pdt + Offset) % nombreDePasDeTempsPourUneOptimisation; - } - else - { - pdt1 = (pdt + Offset + problemeHebdo->NombreDePasDeTemps) - % nombreDePasDeTempsPourUneOptimisation; - } - - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariableDuPalierThermique[palier]; - if (var >= 0) - { - Pi[nombreDeTermes] = poids; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - - CorrespondanceCntNativesCntOptimHebdomadaires - .NumeroDeContrainteDesContraintesCouplantes[cntCouplante] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.UpdateTimeStep(semaine); - constraintNamer.BindingConstraintWeek( - ProblemeAResoudre->NombreDeContraintes, - MatriceDesContraintesCouplantes.NomDeLaContrainteCouplante); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, - Pi, - Colonne, - nombreDeTermes, - MatriceDesContraintesCouplantes.SensDeLaContrainteCouplante); + bindingConstraintWeek.add(cntCouplante); } } for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - bool presenceHydro - = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable; - bool TurbEntreBornes - = problemeHebdo->CaracteristiquesHydrauliques[pays].TurbinageEntreBornes; - bool presencePompage - = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable; - - int nombreDeTermes = 0; - if (presenceHydro && !TurbEntreBornes) - { - if (presencePompage) - { - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDeLaProdHyd[pays]; - - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDePompage[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] - = problemeHebdo->CaracteristiquesHydrauliques[pays].PumpingRatio; - Pi[nombreDeTermes] *= -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - else - { - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - } - - problemeHebdo->NumeroDeContrainteEnergieHydraulique[pays] - = ProblemeAResoudre->NombreDeContraintes; - constraintNamer.UpdateTimeStep(problemeHebdo->weekInTheYear); - constraintNamer.HydroPower(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } - else - problemeHebdo->NumeroDeContrainteEnergieHydraulique[pays] = -1; + hydroPower.add(pays); } if (problemeHebdo->TypeDeLissageHydraulique == LISSAGE_HYDRAULIQUE_SUR_SOMME_DES_VARIATIONS) @@ -706,57 +139,7 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaire(PROBLEME_HEBDO* pro if (!problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable) continue; - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - int timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - const auto& CorrespondanceVarNativesVarOptim - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - int nombreDeTermes = 0; - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - int pdt1 = pdt + 1; - if (pdt1 >= nombreDePasDeTempsPourUneOptimisation) - pdt1 = 0; - - if (int var1 = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt1] - .NumeroDeVariablesDeLaProdHyd[pays]; - var1 >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var1; - nombreDeTermes++; - } - - if (int var2 = CorrespondanceVarNativesVarOptim - .NumeroDeVariablesVariationHydALaBaisse[pays]; - var2 >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var2; - nombreDeTermes++; - } - - if (int var3 = CorrespondanceVarNativesVarOptim - .NumeroDeVariablesVariationHydALaHausse[pays]; - var3 >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var3; - nombreDeTermes++; - } - - constraintNamer.HydroPowerSmoothingUsingVariationSum( - ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } + hydroPowerSmoothingUsingVariationSum.add(pays); } } else if (problemeHebdo->TypeDeLissageHydraulique == LISSAGE_HYDRAULIQUE_SUR_VARIATION_MAX) @@ -769,287 +152,40 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaire(PROBLEME_HEBDO* pro constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - int timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; - constraintNamer.UpdateTimeStep(timeStepInYear); - const auto& CorrespondanceVarNativesVarOptim - = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - int nombreDeTermes = 0; - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - int var1 = problemeHebdo->CorrespondanceVarNativesVarOptim[0] - .NumeroDeVariablesVariationHydALaBaisse[pays]; - if (var1 >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var1; - nombreDeTermes++; - } - - constraintNamer.HydroPowerSmoothingUsingVariationMaxDown( - ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - - nombreDeTermes = 0; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var1 = problemeHebdo->CorrespondanceVarNativesVarOptim[0] - .NumeroDeVariablesVariationHydALaHausse[pays]; - if (var1 >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var1; - nombreDeTermes++; - } - - constraintNamer.HydroPowerSmoothingUsingVariationMaxUp( - ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '>'); + hydroPowerSmoothingUsingVariationMaxDown.add(pays, pdt); + hydroPowerSmoothingUsingVariationMaxUp.add(pays, pdt); } } } for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - const bool presenceHydro - = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDHydrauliqueModulable; - const bool presencePompage - = problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable; - const bool TurbEntreBornes - = problemeHebdo->CaracteristiquesHydrauliques[pays].TurbinageEntreBornes; - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - if (presenceHydro && (TurbEntreBornes || presencePompage)) - { - int nombreDeTermes = 0; - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - - problemeHebdo->NumeroDeContrainteMinEnergieHydraulique[pays] - = ProblemeAResoudre->NombreDeContraintes; - constraintNamer.UpdateTimeStep(problemeHebdo->weekInTheYear); - constraintNamer.MinHydroPower(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '>'); - } - else - problemeHebdo->NumeroDeContrainteMinEnergieHydraulique[pays] = -1; - - if (presenceHydro - && (TurbEntreBornes - || problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable)) - { - int nombreDeTermes = 0; - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - constraintNamer.UpdateTimeStep(problemeHebdo->weekInTheYear * 168 + pdt); - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } + minHydroPower.add(pays); - problemeHebdo->NumeroDeContrainteMaxEnergieHydraulique[pays] - = ProblemeAResoudre->NombreDeContraintes; - constraintNamer.UpdateTimeStep(problemeHebdo->weekInTheYear); - constraintNamer.MaxHydroPower(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - } - else - problemeHebdo->NumeroDeContrainteMaxEnergieHydraulique[pays] = -1; + maxHydroPower.add(pays); } for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - if (problemeHebdo->CaracteristiquesHydrauliques[pays].PresenceDePompageModulable) - { - int nombreDeTermes = 0; - for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) - { - var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt] - .NumeroDeVariablesDePompage[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - - problemeHebdo->NumeroDeContrainteMaxPompage[pays] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.UpdateTimeStep(problemeHebdo->weekInTheYear); - constraintNamer.MaxPumping(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '<'); - } - else - problemeHebdo->NumeroDeContrainteMaxPompage[pays] = -1; + maxPumping.add(pays); } for (int pdt = 0; pdt < nombreDePasDeTempsPourUneOptimisation; pdt++) { - const auto& CorrespondanceVarNativesVarOptim = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt]; - CORRESPONDANCES_DES_CONTRAINTES& CorrespondanceCntNativesCntOptim - = problemeHebdo->CorrespondanceCntNativesCntOptim[pdt]; - int timeStepInYear = problemeHebdo->weekInTheYear * 168 + pdt; constraintNamer.UpdateTimeStep(timeStepInYear); for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - if (problemeHebdo->CaracteristiquesHydrauliques[pays].SuiviNiveauHoraire) - { - int nombreDeTermes = 0; - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeNiveau[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - if (pdt > 0) - { - int var1 = problemeHebdo->CorrespondanceVarNativesVarOptim[pdt - 1] - .NumeroDeVariablesDeNiveau[pays]; - if (var1 >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var1; - nombreDeTermes++; - } - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeLaProdHyd[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDePompage[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] - = problemeHebdo->CaracteristiquesHydrauliques[pays].PumpingRatio; - Pi[nombreDeTermes] *= -1; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - var = CorrespondanceVarNativesVarOptim.NumeroDeVariablesDeDebordement[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - - CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesNiveauxPays[pays] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.AreaHydroLevel(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } - else - CorrespondanceCntNativesCntOptim.NumeroDeContrainteDesNiveauxPays[pays] = -1; + areaHydroLevel.add(pays, pdt); } } /* For each area with ad hoc properties, two possible sets of two additional constraints */ for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++) { - const auto& week = problemeHebdo->weekInTheYear; - constraintNamer.UpdateArea(problemeHebdo->NomsDesPays[pays]); - constraintNamer.UpdateTimeStep(week * 168 + nombreDePasDeTempsPourUneOptimisation - 1); - - if (problemeHebdo->CaracteristiquesHydrauliques[pays].AccurateWaterValue - && problemeHebdo->CaracteristiquesHydrauliques[pays].DirectLevelAccess) - /* equivalence constraint : StockFinal- Niveau[T]= 0*/ - { - int nombreDeTermes = 0; - var = problemeHebdo->NumeroDeVariableStockFinal[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - var = problemeHebdo - ->CorrespondanceVarNativesVarOptim[nombreDePasDeTempsPourUneOptimisation - 1] - .NumeroDeVariablesDeNiveau[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - problemeHebdo->NumeroDeContrainteEquivalenceStockFinal[pays] - = ProblemeAResoudre->NombreDeContraintes; + finalStockEquivalent.add(pays); - constraintNamer.FinalStockEquivalent(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } - if (problemeHebdo->CaracteristiquesHydrauliques[pays].AccurateWaterValue) - /* expression constraint : - StockFinal +sum (stocklayers) = 0*/ - { - int nombreDeTermes = 0; - var = problemeHebdo->NumeroDeVariableStockFinal[pays]; - if (var >= 0) - { - Pi[nombreDeTermes] = -1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - for (int layerindex = 0; layerindex < 100; layerindex++) - { - var = problemeHebdo->NumeroDeVariableDeTrancheDeStock[pays][layerindex]; - - if (var >= 0) - { - Pi[nombreDeTermes] = 1.0; - Colonne[nombreDeTermes] = var; - nombreDeTermes++; - } - } - - problemeHebdo->NumeroDeContrainteExpressionStockFinal[pays] - = ProblemeAResoudre->NombreDeContraintes; - - constraintNamer.FinalStockExpression(ProblemeAResoudre->NombreDeContraintes); - OPT_ChargerLaContrainteDansLaMatriceDesContraintes( - ProblemeAResoudre, Pi, Colonne, nombreDeTermes, '='); - } + finalStockExpression.add(pays); } if (problemeHebdo->OptimisationAvecCoutsDeDemarrage) @@ -1059,7 +195,7 @@ void OPT_ConstruireLaMatriceDesContraintesDuProblemeLineaire(PROBLEME_HEBDO* pro } // Export structure - if (exportStructure && firstWeekOfSimulation) + if (problemeHebdo->ExportStructure && problemeHebdo->firstWeekOfSimulation) { OPT_ExportInterco(writer, problemeHebdo); OPT_ExportAreaName(writer, problemeHebdo->NomsDesPays); diff --git a/src/solver/optimisation/opt_rename_problem.h b/src/solver/optimisation/opt_rename_problem.h index bd392a1ba5..d8c6b9a605 100644 --- a/src/solver/optimisation/opt_rename_problem.h +++ b/src/solver/optimisation/opt_rename_problem.h @@ -8,8 +8,7 @@ const std::string AREA_SEP = "$$"; class TargetVectorUpdater { public: - TargetVectorUpdater(std::vector& target) : - target_(target) + explicit TargetVectorUpdater(std::vector& target) : target_(target) { } @@ -25,9 +24,11 @@ class TargetVectorUpdater class Namer { public: - Namer(std::vector& target) : - targetUpdater_(target) + explicit Namer(std::vector& target) : targetUpdater_(target) { +#ifdef __linux__ + std::cout << "Namer::Namer :" << __PRETTY_FUNCTION__ << "\n"; +#endif } void UpdateTimeStep(unsigned int timeStep)