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