From 475f08bcb182812f142a952eb4fb86836af593d6 Mon Sep 17 00:00:00 2001
From: payetvin <113102157+payetvin@users.noreply.github.com>
Date: Mon, 20 Jan 2025 10:39:26 +0100
Subject: [PATCH 1/2] GUI bug: wrong indexes for thermal clusters in scenario
 builder [ANT-2580]  (#2576)

---
 .../antares/study/parts/common/cluster.h      |  5 +-
 .../study/parts/common/cluster_list.cpp       |  6 +-
 src/solver/simulation/common-eco-adq.cpp      |  2 +
 .../solver/variable/adequacy/overallCost.h    |  2 +-
 .../include/antares/solver/variable/area.hxx  |  4 +-
 .../variable/economy/dispatchableGeneration.h |  2 +-
 .../economy/nbOfDispatchedUnitsByPlant.h      | 10 +--
 .../economy/npCostByDispatchablePlant.h       |  4 +-
 .../economy/productionByDispatchablePlant.h   | 14 ++--
 .../economy/productionByRenewablePlant.h      |  4 +-
 .../solver/variable/economy/profitByPlant.h   |  6 +-
 .../economy/thermalAirPollutantEmissions.h    |  3 +-
 .../include/antares/solver/variable/state.h   | 16 ++---
 src/solver/variable/state.cpp                 | 70 +++++++++----------
 src/tests/inmemory-study/in-memory-study.cpp  |  4 +-
 15 files changed, 75 insertions(+), 77 deletions(-)

diff --git a/src/libs/antares/study/include/antares/study/parts/common/cluster.h b/src/libs/antares/study/include/antares/study/parts/common/cluster.h
index 4212fe40ce..99ab44808e 100644
--- a/src/libs/antares/study/include/antares/study/parts/common/cluster.h
+++ b/src/libs/antares/study/include/antares/study/parts/common/cluster.h
@@ -117,9 +117,8 @@ class Cluster
     double nominalCapacity = 0.;
 
     //! The index of the cluster from the area's point of view
-    //! \warning this variable is only valid when used by the solver
-    // (initialized in the same time that the runtime data)
-    uint areaWideIndex = (uint)-1;
+    unsigned int areaWideIndex = (uint)-1;
+    unsigned int enabledIndex = (uint)-1;
 
     //! tsNumbers must be constructed before series
     TimeSeriesNumbers tsNumbers;
diff --git a/src/libs/antares/study/parts/common/cluster_list.cpp b/src/libs/antares/study/parts/common/cluster_list.cpp
index b9afbaff2f..42720ebff3 100644
--- a/src/libs/antares/study/parts/common/cluster_list.cpp
+++ b/src/libs/antares/study/parts/common/cluster_list.cpp
@@ -153,15 +153,13 @@ void ClusterList<ClusterT>::rebuildIndexes()
     unsigned int index = 0;
     for (auto& c: allClusters_)
     {
-        c->areaWideIndex = index;
-        index++;
+        c->areaWideIndex = index++;
     }
 
     index = 0;
     for (auto& c: each_enabled())
     {
-        c->areaWideIndex = index;
-        index++;
+        c->enabledIndex = index++;
     }
 }
 
