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

For short-term storage cumulative constraints [ANT-1855] #2546

Merged
merged 48 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
11c120e
update
a-zakir Dec 19, 2024
f100200
update
a-zakir Dec 20, 2024
88698d4
read new folder
a-zakir Dec 20, 2024
ffb6a42
update outer-inner constraint count
a-zakir Dec 20, 2024
de7c893
update unpacked constraints
a-zakir Dec 20, 2024
1fcc874
update name of unpacked constraints
a-zakir Dec 20, 2024
c9c7711
Merge branch 'develop' into feature/variable-rhs-sts-new-constraint
a-zakir Dec 20, 2024
be9f174
update
a-zakir Dec 20, 2024
ef2b214
Merge branch 'feature/variable-rhs-sts-new-constraint' of https://git…
a-zakir Dec 20, 2024
11169e1
add UT
a-zakir Dec 20, 2024
cf2e4bc
add UT
a-zakir Dec 20, 2024
c0b684e
use tmp dir as test dir
a-zakir Dec 20, 2024
d2b66c9
add test
a-zakir Dec 20, 2024
8e7cab0
UPDATE
a-zakir Dec 23, 2024
8ca3d69
update tests
a-zakir Dec 23, 2024
dc7488a
Merge branch 'develop' into feature/variable-rhs-sts-new-constraint
payetvin Dec 31, 2024
4c84485
format
payetvin Dec 31, 2024
ebd2664
Add function loadHours
payetvin Dec 31, 2024
480c30f
rename loadconstrintfrominifile
payetvin Dec 31, 2024
9988829
add readRHS
payetvin Dec 31, 2024
77623b5
rename additional_constraints
payetvin Dec 31, 2024
8057164
format
payetvin Dec 31, 2024
fba0351
use a pair
payetvin Dec 31, 2024
5037c3e
use a class instead of struct
payetvin Dec 31, 2024
63d7935
rename files
payetvin Dec 31, 2024
c2ca5b7
few comments
payetvin Dec 31, 2024
309b537
format
payetvin Dec 31, 2024
57a8dd1
revert and update
a-zakir Jan 2, 2025
efd16e0
update
a-zakir Jan 2, 2025
5c4a438
split tests
a-zakir Jan 2, 2025
d5f0bca
on malformed rhs file
a-zakir Jan 2, 2025
bf3bd6e
update
a-zakir Jan 2, 2025
772434d
Add attribute `enabled` to additional constraints, adapt tests [ANT-1…
flomnes Jan 3, 2025
fe5ec25
add robustness tests
a-zakir Jan 6, 2025
f78e9c5
add robustness tests
a-zakir Jan 6, 2025
35f0d6a
update
a-zakir Jan 6, 2025
674155f
Format
flomnes Jan 6, 2025
31e92a0
Merge remote-tracking branch 'github/develop' into feature/variable-r…
flomnes Jan 6, 2025
d1dd983
Fix build
flomnes Jan 6, 2025
87d36c6
update
a-zakir Jan 6, 2025
2eb45b6
update
a-zakir Jan 6, 2025
bd6b47b
update vcpkg
a-zakir Jan 6, 2025
072d709
eliminate spaces
a-zakir Jan 6, 2025
89b260f
avoidable string copy
a-zakir Jan 6, 2025
6634097
test white spaces
a-zakir Jan 6, 2025
a1f7df7
test valid white spaces
a-zakir Jan 6, 2025
eb64775
format
a-zakir Jan 6, 2025
189d1b3
remove comments
a-zakir Jan 6, 2025
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
4 changes: 2 additions & 2 deletions src/libs/antares/study/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ set(SRC_STUDY_PART_SHORT_TERM_STORAGE
parts/short-term-storage/series.cpp
include/antares/study/parts/short-term-storage/series.h
include/antares/study/parts/short-term-storage/cluster.h
include/antares/study/parts/short-term-storage/AdditionalConstraint.h
include/antares/study/parts/short-term-storage/AdditionalConstraints.h
parts/short-term-storage/cluster.cpp
parts/short-term-storage/AdditionalConstraint.cpp
parts/short-term-storage/AdditionalConstraints.cpp
)
source_group("study\\part\\short-term-storage" FILES ${SRC_STUDY_PART_SHORT_TERM_SOTRAGE})

Expand Down
10 changes: 6 additions & 4 deletions src/libs/antares/study/area/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,12 +1194,14 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options)

