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

Feature/reserve model lot1 scalian #2008

Draft
wants to merge 40 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e43dd6f
Add reserves as NewReserve type as Reserve type already existed
h-fournier Mar 19, 2024
383ec23
Merge remote-tracking branch 'rte/develop' into feature/reserve_model…
h-fournier Mar 19, 2024
1272341
A clusterReserveParticipation is now associated to a cluster and not …
h-fournier Mar 22, 2024
9c9587d
Merge remote-tracking branch 'rte/develop' into feature/reserve_model…
h-fournier Mar 22, 2024
8909410
Added the loading of reserve chronicles as time series
sylvmara Mar 25, 2024
f455f4d
Loading reserves into the problem hebdo
sylvmara Mar 28, 2024
70ea5bd
New naming + internal review
h-fournier Apr 2, 2024
28208e6
Adding the first constraint (16bis) and counting the number of reserv…
sylvmara Apr 8, 2024
95d3ff1
Implementation of the linear problem matrix for the reserves, for coh…
sylvmara Apr 11, 2024
85ec9fb
Add variables to take into account the participation to reserves from…
h-fournier Apr 16, 2024
199b78e
Implement equation 17 bis
h-fournier Apr 17, 2024
b021930
Fix cluster index
h-fournier Apr 18, 2024
1a9b819
Clean code duplication
h-fournier Apr 18, 2024
9eaeeaa
Implement equation 17 quater
h-fournier Apr 18, 2024
a635acc
Implement equation 24
h-fournier Apr 19, 2024
e1a6613
Adjusting constraint 24, added global reserve index for index uniform…
sylvmara Apr 24, 2024
2840e41
Implementing reserve costs for excess and failure
sylvmara Apr 24, 2024
0a91049
Adding reserve participation costs
sylvmara Apr 25, 2024
f429eac
Fix include
h-fournier Apr 29, 2024
3761e7c
Fix variable initialization and counting variables
h-fournier Apr 30, 2024
4de9dc7
Fix ClusterParticipationIndex
h-fournier May 6, 2024
7a6238c
Correct number of terms for reserve constraints and renaming of varia…
sylvmara May 13, 2024
3670324
Add NeedReserve name using the variableNamer
h-fournier May 13, 2024
f3096b3
Fix counting nbTermes for equation 24
h-fournier May 13, 2024
85f3dcd
Multiple fixes
h-fournier May 15, 2024
6f11633
Fix missing a max boundary initialization
h-fournier May 15, 2024
df30984
Work on retrocompatibility
h-fournier May 16, 2024
ebbaa11
Add constraint 17 ter : Power output is bounded by must-run commitmen…
h-fournier May 17, 2024
1d7dbcd
Add Reserve cost :
h-fournier May 29, 2024
aa3807a
Working outputs to the ui for reservation costs overall and by cluste…
sylvmara Jun 5, 2024
299664d
Hiding outputs for clusters when reserves are not activated
sylvmara Jun 6, 2024
be5d670
Added reserves outputs as files for unsupplied, spillage costs and re…
sylvmara Jun 12, 2024
50d661d
Solved bug where need values for reserves were repeating
sylvmara Jun 13, 2024
0bb5a73
Removed bug index for cluster reserve participation
sylvmara Jun 17, 2024
1fbd4cf
Add a colomn for each each cluster participation to reserves to the o…
h-fournier Jun 21, 2024
60eff8e
Add a column for each group fo each reserve for the participation to …
h-fournier Jun 24, 2024
e7ea4b3
Added outputs for spilled and unsupplied volumes into the interface a…
sylvmara Jun 24, 2024
8cfba68
Rename VCardReserveParticipationUnsuppliedSpilled.h to vCardReservePa…
sylvmara Jun 26, 2024
502207c
Changeed the cmake list in order to pass the CI
sylvmara Jun 26, 2024
5c27d68
Fixed bugs in indexes of reserves participations
sylvmara Jul 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libs/antares/study/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ source_group("study\\scenario builder" FILES ${SRC_MATRIX})
set(SRC_AREAS
include/antares/study/area/constants.h
include/antares/study/area/area.h
include/antares/study/area/capacityReservation.h
include/antares/study/area/area.hxx
include/antares/study/area/scratchpad.h
area/scratchpad.cpp
Expand Down
79 changes: 78 additions & 1 deletion src/libs/antares/study/area/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "antares/study/parts/parts.h"
#include "antares/study/parts/load/prepro.h"
#include <antares/study/area/scratchpad.h>
#include <antares/study/area/capacityReservation.h>

#define SEP IO::Separator

Expand Down Expand Up @@ -778,6 +779,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study,
area.spreadSpilledEnergyCost = 0.;

bool ret = true;
IniFile ini;

// DSM, Reserves, D-1
buffer.clear() << study.folderInput << SEP << "reserves" << SEP << area.id << ".txt";
Expand Down Expand Up @@ -842,6 +844,78 @@ static bool AreaListLoadFromFolderSingleArea(Study& study,
}
}