diff --git a/src/solver/simulation/common-eco-adq.cpp b/src/solver/simulation/common-eco-adq.cpp
index 59eb02e9b4..c0ef6a28a4 100644
--- a/src/solver/simulation/common-eco-adq.cpp
+++ b/src/solver/simulation/common-eco-adq.cpp
@@ -257,6 +257,8 @@ void PrepareRandomNumbers(Data::Study& study,
           //-----------------------------
           for (auto& cluster: area.thermal.list.each_enabled())
           {
+              // we use the areaWideIndex because the thermal noises are randomly calculated
+              // for every cluster to avoid different results if a cluster is deactivated
               uint clusterIndex = cluster->areaWideIndex;
               double& rnd = randomForYear.pThermalNoisesByArea[indexArea][clusterIndex];
               double randomClusterProdCost(0.);
diff --git a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h
index 3bdcee903b..8d73a400c8 100644
--- a/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h
+++ b/src/solver/variable/include/antares/solver/variable/adequacy/overallCost.h
@@ -263,7 +263,7 @@ class OverallCost: public Variable::IVariable<OverallCost<NextT>, NextT, VCardOv
         for (auto& cluster: area->thermal.list.each_enabled())
         {
             pValuesForTheCurrentYear[numSpace][state.hourInTheYear]
-              += thermal[area->index].thermalClustersOperatingCost[cluster->areaWideIndex];
+              += thermal[area->index].thermalClustersOperatingCost[cluster->enabledIndex];
         }
 
         // Next variable
diff --git a/src/solver/variable/include/antares/solver/variable/area.hxx b/src/solver/variable/include/antares/solver/variable/area.hxx
index 60028d1a85..c4601f08c7 100644
--- a/src/solver/variable/include/antares/solver/variable/area.hxx
+++ b/src/solver/variable/include/antares/solver/variable/area.hxx
@@ -379,7 +379,7 @@ void Areas<NextT>::hourForEachArea(State& state, uint numSpace)
           for (const auto& cluster: area.thermal.list.each_enabled())
           {
               // Intiializing the state for the current thermal cluster
-              state.initFromThermalClusterIndex(cluster->areaWideIndex);
+              state.initFromThermalClusterIndex(cluster->enabledIndex);
           }
 
           // Variables
@@ -456,7 +456,7 @@ void Areas<NextT>::yearEndBuild(State& state, uint year, uint numSpace)
               variablesForArea.yearEndBuildPrepareDataForEachThermalCluster(state, year, numSpace);
 
               // Building the end of year
-              state.yearEndBuildFromThermalClusterIndex(cluster->areaWideIndex);
+              state.yearEndBuildFromThermalClusterIndex(cluster->enabledIndex);
 
               // Variables
               variablesForArea.yearEndBuildForEachThermalCluster(state, year, numSpace);
diff --git a/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h b/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h
index 2c9b21046c..650ca63670 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/dispatchableGeneration.h
@@ -278,7 +278,7 @@ class DispatchableGeneration
         for (auto& cluster: area->thermal.list.each_enabled())
         {
             pValuesForTheCurrentYear[numSpace][cluster->groupID][state.hourInTheYear]
-              += thermal[area->index].thermalClustersProductions[cluster->areaWideIndex];
+              += thermal[area->index].thermalClustersProductions[cluster->enabledIndex];
         }
 
         // Next variable
diff --git a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h
index 37f19ea3d6..ed570bca43 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/nbOfDispatchedUnitsByPlant.h
@@ -237,7 +237,7 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariable<NbOfDispatchedUnits
         for (unsigned int i = 0; i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd]; ++i)
         {
             state.thermalClusterDispatchedUnitsCountForYear[i] += static_cast<uint>(
-              pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i]);
+              pValuesForTheCurrentYear[numSpace][state.thermalCluster->enabledIndex].hour[i]);
         }
 
         // Next variable
@@ -251,7 +251,7 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariable<NbOfDispatchedUnits
              i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd];
              ++i)
         {
-            pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i]
+            pValuesForTheCurrentYear[numSpace][state.thermalCluster->enabledIndex].hour[i]
               = state.thermalClusterDispatchedUnitsCountForYear[i];
         }
 
@@ -308,8 +308,8 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariable<NbOfDispatchedUnits
         auto& thermal = state.thermal;
         for (auto& cluster: area->thermal.list.each_enabled())
         {
-            pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].hour[state.hourInTheYear]
-              = thermal[area->index].numberOfUnitsONbyCluster[cluster->areaWideIndex];
+            pValuesForTheCurrentYear[numSpace][cluster->enabledIndex].hour[state.hourInTheYear]
+              = thermal[area->index].numberOfUnitsONbyCluster[cluster->enabledIndex];
         }
 
         // Next variable
@@ -342,7 +342,7 @@ class NbOfDispatchedUnitsByPlant: public Variable::IVariable<NbOfDispatchedUnits
                 // Write the data for the current year
                 results.variableCaption = cluster->name(); // VCardType::Caption();
                 results.variableUnit = VCardType::Unit();
-                pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex]
+                pValuesForTheCurrentYear[numSpace][cluster->enabledIndex]
                   .template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
             }
         }
