diff --git a/src/solver/optimisation/CMakeLists.txt b/src/solver/optimisation/CMakeLists.txt
index 0d64d42e44..bd6e6c4d64 100644
--- a/src/solver/optimisation/CMakeLists.txt
+++ b/src/solver/optimisation/CMakeLists.txt
@@ -75,6 +75,8 @@ set(RTESOLVER_OPT
include/antares/solver/optimisation/constraints/constraint_builder_utils.h
include/antares/solver/optimisation/constraints/AreaBalance.h
constraints/AreaBalance.cpp
+ include/antares/solver/optimisation/constraints/NetPosition.h
+ constraints/NetPosition.cpp
include/antares/solver/optimisation/constraints/FictitiousLoad.h
constraints/FictitiousLoad.cpp
include/antares/solver/optimisation/constraints/ShortTermStorageLevel.h
diff --git a/src/solver/optimisation/constraints/AreaBalance.cpp b/src/solver/optimisation/constraints/AreaBalance.cpp
index c0c254854d..b35139d584 100644
--- a/src/solver/optimisation/constraints/AreaBalance.cpp
+++ b/src/solver/optimisation/constraints/AreaBalance.cpp
@@ -44,22 +44,9 @@ void AreaBalance::add(int pdt, int pays)
builder.updateHourWithinWeek(pdt);
- int interco = data.IndexDebutIntercoOrigine[pays];
- while (interco >= 0)
- {
- builder.NTCDirect(interco, 1.0);
- interco = data.IndexSuivantIntercoOrigine[interco];
- }
-
- interco = data.IndexDebutIntercoExtremite[pays];
- while (interco >= 0)
- {
- builder.NTCDirect(interco, -1.0);
- interco = data.IndexSuivantIntercoExtremite[interco];
- }
-
ExportPaliers(data.PaliersThermiquesDuPays[pays], builder);
- builder.HydProd(pays, -1.0)
+ builder.NetPosition(pays, 1)
+ .HydProd(pays, -1.0)
.Pumping(pays, 1.0)
.PositiveUnsuppliedEnergy(pays, -1.0)
.NegativeUnsuppliedEnergy(pays, 1.0);
diff --git a/src/solver/optimisation/constraints/ConstraintBuilder.cpp b/src/solver/optimisation/constraints/ConstraintBuilder.cpp
index 6d7662a605..217a386749 100644
--- a/src/solver/optimisation/constraints/ConstraintBuilder.cpp
+++ b/src/solver/optimisation/constraints/ConstraintBuilder.cpp
@@ -49,6 +49,12 @@ ConstraintBuilder& ConstraintBuilder::DispatchableProduction(unsigned int index,
return *this;
}
+ConstraintBuilder& ConstraintBuilder::NetPosition(unsigned int index, double coeff)
+{
+ AddVariable(variableManager_.NetPosition(index, hourInWeek_), coeff);
+ return *this;
+}
+
ConstraintBuilder& ConstraintBuilder::NumberOfDispatchableUnits(unsigned int index, double coeff)
{
AddVariable(variableManager_.NumberOfDispatchableUnits(index, hourInWeek_), coeff);
diff --git a/src/solver/optimisation/constraints/Group1.cpp b/src/solver/optimisation/constraints/Group1.cpp
index 61de7cf2b3..bb5b5c199f 100644
--- a/src/solver/optimisation/constraints/Group1.cpp
+++ b/src/solver/optimisation/constraints/Group1.cpp
@@ -35,6 +35,15 @@ AreaBalanceData Group1::GetAreaBalanceData()
.ShortTermStorage = problemeHebdo_->ShortTermStorage};
}
+NetPositionData Group1::GetNetPositionData()
+{
+ return {.CorrespondanceCntNativesCntOptim = problemeHebdo_->CorrespondanceCntNativesCntOptim,
+ .IndexDebutIntercoOrigine = problemeHebdo_->IndexDebutIntercoOrigine,
+ .IndexSuivantIntercoOrigine = problemeHebdo_->IndexSuivantIntercoOrigine,
+ .IndexDebutIntercoExtremite = problemeHebdo_->IndexDebutIntercoExtremite,
+ .IndexSuivantIntercoExtremite = problemeHebdo_->IndexSuivantIntercoExtremite};
+}
+
FictitiousLoadData Group1::GetFictitiousLoadData()
{
return {.CorrespondanceCntNativesCntOptim = problemeHebdo_->CorrespondanceCntNativesCntOptim,
@@ -79,6 +88,9 @@ void Group1::BuildConstraints()
auto areaBalanceData = GetAreaBalanceData();
AreaBalance areaBalance(builder_, areaBalanceData);
+ auto netPositionData = GetNetPositionData();
+ NetPosition netPosition(builder_, netPositionData);
+
auto fictitiousLoadData = GetFictitiousLoadData();
FictitiousLoad fictitiousLoad(builder_, fictitiousLoadData);
@@ -116,6 +128,7 @@ void Group1::BuildConstraints()
for (uint32_t pays = 0; pays < problemeHebdo_->NombreDePays; pays++)
{
areaBalance.add(pdt, pays);
+ netPosition.add(pdt, pays);
fictitiousLoad.add(pdt, pays);
shortTermStorageLevel.add(pdt, pays);
shortTermStorageCostVariationInjectionBackward.add(pdt, pays);
diff --git a/src/solver/optimisation/constraints/NetPosition.cpp b/src/solver/optimisation/constraints/NetPosition.cpp
new file mode 100644
index 0000000000..3f5edbed75
--- /dev/null
+++ b/src/solver/optimisation/constraints/NetPosition.cpp
@@ -0,0 +1,47 @@
+/*
+** Copyright 2007-2024, RTE (https://www.rte-france.com)
+** See AUTHORS.txt
+** SPDX-License-Identifier: MPL-2.0
+** This file is part of Antares-Simulator,
+** Adequacy and Performance assessment for interconnected energy networks.
+**
+** Antares_Simulator is free software: you can redistribute it and/or modify
+** it under the terms of the Mozilla Public Licence 2.0 as published by
+** the Mozilla Foundation, either version 2 of the License, or
+** (at your option) any later version.
+**
+** Antares_Simulator is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** Mozilla Public Licence 2.0 for more details.
+**
+** You should have received a copy of the Mozilla Public Licence 2.0
+** along with Antares_Simulator. If not, see .
+*/
+
+#include "antares/solver/optimisation/constraints/NetPosition.h"
+
+void NetPosition::add(int pdt, int pays)
+{
+ int interco = data.IndexDebutIntercoOrigine[pays];
+ while (interco >= 0)
+ {
+ builder.NTCDirect(interco, 1.0);
+ interco = data.IndexSuivantIntercoOrigine[interco];
+ }
+
+ interco = data.IndexDebutIntercoExtremite[pays];
+ while (interco >= 0)
+ {
+ builder.NTCDirect(interco, -1.0);
+ interco = data.IndexSuivantIntercoExtremite[interco];
+ }
+
+ ConstraintNamer namer(builder.data.NomDesContraintes);
+ namer.UpdateTimeStep(builder.data.weekInTheYear * 168 + pdt);
+ namer.UpdateArea(builder.data.NomsDesPays[pays]);
+ namer.NetPosition(builder.data.nombreDeContraintes);
+
+ builder.NetPosition(pays, -1.0);
+ builder.equalTo().build();
+}
diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h
index 31019332d3..f7f1906373 100644
--- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h
+++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/ConstraintBuilder.h
@@ -137,6 +137,8 @@ class ConstraintBuilder
int offset = 0,
int delta = 0);
+ ConstraintBuilder& NetPosition(unsigned int index, double coeff);
+
ConstraintBuilder& HydProd(unsigned int index, double coeff);
ConstraintBuilder& HydProdDown(unsigned int index, double coeff);
diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h
index c74567716e..9f866892b0 100644
--- a/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h
+++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/Group1.h
@@ -25,6 +25,7 @@
#include "ConstraintGroup.h"
#include "FictitiousLoad.h"
#include "FlowDissociation.h"
+#include "NetPosition.h"
#include "ShortTermStorageLevel.h"
class Group1: public ConstraintGroup
@@ -36,6 +37,7 @@ class Group1: public ConstraintGroup
private:
AreaBalanceData GetAreaBalanceData();
+ NetPositionData GetNetPositionData();
FictitiousLoadData GetFictitiousLoadData();
ShortTermStorageData GetShortTermStorageData();
diff --git a/src/solver/optimisation/include/antares/solver/optimisation/constraints/NetPosition.h b/src/solver/optimisation/include/antares/solver/optimisation/constraints/NetPosition.h
new file mode 100644
index 0000000000..139728cee2
--- /dev/null
+++ b/src/solver/optimisation/include/antares/solver/optimisation/constraints/NetPosition.h
@@ -0,0 +1,56 @@
+/*
+** Copyright 2007-2024, RTE (https://www.rte-france.com)
+** See AUTHORS.txt
+** SPDX-License-Identifier: MPL-2.0
+** This file is part of Antares-Simulator,
+** Adequacy and Performance assessment for interconnected energy networks.
+**
+** Antares_Simulator is free software: you can redistribute it and/or modify
+** it under the terms of the Mozilla Public Licence 2.0 as published by
+** the Mozilla Foundation, either version 2 of the License, or
+** (at your option) any later version.
+**
+** Antares_Simulator is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** Mozilla Public Licence 2.0 for more details.
+**
+** You should have received a copy of the Mozilla Public Licence 2.0
+** along with Antares_Simulator. If not, see .
+*/
+#pragma once
+#include "ConstraintBuilder.h"
+
+struct NetPositionData
+{
+ std::vector& CorrespondanceCntNativesCntOptim;
+ const std::vector& IndexDebutIntercoOrigine;
+ const std::vector& IndexSuivantIntercoOrigine;
+ const std::vector& IndexDebutIntercoExtremite;
+ const std::vector& IndexSuivantIntercoExtremite;
+};
+
+/*!
+ * represent 'Net Position' constraint type
+ */
+
+class NetPosition: public ConstraintFactory
+{
+public:
+ NetPosition(ConstraintBuilder& builder, NetPositionData& data):
+ ConstraintFactory(builder),
+ data(data)
+ {
+ }
+
+ /*!
+ * @brief Add variables to the constraint and update constraints Matrix
+ * @param pdt : timestep
+ * @param pays : area
+ */
+
+ void add(int pdt, int pays);
+
+private:
+ NetPositionData& data;
+};
diff --git a/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h b/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h
index c7c3dff284..ab526cbf04 100644
--- a/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h
+++ b/src/solver/optimisation/include/antares/solver/optimisation/opt_rename_problem.h
@@ -114,6 +114,7 @@ class VariableNamer: public Namer
void PositiveUnsuppliedEnergy(unsigned int variable);
void NegativeUnsuppliedEnergy(unsigned int variable);
void AreaBalance(unsigned int variable);
+ void NetPosition(unsigned int variable);
private:
void SetAreaVariableName(unsigned int variable,
@@ -133,6 +134,7 @@ class ConstraintNamer: public Namer
const std::string& origin,
const std::string& destination);
+ void NetPosition(unsigned int variable);
void AreaBalance(unsigned int constraint);
void FictiveLoads(unsigned int constraint);
void HydroPower(unsigned int constraint);
diff --git a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp
index d2e68570e9..ace9a312fe 100644
--- a/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp
+++ b/src/solver/optimisation/opt_construction_variables_optimisees_lineaire.cpp
@@ -86,6 +86,12 @@ void OPT_ConstruireLaListeDesVariablesOptimiseesDuProblemeLineaire(PROBLEME_HEBD
NombreDeVariables++;
}
+ // NetPosition
+ ProblemeAResoudre->TypeDeVariable[NombreDeVariables] = VARIABLE_NON_BORNEE;
+ variableManager.NetPosition(pays, pdt) = NombreDeVariables;
+ variableNamer.NetPosition(NombreDeVariables);
+ NombreDeVariables++;
+
for (const auto& storage: problemeHebdo->ShortTermStorage[pays])
{
const int clusterGlobalIndex = storage.clusterGlobalIndex;
diff --git a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp
index 79c29c58ab..720e8bcb83 100644
--- a/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp
+++ b/src/solver/optimisation/opt_decompte_variables_et_contraintes.cpp
@@ -281,6 +281,13 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO*
}
}
+ // NetPosition
+ for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++)
+ {
+ ProblemeAResoudre->NombreDeVariables += nombreDePasDeTempsPourUneOptimisation;
+ ProblemeAResoudre->NombreDeContraintes += nombreDePasDeTempsPourUneOptimisation;
+ }
+
if (problemeHebdo->OptimisationAvecCoutsDeDemarrage)
{
OPT_DecompteDesVariablesEtDesContraintesCoutsDeDemarrage(problemeHebdo);
diff --git a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp
index 5c507fbed7..5e6b7673f7 100644
--- a/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp
+++ b/src/solver/optimisation/opt_gestion_des_bornes_cas_lineaire.cpp
@@ -470,6 +470,14 @@ void OPT_InitialiserLesBornesDesVariablesDuProblemeLineaire(PROBLEME_HEBDO* prob
AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = adresseDuResultat;
}
}
+ for (uint32_t pays = 0; pays < problemeHebdo->NombreDePays; pays++)
+ {
+ int var = problemeHebdo->CorrespondanceVarNativesVarOptim[pdtHebdo]
+ .NumeroDeVariableNetPosition[pays];
+ double* adresseDuResultat = &(
+ problemeHebdo->ResultatsHoraires[pays].NetPositionHoraire[pdtHebdo]);
+ AdresseOuPlacerLaValeurDesVariablesOptimisees[var] = adresseDuResultat;
+ }
}
setBoundsForUnsuppliedEnergy(problemeHebdo,
diff --git a/src/solver/optimisation/opt_rename_problem.cpp b/src/solver/optimisation/opt_rename_problem.cpp
index b385c0f8f5..622e8fbb09 100644
--- a/src/solver/optimisation/opt_rename_problem.cpp
+++ b/src/solver/optimisation/opt_rename_problem.cpp
@@ -192,6 +192,11 @@ void VariableNamer::ShortTermStorageCostVariationWithdrawal(unsigned int variabl
SetShortTermStorageVariableName(variable, "CostVariationWithdrawal", shortTermStorageName);
}
+void VariableNamer::NetPosition(unsigned int constraint)
+{
+ SetAreaElementNameHour(constraint, "NetPositionVariable");
+}
+
void VariableNamer::HydProd(unsigned int variable)
{
SetAreaElementNameHour(variable, "HydProd");
@@ -275,6 +280,11 @@ void ConstraintNamer::AreaBalance(unsigned int constraint)
SetAreaElementNameHour(constraint, "AreaBalance");
}
+void ConstraintNamer::NetPosition(unsigned int constraint)
+{
+ SetAreaElementNameHour(constraint, "NetPositionConstraint");
+}
+
void ConstraintNamer::FictiveLoads(unsigned int constraint)
{
SetAreaElementNameHour(constraint, "FictiveLoads");
diff --git a/src/solver/optimisation/variables/VariableManagement.cpp b/src/solver/optimisation/variables/VariableManagement.cpp
index 37d50b5f97..56ae54706f 100644
--- a/src/solver/optimisation/variables/VariableManagement.cpp
+++ b/src/solver/optimisation/variables/VariableManagement.cpp
@@ -156,6 +156,15 @@ int& VariableManager::ShortTermStorageCostVariationWithdrawal(unsigned int index
.SIM_ShortTermStorage.CostVariationWithdrawal[index];
}
+int& VariableManager::NetPosition(unsigned int index,
+ unsigned int hourInWeek,
+ int offset,
+ int delta)
+{
+ auto pdt = GetShiftedTimeStep(offset, delta, hourInWeek);
+ return CorrespondanceVarNativesVarOptim_[pdt].NumeroDeVariableNetPosition[index];
+}
+
int& VariableManager::HydProd(unsigned int index, unsigned int hourInWeek, int offset, int delta)
{
auto pdt = GetShiftedTimeStep(offset, delta, hourInWeek);
diff --git a/src/solver/optimisation/variables/VariableManagement.h b/src/solver/optimisation/variables/VariableManagement.h
index 252c4007dd..9b730f80d3 100644
--- a/src/solver/optimisation/variables/VariableManagement.h
+++ b/src/solver/optimisation/variables/VariableManagement.h
@@ -75,6 +75,8 @@ class VariableManager
int offset = 0,
int delta = 0);
+ int& NetPosition(unsigned int index, unsigned int hourInWeek, int offset = 0, int delta = 0);
+
int& HydProd(unsigned int index, unsigned int hourInWeek, int offset = 0, int delta = 0);
int& HydProdDown(unsigned int index, unsigned int hourInWeek, int offset = 0, int delta = 0);
diff --git a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h
index 35051ba2d5..a82eee38f5 100644
--- a/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h
+++ b/src/solver/simulation/include/antares/solver/simulation/sim_structure_probleme_economique.h
@@ -45,6 +45,7 @@ struct CORRESPONDANCES_DES_VARIABLES
std::vector NumeroDeVariableDuPalierThermique;
+ std::vector NumeroDeVariableNetPosition;
std::vector NumeroDeVariablesDeLaProdHyd;
std::vector NumeroDeVariablesDePompage;
@@ -438,6 +439,8 @@ struct RESULTATS_HORAIRES
std::vector CoutsMarginauxHoraires;
std::vector ProductionThermique; // index is pdtHebdo
+ std::vector NetPositionHoraire;
+
std::vector<::ShortTermStorage::RESULTS> ShortTermStorage;
};
diff --git a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp
index dd7480671c..38d64d762e 100644
--- a/src/solver/simulation/sim_alloc_probleme_hebdo.cpp
+++ b/src/solver/simulation/sim_alloc_probleme_hebdo.cpp
@@ -157,6 +157,7 @@ void SIM_AllocationProblemePasDeTemps(PROBLEME_HEBDO& problem,
variablesMapping.NumeroDeVariableDuPalierThermique
.assign(study.runtime.thermalPlantTotalCount, 0);
+ variablesMapping.NumeroDeVariableNetPosition.assign(nbPays, 0);
variablesMapping.NumeroDeVariablesDeLaProdHyd.assign(nbPays, 0);
variablesMapping.NumeroDeVariablesDePompage.assign(nbPays, 0);
variablesMapping.NumeroDeVariablesDeNiveau.assign(nbPays, 0);
@@ -397,6 +398,9 @@ void SIM_AllocateAreas(PROBLEME_HEBDO& problem,
problem.ResultatsHoraires[k].TurbinageHoraire.assign(NombreDePasDeTemps, 0.);
problem.ResultatsHoraires[k].PompageHoraire.assign(NombreDePasDeTemps, 0.);
+
+ problem.ResultatsHoraires[k].NetPositionHoraire.assign(NombreDePasDeTemps, 0.);
+
problem.ResultatsHoraires[k].CoutsMarginauxHoraires.assign(NombreDePasDeTemps, 0.);
problem.ResultatsHoraires[k].niveauxHoraires.assign(NombreDePasDeTemps, 0.);
problem.ResultatsHoraires[k].valeurH2oHoraire.assign(NombreDePasDeTemps, 0.);