// Reserves
{
buffer.clear() << study.folderInput << SEP << "reserves" << SEP << area.id << SEP
<< "reserves.ini";
if (!ini.open(buffer))
{
logs.warning() << study.folderInput << SEP << "reserves" << SEP << area.id << SEP
<< "reserves.ini";
return false;
}
ini.each(
[&](const IniFile::Section& section)
{
if (area.allCapacityReservations.contains(section.name))
{
logs.warning() << area.name << ": reserve name already exists for reserve "
<< section.name;
}
else
{
CapacityReservation tmpCapacityReservation;
std::string file_name = AllCapacityReservations::toFilename(section.name);
int type = -1;
for (auto* p = section.firstProperty; p; p = p->next)
{
CString<30, false> tmp;
tmp = p->key;
tmp.toLower();

if (tmp == "failure-cost")
{
if (!p->value.to<float>(tmpCapacityReservation.failureCost))
{
logs.warning() << area.name << ": invalid failure cost for reserve "
<< section.name;
}
}
else if (tmp == "spillage-cost")
{
if (!p->value.to<float>(tmpCapacityReservation.spillageCost))
{
logs.warning() << area.name << ": invalid spillage cost for reserve "
<< section.name;
}
}
else if (tmp == "type")
{
if (p->value == "up")
type = 0;
else if (p->value == "down")
type = 1;
else
logs.warning()
<< area.name << ": invalid type for reserve " << section.name;
}
else
logs.warning()
<< area.name << ": invalid key " << tmp << " in file " << buffer;
}
buffer.clear() << study.folderInput << SEP << "reserves" << SEP << area.id << SEP
<< file_name << ".txt";
ret = tmpCapacityReservation.need.loadFromFile(buffer, false) && ret;
if (type == 0)
area.allCapacityReservations.areaCapacityReservationsUp.emplace(section.name, tmpCapacityReservation);
else if (type == 1)
area.allCapacityReservations.areaCapacityReservationsDown.emplace(section.name, tmpCapacityReservation);
else
logs.warning() << area.name << ": invalid type for reserve " << section.name;
}
});
}