diff --git a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h
index 79304684b3..2a9b806664 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/npCostByDispatchablePlant.h
@@ -240,7 +240,7 @@ class NonProportionalCostByDispatchablePlant
              i <= state.study.runtime.rangeLimits.hour[Data::rangeEnd];
              ++i)
         {
-            pValuesForTheCurrentYear[numSpace][state.thermalCluster->areaWideIndex].hour[i]
+            pValuesForTheCurrentYear[numSpace][state.thermalCluster->enabledIndex].hour[i]
               = state.thermalClusterNonProportionalCostForYear[i];
         }
 
@@ -323,7 +323,7 @@ class NonProportionalCostByDispatchablePlant
                 // Write the data for the current year
                 results.variableCaption = cluster->name(); // VCardType::Caption();
                 results.variableUnit = VCardType::Unit();
-                pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex]
+                pValuesForTheCurrentYear[numSpace][cluster->enabledIndex]
                   .template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
             }
         }
diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h
index 3e62a1f893..b2b604a6fc 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/productionByDispatchablePlant.h
@@ -259,10 +259,10 @@ class ProductionByDispatchablePlant
         {
             state.thermalClusterProductionForYear[i] += pValuesForTheCurrentYear
                                                           [numSpace]
-                                                          [state.thermalCluster->areaWideIndex]
+                                                          [state.thermalCluster->enabledIndex]
                                                             .hour[i];
             state.thermalClusterPMinOfTheClusterForYear[i] += pminOfTheClusterForYear
-              [numSpace][(state.thermalCluster->areaWideIndex * HOURS_PER_YEAR) + i];
+              [numSpace][(state.thermalCluster->enabledIndex * HOURS_PER_YEAR) + i];
         }
 
         // Next variable
@@ -319,12 +319,12 @@ class ProductionByDispatchablePlant
         for (auto& cluster: area->thermal.list.each_enabled())
         {
             // Production for this hour
-            pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].hour[state.hourInTheYear]
-              += thermal[area->index].thermalClustersProductions[cluster->areaWideIndex];
+            pValuesForTheCurrentYear[numSpace][cluster->enabledIndex].hour[state.hourInTheYear]
+              += thermal[area->index].thermalClustersProductions[cluster->enabledIndex];
 
             pminOfTheClusterForYear[numSpace]
-                                   [(cluster->areaWideIndex * HOURS_PER_YEAR) + state.hourInTheYear]
-              = thermal[area->index].PMinOfClusters[cluster->areaWideIndex];
+                                   [(cluster->enabledIndex * HOURS_PER_YEAR) + state.hourInTheYear]
+              = thermal[area->index].PMinOfClusters[cluster->enabledIndex];
         }
 
         // Next variable
@@ -363,7 +363,7 @@ class ProductionByDispatchablePlant
                 // Write the data for the current year
                 results.variableCaption = cluster->name(); // VCardType::Caption();
                 results.variableUnit = VCardType::Unit();
-                pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex]
+                pValuesForTheCurrentYear[numSpace][cluster->enabledIndex]
                   .template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
             }
         }
diff --git a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h
index ae459393db..1267c51b67 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/productionByRenewablePlant.h
@@ -286,7 +286,7 @@ class ProductionByRenewablePlant: public Variable::IVariable<ProductionByRenewab
               state.year,
               state.hourInTheYear);
 
-            pValuesForTheCurrentYear[numSpace][renewableCluster->areaWideIndex]
+            pValuesForTheCurrentYear[numSpace][renewableCluster->enabledIndex]
               .hour[state.hourInTheYear]
               += renewableClusterProduction;
         }
@@ -326,7 +326,7 @@ class ProductionByRenewablePlant: public Variable::IVariable<ProductionByRenewab
                 // Write the data for the current year
                 results.variableCaption = cluster->name();
                 results.variableUnit = VCardType::Unit();
-                pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex]
+                pValuesForTheCurrentYear[numSpace][cluster->enabledIndex]
                   .template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
             }
         }
