Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New "cash-flow" variable for ST storage #1633

Merged
merged 11 commits into from
Sep 22, 2023
1 change: 1 addition & 0 deletions src/solver/variable/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ set(SRC_VARIABLE_ECONOMY
economy/STStorageInjectionByCluster.h
economy/STStorageWithdrawalByCluster.h
economy/STStorageLevelsByCluster.h
economy/STStorageCashFlowByCluster.h
economy/unsupliedEnergy.h
economy/domesticUnsuppliedEnergy.h
economy/localMatchingRuleViolations.h
Expand Down
305 changes: 305 additions & 0 deletions src/solver/variable/economy/STStorageCashFlowByCluster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
/*
** 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 <http://www.gnu.org/licenses/>.
**
** SPDX-License-Identifier: licenceRef-GPL3_WITH_RTE-Exceptions
*/
#pragma once

#include "../variable.h"

namespace Antares::Solver::Variable::Economy
{
struct VCardSTstorageCashFlowByCluster
{
//! Caption
static std::string Caption()
{
return "STS Cashflow";
payetvin marked this conversation as resolved.
Show resolved Hide resolved
}
//! Unit
static std::string Unit()
{
return "CashFlow - Euro";
}

//! The short description of the variable
static std::string Description()
{
return "Cash Flow for short term storage";
payetvin marked this conversation as resolved.
Show resolved Hide resolved
}

//! The expecte results
typedef Results<R::AllYears::Average< // The average values throughout all years
>>
ResultsType;

//! The VCard to look for for calculating spatial aggregates
typedef VCardSTstorageCashFlowByCluster VCardForSpatialAggregate;

enum
flomnes marked this conversation as resolved.
Show resolved Hide resolved
{
//! Data Level
categoryDataLevel = Category::area,
//! File level (provided by the type of the results)
categoryFileLevel = ResultsType::categoryFile & (Category::de_sts),
payetvin marked this conversation as resolved.
Show resolved Hide resolved
//! Precision (views)
precision = Category::all,
//! Indentation (GUI)
nodeDepthForGUI = +0,
//! Decimal precision
decimal = 0,
//! Number of columns used by the variable
columnCount = Category::dynamicColumns,
//! The Spatial aggregation
spatialAggregate = Category::spatialAggregateSum,
spatialAggregateMode = Category::spatialAggregateEachYear,
spatialAggregatePostProcessing = 0,
//! Intermediate values
hasIntermediateValues = 1,
//! Can this variable be non applicable (0 : no, 1 : yes)
isPossiblyNonApplicable = 0,
};

typedef IntermediateValues IntermediateValuesDeepType;
typedef IntermediateValues* IntermediateValuesBaseType;
typedef IntermediateValuesBaseType* IntermediateValuesType;

}; // class VCard

/*!
** \brief Energy generated by short term storage clusters
*/
template<class NextT = Container::EndOfList>
class STstorageCashFlowByCluster : public Variable::IVariable<STstorageCashFlowByCluster<NextT>,
NextT,
VCardSTstorageCashFlowByCluster>
{
public:
//! Type of the next static variable
typedef NextT NextType;
//! VCard
typedef VCardSTstorageCashFlowByCluster VCardType;
//! Ancestor
typedef Variable::IVariable<STstorageCashFlowByCluster<NextT>, NextT, VCardType> AncestorType;

//! List of expected results
typedef typename VCardType::ResultsType ResultsType;

typedef VariableAccessor<ResultsType, VCardType::columnCount> VariableAccessorType;

enum
{
//! How many items have we got
count = 1 + NextT::count,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const instead of anonymous enum?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use constexpr instead

};
payetvin marked this conversation as resolved.
Show resolved Hide resolved

template<int CDataLevel, int CFile>
struct Statistics
{
enum
{
count
= ((VCardType::categoryDataLevel & CDataLevel && VCardType::categoryFileLevel & CFile)
? (NextType::template Statistics<CDataLevel, CFile>::count
+ VCardType::columnCount * ResultsType::count)
: NextType::template Statistics<CDataLevel, CFile>::count),
};
};

public:
STstorageCashFlowByCluster() : pValuesForTheCurrentYear(nullptr)
{
}
payetvin marked this conversation as resolved.
Show resolved Hide resolved

~STstorageCashFlowByCluster()
{
for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++)
delete[] pValuesForTheCurrentYear[numSpace];
delete[] pValuesForTheCurrentYear;
}

void initializeFromArea(Data::Study* study, Data::Area* area)
{
// Get the number of years in parallel
pNbYearsParallel = study->maxNbYearsInParallel;
pValuesForTheCurrentYear = new VCardType::IntermediateValuesBaseType[pNbYearsParallel];

// Get the area
nbClusters_ = area->shortTermStorage.count();
if (nbClusters_)
{
AncestorType::pResults.resize(nbClusters_);

for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++)
pValuesForTheCurrentYear[numSpace]
= new VCardType::IntermediateValuesDeepType[nbClusters_];

for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++)
for (unsigned int i = 0; i != nbClusters_; ++i)
pValuesForTheCurrentYear[numSpace][i].initializeFromStudy(*study);

for (unsigned int i = 0; i != nbClusters_; ++i)
{
AncestorType::pResults[i].initializeFromStudy(*study);
AncestorType::pResults[i].reset();
}
}
else
{
for (unsigned int numSpace = 0; numSpace < pNbYearsParallel; numSpace++)
{
pValuesForTheCurrentYear[numSpace] = nullptr;
}

AncestorType::pResults.clear();
}
// Next
NextType::initializeFromArea(study, area);
}

size_t getMaxNumberColumns() const
{
return nbClusters_ * ResultsType::count;
}