// Solar
{
if (area.solar.prepro) // Prepro
Expand Down Expand Up @@ -937,6 +1011,10 @@ static bool AreaListLoadFromFolderSingleArea(Study& study,
// In adequacy mode, all thermal clusters must be in 'mustrun' mode
if (study.usedByTheSolver && study.parameters.mode == SimulationMode::Adequacy)
area.thermal.list.enableMustrunForEveryone();

buffer.clear() << study.folderInput << SEP << "thermal" << SEP << "clusters" << SEP
<< area.id << SEP << "reserves.ini";
ret = area.thermal.list.loadReserveParticipations(area, buffer) && ret;
}

// Short term storage
Expand All @@ -962,7 +1040,6 @@ static bool AreaListLoadFromFolderSingleArea(Study& study,
// Nodal Optimization
buffer.clear() << study.folderInput << SEP << "areas" << SEP << area.id << SEP
<< "optimization.ini";
IniFile ini;
if (!ini.open(buffer))
return false;

Expand Down
4 changes: 4 additions & 0 deletions src/libs/antares/study/include/antares/study/area/area.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "ui.h"
#include "constants.h"
#include "antares/study/filter.h"
#include <antares/study/area/capacityReservation.h>

namespace Antares
{
Expand Down Expand Up @@ -293,6 +294,9 @@ class Area final : private Yuni::NonCopyable<Area>
double spreadSpilledEnergyCost = 0.;
//@}

/// \name AllCapacityReservations structure to keep track of the added capacity reservations
AllCapacityReservations allCapacityReservations;

//! \name Output filtering
//@{
//! Print results for the area in the simulation synthesis
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
** 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 <https://opensource.org/license/mpl-2-0/>.
*/
#ifndef __ANTARES_LIBS_STUDY_NEW_RESERVES_H__
#define __ANTARES_LIBS_STUDY_NEW_RESERVES_H__

#include <yuni/yuni.h>
#include <yuni/core/noncopyable.h>
#include <yuni/core/string.h>
#include <vector>
#include <optional>
#include <antares/series/series.h>
#include <antares/array/matrix.h>

/// @brief Represents an area capacity reservation using it's name, it's failure cost and it's spillage cost
struct CapacityReservation
{
CapacityReservation() : failureCost(0), spillageCost(0), need(timeseriesNumbers) {}
float failureCost;
float spillageCost;
Antares::Data::TimeSeries need;

private:
Matrix<uint32_t> timeseriesNumbers;
};

/// @brief Stores all the Capacity reservations in two vectors for the up and down reserves
struct AllCapacityReservations
{
std::map<std::string, CapacityReservation> areaCapacityReservationsUp;
std::map<std::string, CapacityReservation> areaCapacityReservationsDown;

/// @brief Check if the capacity reservation name already exist in both the up and down reserves
/// @param name
/// @return true if the capacity reservation already existed
bool contains(std::string name)
{
return areaCapacityReservationsUp.contains(name) || areaCapacityReservationsDown.contains(name);
}

/// @brief Get a capacity reservation from both the up and down reserves using its name
/// @param name
/// @return an optional of the capacity reservation reference if the reserve was found, and a nullopt
/// otherwise
std::optional<std::reference_wrapper<CapacityReservation>> getReserveByName(Yuni::ShortString256 name)
{
if (areaCapacityReservationsUp.contains(name))
{
return areaCapacityReservationsUp.at(name);
}
else if (areaCapacityReservationsDown.contains(name))
{
return areaCapacityReservationsDown.at(name);
}
return std::nullopt;
}

/// @brief Returns lower case, no space string
/// @param name
/// @return A string usable for file naming
static std::string toFilename(std::string name)
{
std::string file_name = name;
std::replace(file_name.begin(), file_name.end(), ' ', '_');
std::transform(file_name.begin(), file_name.end(), file_name.begin(), ::tolower);
return file_name;
}
};

/// @brief Represents the cluster reserve participation to a given reserve
struct ClusterReserveParticipation
{
std::reference_wrapper<CapacityReservation> capacityReservation;
float maxPower = 0;
float participationCost = 0;

ClusterReserveParticipation(std::reference_wrapper<CapacityReservation> reserve,
float power,
float cost) :
capacityReservation(reserve), maxPower(power), participationCost(cost)
{
}

ClusterReserveParticipation& operator=(const ClusterReserveParticipation& other)
{
// Check for self-assignment
if (this != &other)
{
// Copy the values from the other object
capacityReservation = other.capacityReservation;
maxPower = other.maxPower;
participationCost = other.participationCost;
}
return *this;
}
};

#endif // __ANTARES_LIBS_STUDY_LINKS_H__
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <antares/array/matrix.h>
#include <antares/series/series.h>
#include "../../fwd.h"
#include <antares/study/area/capacityReservation.h>

#include <set>
#include <map>
Expand Down Expand Up @@ -104,6 +105,12 @@ class Cluster
bool saveDataSeriesToFolder(const AnyString& folder) const;
bool loadDataSeriesFromFolder(Study& s, const AnyString& folder);

//! @brief Add the reserve participation to the current clusterReservesParticipations map
//! @param name the name of the reserve to add
//! @param reserveParticipation the reserve participation to add
void addReserveParticipation(std::string name,
ClusterReserveParticipation reserveParticipation);

uint unitCount = 0;

bool isEnabled() const { return enabled; }
Expand Down Expand Up @@ -133,13 +140,30 @@ class Cluster
*/
Matrix<> modulation;

//! \brief Returns true if cluster participates in a reserve with this name
bool isParticipatingInReserve(std::string name);

//! \brief Returns max power for a reserve if participating, -1 otherwise
float reserveMaxPower(std::string name);

//! \brief Returns participating cost for a reserve if participating, -1 otherwise
float reserveCost(std::string name);

//! \brief Returns the number of reserves linked to this cluster
unsigned int reservesCount();


protected:
Data::ClusterName pName;
Data::ClusterName pID;
Data::ClusterName pGroup;

private:
virtual unsigned int precision() const = 0;
//! @brief Stores the reserves Participations for each reserve, the key is the name of the
//! reserve
std::map<std::string, ClusterReserveParticipation> clusterReservesParticipations;

};
} // namespace Data
} // namespace Antares
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "../../fwd.h"

#include <antares/writer/i_writer.h>
#include <antares/study/area/capacityReservation.h>
#include <antares/study/parts/common/cluster.h>

#include <algorithm>
#include <vector>
Expand Down Expand Up @@ -127,6 +129,14 @@ class ClusterList
bool loadDataSeriesFromFolder(Study& study,
const AnyString& folder);

/// @brief Load the reserve participation. For each entry, it checks if the reserve has been
/// added to area.allCapacityReservations, if not then log the name of the reserve that has not been found.
/// @tparam ClusterT Type of the Cluster list
/// @param area Reference to area
/// @param file File to read the reserve participations entries
/// @return false if the file opening failed, true otherwise
bool loadReserveParticipations(Area& area, const AnyString& folder);

bool saveDataSeriesToFolder(const AnyString& folder) const;

virtual bool saveToFolder(const AnyString& folder) const = 0;
Expand All @@ -148,6 +158,10 @@ class ClusterList
unsigned int allClustersCount() const;
void addToCompleteList(std::shared_ptr<ClusterT> cluster);
void sortCompleteList();
/// @brief Get the cluster from the vector allClusters_ using it's name
/// @param clusterName
/// @return nullopt if no clusters found else a pointer to the cluster
std::optional<std::shared_ptr<Cluster>> getClusterByName(std::string clusterName);

protected:
std::vector<std::shared_ptr<ClusterT>> allClusters_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ class ThermalClusterList : public ClusterList<ThermalCluster>
unsigned int enabledAndMustRunCount() const;
unsigned int enabledAndNotMustRunCount() const;

unsigned int reservesCount() const;

private:
// Give a special index to enbled and not must-run THERMAL clusters
void rebuildIndex() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class StudyRuntimeInfos
//! Total
uint thermalPlantTotalCount;
uint thermalPlantTotalCountMustRun;
uint capacityReservationCount = 0;

uint shortTermStorageCount = 0;

Expand Down
Loading
Loading