diff --git a/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h b/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h
index 20e1d6e228..22b8f2d527 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/profitByPlant.h
@@ -281,11 +281,11 @@ class ProfitByPlant: public Variable::IVariable<ProfitByPlant<NextT>, NextT, VCa
         for (auto& cluster: area->thermal.list.each_enabled())
         {
             double hourlyClusterProduction = thermal[area->index]
-                                               .thermalClustersProductions[cluster->areaWideIndex];
+                                               .thermalClustersProductions[cluster->enabledIndex];
             uint tsIndex = cluster->series.timeseriesNumbers[state.year];
 
             // Thermal cluster profit
-            pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex].hour[hourInTheYear]
+            pValuesForTheCurrentYear[numSpace][cluster->enabledIndex].hour[hourInTheYear]
               = std::max((hourlyClusterProduction - cluster->PthetaInf[hourInTheYear]), 0.)
                 * (-areaMarginalCosts[hourInTheWeek]
                    - cluster->getCostProvider().getMarginalCost(tsIndex, hourInTheYear));
@@ -321,7 +321,7 @@ class ProfitByPlant: public Variable::IVariable<ProfitByPlant<NextT>, NextT, VCa
                 // Write the data for the current year
                 results.variableCaption = cluster->name(); // VCardType::Caption();
                 results.variableUnit = VCardType::Unit();
-                pValuesForTheCurrentYear[numSpace][cluster->areaWideIndex]
+                pValuesForTheCurrentYear[numSpace][cluster->enabledIndex]
                   .template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
             }
         }
diff --git a/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h b/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h
index 2955469715..3afdc2914b 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/thermalAirPollutantEmissions.h
@@ -259,8 +259,7 @@ class ThermalAirPollutantEmissions: public Variable::IVariable<ThermalAirPolluta
             {
                 pValuesForTheCurrentYear[numSpace][pollutant][state.hourInTheYear]
                   += cluster->emissions.factors[pollutant]
-                     * thermal[state.area->index]
-                         .thermalClustersProductions[cluster->areaWideIndex];
+                     * thermal[state.area->index].thermalClustersProductions[cluster->enabledIndex];
             }
         }
 
diff --git a/src/solver/variable/include/antares/solver/variable/state.h b/src/solver/variable/include/antares/solver/variable/state.h
index cbd55f4949..cabca09f08 100644
--- a/src/solver/variable/include/antares/solver/variable/state.h
+++ b/src/solver/variable/include/antares/solver/variable/state.h
@@ -85,9 +85,9 @@ class State
     ** We assume here that the variables related to an area
     ** are properly initialized.
     **
-    ** \param areaWideIndex Index of the thermal cluster for the current area
+    ** \param clusterEnabledIndex Index of the thermal cluster for the current area
     */
-    void initFromThermalClusterIndex(const unsigned int areaWideIndex);
+    void initFromThermalClusterIndex(const unsigned int clusterEnabledIndex);
 
     /*!
     ** \brief End the year by smoothing the thermal units run
@@ -95,10 +95,10 @@ class State
     ** We assume here that the variables related to an area
     ** are properly initialized.
     **
-    ** \param areaWideIndex Index of the thermal cluster for the current area
+    ** \param clusterEnabledIndex Index of the thermal cluster for the current area
     */
 
-    void yearEndBuildFromThermalClusterIndex(const unsigned int areaWideIndex);
+    void yearEndBuildFromThermalClusterIndex(const unsigned int clusterEnabledIndex);
 
 private:
     /*!
@@ -106,9 +106,9 @@ class State
     **
     ** Called in initFromAreaIndex to split code
     **
-    ** \param areaWideIndex Index of the thermal cluster for the current area
+    ** \param clusterEnabledIndex Index of the thermal cluster for the current area
     */