void yearBegin(unsigned int year, unsigned int numSpace)
{
// Reset the values for the current year
for (unsigned int i = 0; i != nbClusters_; ++i)
payetvin marked this conversation as resolved.
Show resolved Hide resolved
{
pValuesForTheCurrentYear[numSpace][i].reset();
}
// Next variable
NextType::yearBegin(year, numSpace);
}

void yearEnd(unsigned int year, unsigned int numSpace)
{
for (unsigned int clusterIndex = 0; clusterIndex < nbClusters_; ++clusterIndex)
{
// Compute all statistics from hourly results for the current year (daily, weekly, monthly, ...)
pValuesForTheCurrentYear[numSpace][clusterIndex].computeStatisticsForTheCurrentYear();
}
// Next variable
NextType::yearEnd(year, numSpace);
}

void computeSummary(std::map<unsigned int, unsigned int>& numSpaceToYear,
unsigned int nbYearsForCurrentSummary)
{
for (unsigned int numSpace = 0; numSpace < nbYearsForCurrentSummary; ++numSpace)
{
for (unsigned int clusterIndex = 0; clusterIndex < nbClusters_; ++clusterIndex)
{
// Merge all those values with the global results
AncestorType::pResults[clusterIndex].merge(numSpaceToYear[numSpace],
pValuesForTheCurrentYear[numSpace][clusterIndex]);
}
}

// Next variable
NextType::computeSummary(numSpaceToYear, nbYearsForCurrentSummary);
}

void hourBegin(unsigned int hourInTheYear)
{
// Next variable
NextType::hourBegin(hourInTheYear);
}

void hourForEachArea(State& state, unsigned int numSpace)
payetvin marked this conversation as resolved.
Show resolved Hide resolved
{
for (uint clusterIndex = 0; clusterIndex != state.area->shortTermStorage.count();
++clusterIndex)
{
// ST storage injection for the current cluster and this hour
// CashFlow[h] = (withdrawal - injection) * MRG. PRICE
pValuesForTheCurrentYear[numSpace][clusterIndex].hour[state.hourInTheYear]
= (state.hourlyResults->ShortTermStorage[state.hourInTheWeek].withdrawal[clusterIndex]
- state.hourlyResults->ShortTermStorage[state.hourInTheWeek].injection[clusterIndex])
payetvin marked this conversation as resolved.
Show resolved Hide resolved
* (-state.hourlyResults->CoutsMarginauxHoraires[state.hourInTheWeek]);
// Note: The marginal price provided by the solver is negative (naming convention).
}

// Next variable
NextType::hourForEachArea(state, numSpace);
}

inline void buildDigest(SurveyResults& results, int digestLevel, int dataLevel) const
{
// Ask to build the digest to the next variable
NextType::buildDigest(results, digestLevel, dataLevel);
}

Antares::Memory::Stored<double>::ConstReturnType retrieveRawHourlyValuesForCurrentYear(
unsigned int column,
unsigned int numSpace) const
{
return pValuesForTheCurrentYear[numSpace][column].hour;
}

inline uint64_t memoryUsage() const
{
uint64_t r = (sizeof(IntermediateValues) * nbClusters_ + IntermediateValues::MemoryUsage())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what r is for?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a temporary variable that's used to compute the memory usage.

* pNbYearsParallel;
r += sizeof(double) * nbClusters_ * maxHoursInAYear * pNbYearsParallel;
r += AncestorType::memoryUsage();
return r;
}

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])
{
assert(NULL != results.data.area);
const auto& shortTermStorage = results.data.area->shortTermStorage;

// Write the data for the current year
for (uint clusterIndex = 0; clusterIndex < nbClusters_; ++clusterIndex)
{
// Write the data for the current year
const auto* cluster = shortTermStorage.storagesByIndex[clusterIndex];
results.variableCaption = cluster->properties.name;
results.variableUnit = VCardType::Unit();
pValuesForTheCurrentYear[numSpace][clusterIndex]
.template buildAnnualSurveyReport<VCardType>(results, fileLevel, precision);
}
}
}

private:
//! Intermediate values for each year
typename VCardType::IntermediateValuesType pValuesForTheCurrentYear;
payetvin marked this conversation as resolved.
Show resolved Hide resolved
size_t nbClusters_;
payetvin marked this conversation as resolved.
Show resolved Hide resolved
unsigned int pNbYearsParallel;
payetvin marked this conversation as resolved.
Show resolved Hide resolved

}; // class STstorageCashFlowByCluster

} // End namespace Antares::Solver::Variable::Economy
4 changes: 3 additions & 1 deletion src/solver/variable/economy/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
#include "STStorageInjectionByCluster.h"
#include "STStorageWithdrawalByCluster.h"
#include "STStorageLevelsByCluster.h"
#include "STStorageCashFlowByCluster.h"

// Output variables associated to links
#include "links/flowLinear.h"
Expand Down Expand Up @@ -155,6 +156,7 @@ typedef // Prices
<HydroCost // Hydro costs
<ShortTermStorageByGroup<STstorageInjectionByCluster<
STstorageWithdrawalByCluster<STstorageLevelsByCluster<
STstorageCashFlowByCluster<
UnsupliedEnergy // Unsuplied Energy
<DomesticUnsuppliedEnergy // Domestic Unsupplied Energy
<LMRViolations // LMR Violations
Expand All @@ -174,7 +176,7 @@ typedef // Prices
<ProfitByPlant
// Links
<Variable::Economy::Links // All links
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
flomnes marked this conversation as resolved.
Show resolved Hide resolved
VariablesPerArea;

/*!
Expand Down