if (fs::exists(stsFolder))
{
for (const auto& [id, area]: areas)
for (const auto& area: areas | std::views::values)
{
fs::path folder = stsFolder / "clusters" / area->id.c_str();
fs::path cluster_folder = stsFolder / "clusters" / area->id.c_str();
ret = area->shortTermStorage.createSTStorageClustersFromIniFile(cluster_folder) &&
ret;

ret = area->shortTermStorage.createSTStorageClustersFromIniFile(folder) && ret;
ret = area->shortTermStorage.LoadConstraintsFromIniFile(folder) && ret;
const auto constraints_folder = stsFolder / "constraints" / area->id.c_str();
ret = area->shortTermStorage.LoadConstraintsFromIniFile(constraints_folder) && ret;
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,30 @@
#pragma once
#include <set>
#include <string>
#include <vector>

namespace Antares::Data::ShortTermStorage
{
struct SingleAdditionalConstraint
{
std::set<int> hours;
unsigned int globalIndex = 0;
unsigned int localIndex = 0;

bool isValidHoursRange() const;
};

struct AdditionalConstraint
struct AdditionalConstraints
{
std::string name;
std::string cluster_id;
std::string variable;
std::string operatorType;
std::set<int> hours;
double rhs;
// TODO a lot unused entries
//std::array<double, HOURS_PER_YEAR> rhs = {};
std::vector<double> rhs = {};

unsigned int globalIndex = 0;
std::vector<SingleAdditionalConstraint> constraints = {};
payetvin marked this conversation as resolved.
Show resolved Hide resolved

struct ValidateResult
{
Expand All @@ -48,6 +58,7 @@ struct AdditionalConstraint
private:
bool isValidVariable() const;
bool isValidOperatorType() const;
bool isValidHoursRange() const;

bool isValidHours() const;
};
} // namespace Antares::Data::ShortTermStorage
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

#include <antares/inifile/inifile.h>

#include "AdditionalConstraint.h"
#include "AdditionalConstraints.h"
#include "properties.h"
#include "series.h"

Expand All @@ -51,6 +51,6 @@ class STStorageCluster

std::shared_ptr<Series> series = std::make_shared<Series>();
mutable Properties properties;
std::vector<AdditionalConstraint> additional_constraints;
std::vector<AdditionalConstraints> additional_constraints;
};
} // namespace Antares::Data::ShortTermStorage
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <filesystem>
#include <string>

#include "AdditionalConstraint.h"
#include "cluster.h"

namespace Antares::Data::ShortTermStorage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ class Series

bool loadFile(const std::filesystem::path& folder, std::vector<double>& vect);
bool writeVectorToFile(const std::string& path, const std::vector<double>& vect);

void fillIfEmpty(std::vector<double>& v, double value);
} // namespace Antares::Data::ShortTermStorage
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
** 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/>.
*/
#include "antares/study/parts/short-term-storage/AdditionalConstraint.h"
#include "antares/study/parts/short-term-storage/AdditionalConstraints.h"
#include <algorithm>

namespace Antares::Data::ShortTermStorage
{
AdditionalConstraint::ValidateResult AdditionalConstraint::validate() const
AdditionalConstraints::ValidateResult AdditionalConstraints::validate() const
flomnes marked this conversation as resolved.
Show resolved Hide resolved
{
if (cluster_id.empty())
{
Expand All @@ -39,26 +40,38 @@ AdditionalConstraint::ValidateResult AdditionalConstraint::validate() const
return {false, "Invalid operator type. Must be 'less', 'equal', or 'greater'."};
}

if (!isValidHoursRange())
if (!isValidHours())
{
return {false, "Hours set contains invalid values. Must be between 1 and 168."};
return {false, "Hours sets contains invalid values. Must be between 1 and 168."};
}

return {true, ""};
}

bool AdditionalConstraint::isValidHoursRange() const
bool SingleAdditionalConstraint::isValidHoursRange() const
{
// `hours` is a sorted set; begin() gives the smallest and prev(end()) gives the largest.
return !hours.empty() && *hours.begin() >= 1 && *std::prev(hours.end()) <= 168;
return !hours.empty() && *hours.begin()
>= 1 && *std::prev(
hours.end()) <= 168;
}

bool AdditionalConstraint::isValidVariable() const
bool AdditionalConstraints::isValidHours() const
{
return std::ranges::all_of(constraints.begin(),
payetvin marked this conversation as resolved.
Show resolved Hide resolved
constraints.end(),
[](const auto& constraint)
{
return constraint.isValidHoursRange();
});
}


bool AdditionalConstraints::isValidVariable() const
{
return variable == "injection" || variable == "withdrawal" || variable == "netting";
}

bool AdditionalConstraint::isValidOperatorType() const
bool AdditionalConstraints::isValidOperatorType() const
{
return operatorType == "less" || operatorType == "equal" || operatorType == "greater";
}
Expand Down
92 changes: 69 additions & 23 deletions src/libs/antares/study/parts/short-term-storage/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <algorithm>
#include <numeric>
#include <regex>
#include <string>

#include <yuni/io/file.h>
Expand Down Expand Up @@ -87,8 +88,8 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path)