-    void initFromThermalClusterIndexProduction(const unsigned int areaWideIndex);
+    void initFromThermalClusterIndexProduction(const unsigned int clusterEnabledIndex);
 
     void yearEndBuildThermalClusterCalculateStartupCosts(
       const uint& maxDurationON,
@@ -125,9 +125,9 @@ class State
     ** \brief Smooth the thermal units run after resolutions
     ** using heuristics
     **
-    ** \param areaWideIndex Index of the thermal cluster for the current area
+    ** \param clusterEnabledIndex Index of the thermal cluster for the current area
     */
-    void yearEndSmoothDispatchedUnitsCount(const unsigned int areaWideIndex, uint numSpace);
+    void yearEndSmoothDispatchedUnitsCount(const unsigned int clusterEnabledIndex, uint numSpace);
 
 public:
     /*!
diff --git a/src/solver/variable/state.cpp b/src/solver/variable/state.cpp
index 0e9f0eca8e..0f96aef811 100644
--- a/src/solver/variable/state.cpp
+++ b/src/solver/variable/state.cpp
@@ -65,14 +65,14 @@ State::State(Data::Study& s):
 {
 }
 
-void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
+void State::initFromThermalClusterIndex(const uint clusterEnabledIndex)
 {
     // asserts
     assert(area);
-    assert(clusterAreaWideIndex < area->thermal.list.enabledCount());
+    assert(clusterEnabledIndex < area->thermal.list.enabledCount());
 
     // alias to the current thermal cluster
-    thermalCluster = area->thermal.list.enabledClusterAt(clusterAreaWideIndex).get();
+    thermalCluster = area->thermal.list.enabledClusterAt(clusterEnabledIndex).get();
     double thermalClusterAvailableProduction = thermalCluster->series.getCoefficient(this->year,
                                                                                      hourInTheYear);
 
@@ -86,14 +86,14 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
         // it doen't exist from the solver perspective
         assert(hourInTheYear < thermalCluster->series.timeSeries.height);
 
-        thermal[area->index].thermalClustersProductions[clusterAreaWideIndex]
+        thermal[area->index].thermalClustersProductions[clusterEnabledIndex]
           = thermalClusterAvailableProduction;
 
-        thermal[area->index].PMinOfClusters[clusterAreaWideIndex] = 0.;
-        thermal[area->index].numberOfUnitsONbyCluster[clusterAreaWideIndex] = 0; // will be
-                                                                                 // calculated
-                                                                                 // during the
-                                                                                 // smoothing
+        thermal[area->index].PMinOfClusters[clusterEnabledIndex] = 0.;
+        thermal[area->index].numberOfUnitsONbyCluster[clusterEnabledIndex] = 0; // will be
+                                                                                // calculated
+                                                                                // during the
+                                                                                // smoothing
     }
     else
     {
@@ -104,7 +104,7 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
             thermalClusterPMinOfAGroup = problemeHebdo->PaliersThermiquesDuPays[area->index]
                                            .pminDUnGroupeDuPalierThermique
                                              [thermalCluster->index]; // one by cluster
-            thermal[area->index].PMinOfClusters[clusterAreaWideIndex]
+            thermal[area->index].PMinOfClusters[clusterEnabledIndex]
               = problemeHebdo->PaliersThermiquesDuPays[area->index]
                   .PuissanceDisponibleEtCout[thermalCluster->index]
                   .PuissanceMinDuPalierThermique[hourInTheWeek]; // one per hour for one
@@ -113,10 +113,10 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
         else
         {
             // Adequacy
-            thermal[area->index].PMinOfClusters[clusterAreaWideIndex] = 0.;
+            thermal[area->index].PMinOfClusters[clusterEnabledIndex] = 0.;
         }
 
-        thermal[area->index].thermalClustersProductions[clusterAreaWideIndex]
+        thermal[area->index].thermalClustersProductions[clusterEnabledIndex]
           = hourlyResults->ProductionThermique[hourInTheWeek]
               .ProductionThermiqueDuPalier[thermalCluster->index];
 
@@ -125,22 +125,22 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
             using ucMode = Antares::Data::UnitCommitmentMode;
         case ucMode::ucHeuristicAccurate:
         case ucMode::ucMILP:
-            thermal[area->index].numberOfUnitsONbyCluster[clusterAreaWideIndex] = static_cast<uint>(
+            thermal[area->index].numberOfUnitsONbyCluster[clusterEnabledIndex] = static_cast<uint>(
               hourlyResults->ProductionThermique[hourInTheWeek]
                 .NombreDeGroupesEnMarcheDuPalier[thermalCluster->index]);
             break;
         default:
             // Economy Fast or Adequacy -- will be calculated during the smoothing
-            thermal[area->index].numberOfUnitsONbyCluster[clusterAreaWideIndex] = 0;
+            thermal[area->index].numberOfUnitsONbyCluster[clusterEnabledIndex] = 0;
         }
     }
-    initFromThermalClusterIndexProduction(clusterAreaWideIndex);
+    initFromThermalClusterIndexProduction(clusterEnabledIndex);
 
     if (simulationMode != Data::SimulationMode::Adequacy)
     {
         // Minimum power of a group of the cluster, one per year for each cluster - from the
         // solver
-        thermal[area->index].pminOfAGroup[clusterAreaWideIndex] = thermalClusterPMinOfAGroup;
+        thermal[area->index].pminOfAGroup[clusterEnabledIndex] = thermalClusterPMinOfAGroup;
     }
 
     // Nombre min de groupes appelés
@@ -148,21 +148,21 @@ void State::initFromThermalClusterIndex(const uint clusterAreaWideIndex)
     // en mode fast : est pris depuis l'heuristique
 }
 
-void State::initFromThermalClusterIndexProduction(const uint clusterAreaWideIndex)
+void State::initFromThermalClusterIndexProduction(const uint clusterEnabledIndex)
 {
     uint serieIndex = thermalCluster->series.timeseriesNumbers[this->year];
 
-    if (thermal[area->index].thermalClustersProductions[clusterAreaWideIndex] > 0.)
+    if (thermal[area->index].thermalClustersProductions[clusterEnabledIndex] > 0.)
     {
         // alias to the production of the current thermal cluster
-        double p = thermal[area->index].thermalClustersProductions[clusterAreaWideIndex];
+        double p = thermal[area->index].thermalClustersProductions[clusterEnabledIndex];
         // alias to the previous number of started units
-        uint previousUnitCount = thermal[area->index].unitCountLastHour[clusterAreaWideIndex];
+        uint previousUnitCount = thermal[area->index].unitCountLastHour[clusterEnabledIndex];
 
         // Looking for the new number of units which have been started
         uint newUnitCount;
 
-        if (p > thermal[area->index].productionLastHour[clusterAreaWideIndex])
+        if (p > thermal[area->index].productionLastHour[clusterEnabledIndex])
         {
             newUnitCount = static_cast<uint>(
               std::ceil(p / thermalCluster->nominalCapacityWithSpinning));
@@ -198,34 +198,34 @@ void State::initFromThermalClusterIndexProduction(const uint clusterAreaWideInde
 
         // calculating the operating cost for the current hour
         // O(h) = MA * P(h) * Modulation
-        thermal[area->index].thermalClustersOperatingCost[clusterAreaWideIndex]
+        thermal[area->index].thermalClustersOperatingCost[clusterEnabledIndex]
           = (p * thermalCluster->getCostProvider().getOperatingCost(serieIndex, hourInTheYear));
 
         // Startup cost
         if (newUnitCount > previousUnitCount && hourInTheSimulation != 0u)
         {
-            thermal[area->index].thermalClustersOperatingCost[clusterAreaWideIndex]
+            thermal[area->index].thermalClustersOperatingCost[clusterEnabledIndex]
               += thermalCluster->startupCost * (newUnitCount - previousUnitCount);
         }
 
         // Fixed price
-        thermal[area->index].thermalClustersOperatingCost[clusterAreaWideIndex] += thermalCluster
-                                                                                     ->fixedCost
-                                                                                   * newUnitCount;
+        thermal[area->index].thermalClustersOperatingCost[clusterEnabledIndex] += thermalCluster
+                                                                                    ->fixedCost
+                                                                                  * newUnitCount;
 
         // Storing the new unit count for the next hour
-        thermal[area->index].unitCountLastHour[clusterAreaWideIndex] = newUnitCount;
-        thermal[area->index].productionLastHour[clusterAreaWideIndex] = p;
+        thermal[area->index].unitCountLastHour[clusterEnabledIndex] = newUnitCount;
+        thermal[area->index].productionLastHour[clusterEnabledIndex] = p;
     }
     else
     {
-        thermal[area->index].thermalClustersOperatingCost[clusterAreaWideIndex] = 0.;
-        thermal[area->index].unitCountLastHour[clusterAreaWideIndex] = 0u;
-        thermal[area->index].productionLastHour[clusterAreaWideIndex] = 0.;
+        thermal[area->index].thermalClustersOperatingCost[clusterEnabledIndex] = 0.;
+        thermal[area->index].unitCountLastHour[clusterEnabledIndex] = 0u;
+        thermal[area->index].productionLastHour[clusterEnabledIndex] = 0.;
     }
 }
 
-void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex)
+void State::yearEndBuildFromThermalClusterIndex(const uint clusterEnabledIndex)
 {
     uint maxDurationON; // nombre d'heures de fonctionnement d'un groupe au delà duquel un
     // arrêt/redémarrage est préférable
@@ -244,7 +244,7 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex)
     std::array<uint, HOURS_PER_YEAR> ON_opt{};
 
     // Get cluster properties
-    Data::ThermalCluster* currentCluster = area->thermal.list.enabledClusterAt(clusterAreaWideIndex)
+    Data::ThermalCluster* currentCluster = area->thermal.list.enabledClusterAt(clusterEnabledIndex)
                                              .get();
 
     assert(endHourForCurrentYear <= HOURS_PER_YEAR);
@@ -307,12 +307,12 @@ void State::yearEndBuildFromThermalClusterIndex(const uint clusterAreaWideIndex)
             //	ON_min[h] = static_cast<uint>(std::ceil(thermalClusterProduction /
             // currentCluster->nominalCapacityWithSpinning)); // code 5.0.3b<7
             // 5.0.3b7
-            if (thermal[area->index].pminOfAGroup[clusterAreaWideIndex] > 0.)
+            if (thermal[area->index].pminOfAGroup[clusterEnabledIndex] > 0.)
             {
                 ON_min[h] = std::max(
                   std::min(static_cast<uint>(
                              std::floor(thermalClusterPMinOfTheClusterForYear[h]
-                                        / thermal[area->index].pminOfAGroup[clusterAreaWideIndex])),
+                                        / thermal[area->index].pminOfAGroup[clusterEnabledIndex])),
                            static_cast<uint>(
                              std::ceil(thermalClusterAvailableProduction
                                        / currentCluster->nominalCapacityWithSpinning))),
diff --git a/src/tests/inmemory-study/in-memory-study.cpp b/src/tests/inmemory-study/in-memory-study.cpp
index d889ed66c9..ad93a5b264 100644
--- a/src/tests/inmemory-study/in-memory-study.cpp
+++ b/src/tests/inmemory-study/in-memory-study.cpp
@@ -159,14 +159,14 @@ averageResults OutputRetriever::thermalGeneration(ThermalCluster* cluster)
 {
     auto result = retrieveResultsForThermalCluster<
       Variable::Economy::VCardProductionByDispatchablePlant>(cluster);
-    return averageResults((*result)[cluster->areaWideIndex].avgdata);
+    return averageResults((*result)[cluster->enabledIndex].avgdata);
 }
 
 averageResults OutputRetriever::thermalNbUnitsON(ThermalCluster* cluster)
 {
     auto result = retrieveResultsForThermalCluster<
       Variable::Economy::VCardNbOfDispatchedUnitsByPlant>(cluster);
-    return averageResults((*result)[cluster->areaWideIndex].avgdata);
+    return averageResults((*result)[cluster->enabledIndex].avgdata);
 }
 
 ScenarioBuilderRule::ScenarioBuilderRule(Study& study)

From a5ea8f64f86ba940306215e491699ab6a024a48c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20Omn=C3=A8s?= <florian.omnes@rte-france.com>
Date: Mon, 20 Jan 2025 15:27:09 +0100
Subject: [PATCH 2/2] Remove unused enum class (#2584)

---
 .../antares/study/parameters/adq-patch-params.h  | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h
index 53584a96d5..c053230a94 100644
--- a/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h
+++ b/src/libs/antares/study/include/antares/study/parameters/adq-patch-params.h
@@ -50,22 +50,6 @@ enum AdequacyPatchMode
     physicalAreaInsideAdqPatch = 2
 }; // enum AdequacyPatchMode
 
-/*!
-** \brief Setting Link Capacity (NTC) for Adequacy patch first step
-*/
-enum class NtcSetToZeroStatus_AdqPatchStep1
-{
-    //! Leave NTC local values
-    leaveLocalValues = 0,
-    //! Set NTC to zero
-    setToZero,
-    //! set only origine->extremity NTC to zero
-    setOriginExtremityToZero,
-    //! set only extremity->origine NTC to zero
-    setExtremityOriginToZero
-
-}; // enum NTC
-
 /*!
 ** \brief Types of Price Taking Order (PTO) for Adequacy Patch
 */