diff --git a/src/solver/optimisation/post_process_commands.cpp b/src/solver/optimisation/post_process_commands.cpp
index 3ddc06ddde..7e00830580 100644
--- a/src/solver/optimisation/post_process_commands.cpp
+++ b/src/solver/optimisation/post_process_commands.cpp
@@ -19,9 +19,8 @@
** along with Antares_Simulator. If not, see .
*/
-#include "antares/solver/optimisation/post_process_commands.h"
-
#include "antares/solver/optimisation/adequacy_patch_csr/adq_patch_curtailment_sharing.h"
+#include "antares/solver/optimisation/post_process_commands.h"
#include "antares/solver/simulation/adequacy_patch_runtime_data.h"
#include "antares/solver/simulation/common-eco-adq.h"
@@ -143,6 +142,18 @@ void UpdateMrgPriceAfterCSRcmd::execute(const optRuntimeData&)
const bool isHourTriggeredByCsr = problemeHebdo_->adequacyPatchRuntimeData
->wasCSRTriggeredAtAreaHour(Area, hour);
+ // IF UNSP. ENR CSR == 0, MRG. PRICE CSR = MRG. PRICE
+ // ELSE, MRG. PRICE CSR = “Unsupplied Energy Cost”
+ if (hourlyResults.ValeursHorairesDeDefaillancePositiveCSR[hour] > 0.5 && areaInside)
+ {
+ hourlyResults.CoutsMarginauxHorairesCSR[hour] = -unsuppliedEnergyCost;
+ }
+ else
+ {
+ hourlyResults.CoutsMarginauxHorairesCSR[hour] = hourlyResults
+ .CoutsMarginauxHoraires[hour];
+ }
+
if (isHourTriggeredByCsr
&& hourlyResults.ValeursHorairesDeDefaillancePositive[hour] > 0.5 && areaInside)
{
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..4545200331 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
@@ -436,6 +436,7 @@ struct RESULTATS_HORAIRES
std::vector debordementsHoraires;
std::vector CoutsMarginauxHoraires;
+ std::vector CoutsMarginauxHorairesCSR;
std::vector ProductionThermique; // index is pdtHebdo
std::vector<::ShortTermStorage::RESULTS> ShortTermStorage;
diff --git a/src/solver/variable/CMakeLists.txt b/src/solver/variable/CMakeLists.txt
index ed7c017f5b..49105937c3 100644
--- a/src/solver/variable/CMakeLists.txt
+++ b/src/solver/variable/CMakeLists.txt
@@ -100,6 +100,7 @@ set(SRC_VARIABLE_ECONOMY
include/antares/solver/variable/economy/STStorageCashFlowByCluster.h
include/antares/solver/variable/economy/unsupliedEnergy.h
include/antares/solver/variable/economy/unsupliedEnergyCsr.h
+ include/antares/solver/variable/economy/priceCSR.h
include/antares/solver/variable/economy/domesticUnsuppliedEnergy.h
include/antares/solver/variable/economy/localMatchingRuleViolations.h
include/antares/solver/variable/economy/dtgMarginAfterCsr.h
diff --git a/src/solver/variable/include/antares/solver/variable/economy/all.h b/src/solver/variable/include/antares/solver/variable/economy/all.h
index 17207c22db..bd2e5c4cb2 100644
--- a/src/solver/variable/include/antares/solver/variable/economy/all.h
+++ b/src/solver/variable/include/antares/solver/variable/economy/all.h
@@ -60,6 +60,7 @@
#include "overallCost.h"
#include "overallCostCsr.h"
#include "overflow.h"
+#include "priceCSR.h"
#include "pumping.h"
#include "renewableGeneration.h"
#include "reservoirlevel.h"
@@ -95,62 +96,64 @@ namespace Antares::Solver::Variable::Economy
/*!
** \brief All variables for a single area (economy)
*/
-typedef // Prices
- OverallCost // Overall Cost (Op. Cost + Unsupplied Eng.)
- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+typedef // Prices
+ OverallCost // Overall Cost (Op. Cost + Unsupplied Eng.)
+ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
VariablesPerArea;
/*!
diff --git a/src/solver/variable/include/antares/solver/variable/economy/priceCSR.h b/src/solver/variable/include/antares/solver/variable/economy/priceCSR.h
new file mode 100644
index 0000000000..a3eac2966a
--- /dev/null
+++ b/src/solver/variable/include/antares/solver/variable/economy/priceCSR.h
@@ -0,0 +1,273 @@
+/*
+** Copyright 2007-2023 RTE
+** Authors: Antares_Simulator Team
+**
+** This file is part of Antares_Simulator.
+**
+** Antares_Simulator is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** There are special exceptions to the terms and conditions of the
+** license as they are applied to this software. View the full text of
+** the exceptions in file COPYING.txt in the directory of this software
+** distribution
+**
+** 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
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with Antares_Simulator. If not, see .
+**
+** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions
+*/
+#pragma once
+
+#include "yuni/yuni.h"
+
+#include "../variable.h"
+
+namespace Antares::Solver::Variable::Economy
+{
+struct VCardPriceCSR
+{
+ //! Caption
+ static std::string Caption()
+ {
+ return "MRG. PRICE CSR";
+ }
+
+ //! Unit
+ static std::string Unit()
+ {
+ return "Euro";
+ }
+
+ //! The short description of the variable
+ static std::string Description()
+ {
+ return "Marginal Price CSR, throughout all MC years";
+ }
+
+ //! The expecte results
+ typedef Results>>>>
+ ResultsType;
+
+ //! The VCard to look for for calculating spatial aggregates
+ typedef VCardPrice VCardForSpatialAggregate;
+
+ enum
+ {
+ //! Data Level
+ categoryDataLevel = Category::DataLevel::area,
+ //! File level (provided by the type of the results)
+ categoryFileLevel = ResultsType::categoryFile
+ & (Category::FileLevel::id | Category::FileLevel::va),
+ //! Precision (views)
+ precision = Category::all,
+ //! Indentation (GUI)
+ nodeDepthForGUI = +0,
+ //! Decimal precision
+ decimal = 2,
+ //! Number of columns used by the variable (One ResultsType per column)
+ columnCount = 1,
+ //! The Spatial aggregation
+ spatialAggregate = Category::spatialAggregateAverage,
+ spatialAggregateMode = Category::spatialAggregateEachYear,
+ spatialAggregatePostProcessing = Category::spatialAggregatePostProcessingPrice,
+ //! Intermediate values
+ hasIntermediateValues = 1,
+ //! Can this variable be non applicable (0 : no, 1 : yes)
+ isPossiblyNonApplicable = 0,
+ };
+
+ typedef IntermediateValues IntermediateValuesBaseType;
+ typedef IntermediateValues* IntermediateValuesType;
+
+ typedef IntermediateValuesBaseType* IntermediateValuesTypeForSpatialAg;
+
+}; // class VCard
+
+/*!
+** \brief Marginal Price
+*/
+template
+class PriceCSR: public Variable::IVariable, NextT, VCardPriceCSR>
+{
+public:
+ //! Type of the next static variable
+ typedef NextT NextType;
+ //! VCard
+ typedef VCardPriceCSR VCardType;
+ //! Ancestor
+ typedef Variable::IVariable, NextT, VCardType> AncestorType;
+
+ //! List of expected results
+ typedef typename VCardType::ResultsType ResultsType;
+
+ typedef VariableAccessor VariableAccessorType;
+
+ enum
+ {
+ //! How many items have we got
+ count = 1 + NextT::count,
+ };
+
+ template
+ struct Statistics
+ {
+ enum
+ {
+ count = ((VCardType::categoryDataLevel & CDataLevel
+ && VCardType::categoryFileLevel & CFile)
+ ? (NextType::template Statistics::count
+ + VCardType::columnCount * ResultsType::count)
+ : NextType::template Statistics::count),
+ };
+ };
+
+public:
+ ~PriceCSR()
+ {
+ delete[] pValuesForTheCurrentYear;
+ }
+
+ void initializeFromStudy(Data::Study& study)
+ {
+ pNbYearsParallel = study.maxNbYearsInParallel;
+
+ // Average thoughout all years
+ InitializeResultsFromStudy(AncestorType::pResults, study);
+
+ // Intermediate values
+ pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel];
+ for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++)
+ {
+ pValuesForTheCurrentYear[numSpace].initializeFromStudy(study);
+ }
+
+ // Next
+ NextType::initializeFromStudy(study);
+ }
+
+ template
+ static void InitializeResultsFromStudy(R& results, Data::Study& study)
+ {
+ VariableAccessorType::InitializeAndReset(results, study);
+ }
+
+ void initializeFromArea(Data::Study* study, Data::Area* area)
+ {
+ // Next
+ NextType::initializeFromArea(study, area);
+ }
+
+ void initializeFromLink(Data::Study* study, Data::AreaLink* link)
+ {
+ // Next
+ NextType::initializeFromAreaLink(study, link);
+ }
+
+ void simulationBegin()
+ {
+ // Next
+ NextType::simulationBegin();
+ }
+
+ void simulationEnd()
+ {
+ NextType::simulationEnd();
+ }
+
+ void yearBegin(uint year, unsigned int numSpace)
+ {
+ // Reset the values for the current year
+ pValuesForTheCurrentYear[numSpace].reset();
+ // Next variable
+ NextType::yearBegin(year, numSpace);
+ }
+
+ void yearEndBuild(State& state, unsigned int year)
+ {
+ // Next variable
+ NextType::yearEndBuild(state, year);
+ }
+
+ void yearEnd(uint year, unsigned int numSpace)
+ {
+ // Compute all statistics for the current year (daily,weekly,monthly)
+ pValuesForTheCurrentYear[numSpace].computeAveragesForCurrentYearFromHourlyResults();
+
+ // Next variable
+ NextType::yearEnd(year, numSpace);
+ }
+
+ void computeSummary(std::map& numSpaceToYear,
+ unsigned int nbYearsForCurrentSummary)
+ {
+ for (unsigned int numSpace = 0; numSpace < nbYearsForCurrentSummary; ++numSpace)
+ {
+ // Merge all those values with the global results
+ AncestorType::pResults.merge(numSpaceToYear[numSpace] /*year*/,
+ pValuesForTheCurrentYear[numSpace]);
+ }
+
+ // Next variable
+ NextType::computeSummary(numSpaceToYear, nbYearsForCurrentSummary);
+ }
+
+ void hourBegin(uint hourInTheYear)
+ {
+ // Next variable
+ NextType::hourBegin(hourInTheYear);
+ }
+
+ void hourForEachArea(State& state, unsigned int numSpace)
+ {
+ pValuesForTheCurrentYear[numSpace][state.hourInTheYear] = -state.hourlyResults
+ ->CoutsMarginauxHorairesCSR
+ [state.hourInTheWeek];
+ // Next variable
+ NextType::hourForEachArea(state, numSpace);
+ }
+
+ Antares::Memory::Stored::ConstReturnType retrieveRawHourlyValuesForCurrentYear(
+ uint,
+ unsigned int numSpace) const
+ {
+ return pValuesForTheCurrentYear[numSpace].hour;
+ }
+
+ void localBuildAnnualSurveyReport(SurveyResults& results,
+ int fileLevel,
+ int precision,
+ unsigned int numSpace) const
+ {
+ // Initializing external pointer on current variable non applicable status
+ results.isCurrentVarNA = AncestorType::isNonApplicable;
+
+ if (AncestorType::isPrinted[0])
+ {
+ // Write the data for the current year
+ results.variableCaption = VCardType::Caption();
+ results.variableUnit = VCardType::Unit();
+ pValuesForTheCurrentYear[numSpace]
+ .template buildAnnualSurveyReport(results, fileLevel, precision);
+ }
+ }
+
+private:
+ //! Intermediate values for each year
+ typename VCardType::IntermediateValuesType pValuesForTheCurrentYear;
+ unsigned int pNbYearsParallel;
+
+}; // class PriceCSR
+
+} // namespace Antares::Solver::Variable::Economy