for (auto* section = ini.firstSection; section; section = section->next)
{
AdditionalConstraint constraint;
constraint.name = section->name.c_str();
AdditionalConstraints additional_constraints;
guilpier-code marked this conversation as resolved.
Show resolved Hide resolved
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
additional_constraints.name = section->name.c_str();
for (auto* property = section->firstProperty; property; property = property->next)
{
const std::string key = property->key;
Expand All @@ -99,43 +100,77 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path)
// TODO do i have to transform the name to id? TransformNameIntoID
std::string clusterName;
value.to<std::string>(clusterName);
constraint.cluster_id = transformNameIntoID(clusterName);
additional_constraints.cluster_id = transformNameIntoID(clusterName);
}
else if (key == "variable")
{
value.to<std::string>(constraint.variable);
value.to<std::string>(additional_constraints.variable);
}
else if (key == "operator")
{
value.to<std::string>(constraint.operatorType);
value.to<std::string>(additional_constraints.operatorType);
}
else if (key == "hours")
{
std::stringstream ss(value.c_str());
std::string hour;
while (std::getline(ss, hour, ','))
//
// std::stringstream ss(value.c_str());
// std::string hour;
// while (std::getline(ss, hour, ','))
// {
// int hourVal = std::stoi(hour);
// constraint.hours.insert(hourVal);
// }
a-zakir marked this conversation as resolved.
Show resolved Hide resolved

// Split the `hours` field into multiple groups
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
std::string hoursStr = value.c_str();
std::regex groupRegex(R"(\[(.*?)\])");
// Match each group enclosed in square brackets
auto groupsBegin = std::sregex_iterator(hoursStr.begin(),
hoursStr.end(),
groupRegex);
auto groupsEnd = std::sregex_iterator();
unsigned int localIndex = 0;
for (auto it = groupsBegin; it != groupsEnd; ++it)
{
int hourVal = std::stoi(hour);
constraint.hours.insert(hourVal);
// Extract the contents of the square brackets
std::string group = (*it)[1].str();
std::stringstream ss(group);
std::string hour;
std::set<int> hourSet;

while (std::getline(ss, hour, ','))
{
int hourVal = std::stoi(hour);
hourSet.insert(hourVal);
}
if (!hourSet.empty())
{
// Add this group to the `hours` vec
additional_constraints.constraints.push_back(
{.hours = hourSet, .localIndex = localIndex});
++localIndex;
}
}
}
else if (key == "rhs")
{
property->value.to<double>(constraint.rhs);
}
}

if (auto ret = constraint.validate(); !ret.ok)
// try to read the rhs
loadFile(parent_path / ("rhs_" + additional_constraints.name + ".txt"),
additional_constraints.rhs);
fillIfEmpty(additional_constraints.rhs, 0.0);
a-zakir marked this conversation as resolved.
Show resolved Hide resolved

if (auto [ok, error_msg] = additional_constraints.validate(); !ok)
{
logs.error() << "Invalid constraint in section: " << section->name;
logs.error() << ret.error_msg;
logs.error() << error_msg;
return false;
}

auto it = std::find_if(storagesByIndex.begin(),
storagesByIndex.end(),
[&constraint](const STStorageCluster& cluster)
{ return cluster.id == constraint.cluster_id; });
auto it = std::ranges::find_if(storagesByIndex,
[&additional_constraints](const STStorageCluster& cluster)
{
return cluster.id == additional_constraints.cluster_id;
});
if (it == storagesByIndex.end())
{
logs.warning() << " from file " << pathIni;
Expand All @@ -145,7 +180,7 @@ bool STStorageInput::LoadConstraintsFromIniFile(const fs::path& parent_path)
}
else
{
it->additional_constraints.push_back(constraint);
it->additional_constraints.push_back(additional_constraints);
}
}

Expand Down Expand Up @@ -197,8 +232,19 @@ std::size_t STStorageInput::cumulativeConstraintCount() const
return std::accumulate(storagesByIndex.begin(),
storagesByIndex.end(),
0,
[](int acc, const auto& cluster)
{ return acc + cluster.additional_constraints.size(); });
[](size_t outer_constraint_count, const auto& cluster)
{
return outer_constraint_count + std::accumulate(
cluster.additional_constraints.begin(),
cluster.additional_constraints.end(),
0,
[](size_t inner_constraint_count,
const auto& additional_constraints)
{
return inner_constraint_count +
additional_constraints.constraints.size();
});
});
}

std::size_t STStorageInput::count() const
Expand Down
14 changes: 7 additions & 7 deletions src/libs/antares/study/parts/short-term-storage/series.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,16 @@ bool loadFile(const fs::path& path, std::vector<double>& vect)
return true;
}

void Series::fillDefaultSeriesIfEmpty()
void fillIfEmpty(std::vector<double>& v, double value)
{
auto fillIfEmpty = [](std::vector<double>& v, double value)
if (v.empty())
{
if (v.empty())
{
v.resize(HOURS_PER_YEAR, value);
}
};
v.resize(HOURS_PER_YEAR, value);
}
};

void Series::fillDefaultSeriesIfEmpty()
{
fillIfEmpty(maxInjectionModulation, 1.0);
fillIfEmpty(maxWithdrawalModulation, 1.0);
fillIfEmpty(inflows, 0.0);
Expand Down
35 changes: 20 additions & 15 deletions src/solver/optimisation/constraints/ShortTermStorageCumulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,33 @@ void ShortTermStorageCumulation::add(int pays)

for (const auto& storage: data.ShortTermStorage[pays])
{
for (const auto& constraint: storage.additional_constraints)
for (const auto& additional_constraints: storage.additional_constraints)
flomnes marked this conversation as resolved.
Show resolved Hide resolved
{
// sum (var[h]) sign rhs, h in list provided by user where:
// var = injection for InjectionCumulationConstraint
// var = withdrawal for WithdrawalCumulationConstraint
// var = injectionEfficiency * injection - withdrawalEfficiency * withdrawal for Netting
auto constraintHelper = cumulationConstraintFromVariable(constraint.variable);
namer.ShortTermStorageCumulation(constraintHelper->name(),
builder.data.nombreDeContraintes,
storage.name,
constraint.name);
const auto index = storage.clusterGlobalIndex;
data.CorrespondanceCntNativesCntOptimHebdomadaires
.ShortTermStorageCumulation[constraint.globalIndex]
= builder.data.nombreDeContraintes;

for (const auto& hour: constraint.hours)
auto constraintHelper = cumulationConstraintFromVariable(
additional_constraints.variable);
for (const auto& [hours, globalIndex, localIndex]: additional_constraints.constraints)
{
builder.updateHourWithinWeek(hour - 1);
constraintHelper->build(builder, index, storage);
namer.ShortTermStorageCumulation(
constraintHelper->name(),
builder.data.nombreDeContraintes,
storage.name,
additional_constraints.name + "_" + std::to_string(localIndex));
const auto index = storage.clusterGlobalIndex;
data.CorrespondanceCntNativesCntOptimHebdomadaires
.ShortTermStorageCumulation[globalIndex]
= builder.data.nombreDeContraintes;

for (const auto& hour: hours)
{
builder.updateHourWithinWeek(hour - 1);
constraintHelper->build(builder, index, storage);
}
builder.SetOperator(ConvertSense(additional_constraints.operatorType)).build();
}
builder.SetOperator(ConvertSense(constraint.operatorType)).build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,11 @@ int OPT_DecompteDesVariablesEtDesContraintesDuProblemeAOptimiser(PROBLEME_HEBDO*
}
if (!storage.additional_constraints.empty())
{
ProblemeAResoudre->NombreDeContraintes += storage.additional_constraints.size();
for (const auto& additional_constraints: storage.additional_constraints)
{
ProblemeAResoudre->NombreDeContraintes += additional_constraints.constraints
.size();
}
}
}
}
Expand Down
Loading
Loading