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

Fix binding constraint TS loading [ANT-2746] [ANT-2754] #2636

Merged
merged 38 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3d97d32
Add cluster even if disabled
payetvin Feb 11, 2025
5db3cff
Dont remove BC
payetvin Feb 12, 2025
485ec36
Return 0 if cluster not activated
payetvin Feb 12, 2025
8e3eaca
Save even if matrix is full of zeros
payetvin Feb 12, 2025
9cef830
format
payetvin Feb 12, 2025
877ea04
Ok if 1 column
payetvin Feb 14, 2025
1e3ba29
Remove ifEnabled
payetvin Feb 14, 2025
a319777
Merge branch 'develop' into fix/bc-save-develop
pet-mit Feb 17, 2025
1ad8f66
Add message to checkAllElementsIdenticalOrOne
payetvin Feb 17, 2025
efddda8
Merge branch 'fix/bc-save-develop' of https://github.com/AntaresSimul…
payetvin Feb 17, 2025
b140396
Use function for BC
payetvin Feb 17, 2025
ccb63fa
Fix compile
payetvin Feb 17, 2025
e308399
format
payetvin Feb 17, 2025
9460ac2
revert save zeros
payetvin Feb 17, 2025
8cffb84
re-add the func that only takes a vector
payetvin Feb 17, 2025
9b1768e
fix tests
payetvin Feb 17, 2025
f1b4199
Merge branch 'develop' into fix/bc-save-develop
payetvin Feb 18, 2025
8e00baa
Merge branch 'develop' into fix/bc-save-develop
payetvin Feb 19, 2025
1e03fc7
return a pair
payetvin Feb 19, 2025
f835580
Merge branch 'fix/bc-save-develop' of https://github.com/AntaresSimul…
payetvin Feb 19, 2025
85389ed
Return pair.first
payetvin Feb 20, 2025
11c2bd7
Use emplace back
payetvin Feb 20, 2025
0caf00b
Fix condition
payetvin Feb 20, 2025
1100570
Merge remote-tracking branch 'origin/develop' into fix/bc-save-develop
payetvin Feb 20, 2025
cc9feca
Fix function
payetvin Feb 20, 2025
ad3e7de
revert changes on data series
payetvin Feb 21, 2025
d643c7b
fix data series tests
payetvin Feb 21, 2025
d1d257b
format
payetvin Feb 21, 2025
daa12f1
revert change for cluster->isActive
payetvin Feb 21, 2025
e5245d6
Merge branch 'develop' into fix/bc-save-develop
payetvin Feb 21, 2025
edf8ad8
use erase_if
payetvin Feb 21, 2025
eca6c71
cosmetic changes
flomnes Feb 21, 2025
072f504
Merge remote-tracking branch 'github/develop' into fix/bc-save-develop
flomnes Feb 21, 2025
2c6ac3e
logic
flomnes Feb 21, 2025
ae57ec4
re try is Active
payetvin Feb 24, 2025
07c0b45
Fix function BindingConstraint::clusterCount
flomnes Feb 24, 2025
2d59ec9
Add unit test on BindingConstraint::clusterCount
flomnes Feb 24, 2025
aa53d76
Add tests on BindingConstraintGroupRepository::buildFrom
flomnes Feb 24, 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
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,16 @@ DataSeriesRepository DataSeriesRepoImporter::importFromDirectory(const std::file
throw std::invalid_argument("Not a directory: " + path.string());
}
using std::views::filter;
auto pathFilter = filter(static_cast<bool (*)(const fs::path&)>(&fs::is_regular_file))
| filter(&hasRightExtension);
auto pathFilter = filter(static_cast<bool (*)(const fs::path&)>(&fs::is_regular_file));

DataSeriesRepository repo{};
for (auto paths = std::filesystem::directory_iterator{path};
const auto& entry: paths | pathFilter)
{
if (!hasRightExtension(entry))
{
continue;
}
auto timeSeriesSet = std::make_unique<TimeSeriesSet>(importFromFile(entry, csvSeparators));
repo.addDataSeries(std::move(timeSeriesSet));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void BindingConstraint::weight(const AreaLink* lnk, double w)

void BindingConstraint::weight(const ThermalCluster* cluster, double w)
{
if (cluster && cluster->isActive())
if (cluster)
{
if (Utils::isZero(w))
{
Expand Down Expand Up @@ -221,7 +221,7 @@ void BindingConstraint::offset(const AreaLink* lnk, int o)

void BindingConstraint::offset(const ThermalCluster* cluster, int o)
{
if (cluster && cluster->isActive())
if (cluster)
{
if (Utils::isZero(o))
{
Expand Down Expand Up @@ -609,9 +609,9 @@ int BindingConstraint::offset(const AreaLink* lnk) const
return (i != pLinkOffsets.end()) ? i->second : 0;
}

int BindingConstraint::offset(const ThermalCluster* lnk) const
int BindingConstraint::offset(const ThermalCluster* cluster) const
{
auto i = pClusterOffsets.find(lnk);
auto i = pClusterOffsets.find(cluster);
return (i != pClusterOffsets.end()) ? i->second : 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>
#include <numeric>

#include <antares/utils/utils.h>
#include "antares/study/binding_constraint/BindingConstraintGroup.h"
#include "antares/study/binding_constraint/BindingConstraintsRepository.h"

Expand Down Expand Up @@ -69,23 +70,15 @@ bool BindingConstraintGroupRepository::timeSeriesWidthConsistentInGroups() const
{
return false;
}
auto width = (*constraints.begin())->RHSTimeSeries().width;
bool isConsistent = std::ranges::all_of(
constraints,
[&width](const std::shared_ptr<BindingConstraint>& bc)
{
bool sameWidth = bc->RHSTimeSeries().width == width;
if (!sameWidth)
{
logs.error() << "Inconsistent time series width for constraint of the same "
"group. Group at fault: "
<< bc->group() << " .Previous width was " << width
<< " new constraint " << bc->name() << " found with width of "
<< bc->RHSTimeSeries().width;
}
return sameWidth;
});
return !isConsistent;

std::vector<std::pair<unsigned, std::string>> constraintsWidth;
constraintsWidth.reserve(constraints.size());
for (const auto& c: constraints)
{
std::string msg = "Constraint group: " + c->group() + " name: " + c->name();
constraintsWidth.push_back({c->RHSTimeSeries().width, msg});
}
return Utils::checkAllElementsIdenticalOrOne(constraintsWidth);
});
return allConsistent;
}
Expand Down
3 changes: 3 additions & 0 deletions src/libs/antares/utils/include/antares/utils/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ double round(double d, unsigned precision);
double ceilDiv(double numerator, double denominator);
double floorDiv(double numerator, double denominator);

bool checkAllElementsIdenticalOrOne(std::vector<unsigned> w);
bool checkAllElementsIdenticalOrOne(std::vector<std::pair<unsigned, std::string>>& p);

} // namespace Utils
} // namespace Antares

Expand Down
24 changes: 24 additions & 0 deletions src/libs/antares/utils/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,29 @@ double floorDiv(double numerator, double denominator)
return std::floor(std::round(numerator / denominator * largeValue) / largeValue);
}

bool checkAllElementsIdenticalOrOne(std::vector<unsigned> w)
{
auto first_one = std::remove(w.begin(), w.end(), 1); // Reject all 1 to the end
return std::adjacent_find(w.begin(), first_one, std::not_equal_to<uint>()) == first_one;
}

bool checkAllElementsIdenticalOrOne(std::vector<std::pair<unsigned, std::string>>& p)
{
// Reject all 1 to the end
auto first_one = std::ranges::remove_if(p, [](const auto& pair) { return pair.first == 1; });
auto width = first_one.begin()->first;
return std::ranges::all_of(first_one,
[&width](const auto& pair)
{
if (pair.first != width)
{
logs.error()
<< "Inconsitent time series width, found: " << pair.first
<< " Previous was " << width << " for " << pair.second;
}
return true;
});
}

} // namespace Utils
} // namespace Antares
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ bool Generate(Data::Study& study);

void StoreTimeSeriesNumbersIntoOuput(Data::Study& study, IResultWriter& resultWriter);

// Exported for unit-tests
bool checkAllElementsIdenticalOrOne(std::vector<uint> w);

} // namespace Antares::Solver::TimeSeriesNumbers

#endif // __SOLVER_SIMULATION_GENERATE_TIMESERIES_H__
36 changes: 18 additions & 18 deletions src/solver/simulation/timeseries-numbers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,22 @@ class IntraModalConsistencyChecker
bool IntraModalConsistencyChecker::checkTSconsistency()
{
logs.info() << "Checking intra-modal correlation: " << tsTitle_;
std::vector<uint> listNumberTS;
std::vector<unsigned> listNumberTS;
for (auto i = study_.areas.begin(); i != study_.areas.end(); ++i)
{
const Area& area = *(i->second);
vector<uint> areaNumberTSList = tsCounter_->getAreaTimeSeriesNumber(area);
std::vector<unsigned> areaNumberTSList = tsCounter_->getAreaTimeSeriesNumber(area);
listNumberTS.insert(listNumberTS.end(), areaNumberTSList.begin(), areaNumberTSList.end());
}

if (!TimeSeriesNumbers::checkAllElementsIdenticalOrOne(listNumberTS))
if (!Utils::checkAllElementsIdenticalOrOne(listNumberTS))
{
logs.error() << "Intra-modal correlation: " << tsTitle_
<< "'s numbers of time-series are not equal for all areas";
return false;
}
// At this point, all elements are identical or 1
nbTimeseries_ = *(std::max_element(listNumberTS.begin(), listNumberTS.end()));
nbTimeseries_ = *(std::ranges::max_element(listNumberTS));

return true;
}
Expand Down Expand Up @@ -274,34 +274,38 @@ bool checkInterModalConsistencyForArea(const Area& area,
// 2. All elements of this list must be identical

// The list containing the numbers of TS of every "inter-modal" mode over the current area
std::vector<uint> listNumberTsOverArea;
std::vector<std::pair<unsigned, std::string>> listNumberTsOverArea;

// Load : Add load's number of TS in area ...
int indexTS = ts_to_tsIndex.at(timeSeriesLoad);
if (isTSintermodal[indexTS])
{
listNumberTsOverArea.push_back(area.load.series.timeSeries.width);
listNumberTsOverArea.push_back(
{area.load.series.timeSeries.width, "Area: " + area.name + " load"});
}

// Solar : Add solar's number of TS in area ...
indexTS = ts_to_tsIndex.at(timeSeriesSolar);
if (isTSintermodal[indexTS])
{
listNumberTsOverArea.push_back(area.solar.series.timeSeries.width);
listNumberTsOverArea.push_back(
{area.solar.series.timeSeries.width, "Area: " + area.name + " solar"});
}

// Wind : Add wind's number of TS in area ...
indexTS = ts_to_tsIndex.at(timeSeriesWind);
if (isTSintermodal[indexTS])
{
listNumberTsOverArea.push_back(area.wind.series.timeSeries.width);
listNumberTsOverArea.push_back(
{area.wind.series.timeSeries.width, "Area: " + area.name + " wind"});
}

// Hydro : Add hydro's number of TS in area ...
indexTS = ts_to_tsIndex.at(timeSeriesHydro);
if (isTSintermodal[indexTS])
{
listNumberTsOverArea.push_back(area.hydro.series->TScount());
listNumberTsOverArea.push_back(
{area.hydro.series->TScount(), "Area: " + area.name + " wind"});
}

// Thermal : Add thermal's number of TS of each cluster in area ...
Expand All @@ -310,7 +314,8 @@ bool checkInterModalConsistencyForArea(const Area& area,
{
for (auto& cluster: area.thermal.list.each_enabled())
{
listNumberTsOverArea.push_back(cluster->series.timeSeries.width);
std::string msg = "Area: " + area.name + " thermal cluster " + cluster->id();
listNumberTsOverArea.push_back({cluster->series.timeSeries.width, msg});
}
}

Expand All @@ -320,12 +325,13 @@ bool checkInterModalConsistencyForArea(const Area& area,
{
for (const auto& cluster: area.renewable.list.each_enabled())
{
listNumberTsOverArea.push_back(cluster->series.timeSeries.width);
std::string msg = "Area: " + area.name + " renew cluster " + cluster->id();
listNumberTsOverArea.push_back({cluster->series.timeSeries.width, msg});
}
}

// Now check if all elements of list of TS numbers are identical or equal to 1
if (!TimeSeriesNumbers::checkAllElementsIdenticalOrOne(listNumberTsOverArea))
if (!Utils::checkAllElementsIdenticalOrOne(listNumberTsOverArea))
{
logs.error()
<< "Inter-modal correlation: time-series numbers of inter-modal modes in area '"
Expand Down Expand Up @@ -680,12 +686,6 @@ static void applyMatrixDrawsToInterModalModesInArea(
}
}

bool TimeSeriesNumbers::checkAllElementsIdenticalOrOne(std::vector<uint> w)
{
auto first_one = std::remove(w.begin(), w.end(), 1); // Reject all 1 to the end
return std::adjacent_find(w.begin(), first_one, std::not_equal_to<uint>()) == first_one;
}

using Checks = std::vector<std::pair<const Antares::Data::TimeSeriesNumbers*, std::string>>;

static Checks buildChecksFromStudy(const AreaList& areas)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct CsvCreationFixture

CsvCreationFixture()
{
temp_path = filesystem::temp_directory_path() /= std::tmpnam(nullptr);
temp_path = filesystem::temp_directory_path();
filesystem::create_directories(temp_path);
}

Expand Down
30 changes: 20 additions & 10 deletions src/tests/src/solver/simulation/tests-ts-numbers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,36 +87,46 @@ std::shared_ptr<ClusterType> addClusterToArea(Area* area, const std::string& clu
BOOST_AUTO_TEST_CASE(test_compare_function_identical_values_OK)
{
using namespace Antares::Solver::TimeSeriesNumbers;
std::vector<uint> list = {4, 4, 4, 4};
BOOST_CHECK(checkAllElementsIdenticalOrOne(list));
std::vector<std::pair<unsigned, std::string>> list = {{4, ""}, {4, ""}, {4, ""}, {4, ""}};
BOOST_CHECK(Utils::checkAllElementsIdenticalOrOne(list));
}

BOOST_AUTO_TEST_CASE(test_compare_function_identical_values_and_one_OK)
{
using namespace Antares::Solver::TimeSeriesNumbers;
std::vector<uint> list = {4, 4, 4, 4, 1};
BOOST_CHECK(checkAllElementsIdenticalOrOne(list));
std::vector<std::pair<unsigned, std::string>> list = {{4, ""}, {4, ""}, {4, ""}, {1, ""}};
BOOST_CHECK(Utils::checkAllElementsIdenticalOrOne(list));
}

BOOST_AUTO_TEST_CASE(test_compare_function_one_and_identical_values_OK)
{
using namespace Antares::Solver::TimeSeriesNumbers;
std::vector<uint> list = {1, 4, 4, 4, 4};
BOOST_CHECK(checkAllElementsIdenticalOrOne(list));
std::vector<std::pair<unsigned, std::string>> list = {{1, ""}, {4, ""}, {4, ""}, {4, ""}};
BOOST_CHECK(Utils::checkAllElementsIdenticalOrOne(list));
}

BOOST_AUTO_TEST_CASE(test_compare_function_two_distinct_values_of_which_one_KO)
{
using namespace Antares::Solver::TimeSeriesNumbers;
std::vector<uint> list = {1, 2, 1, 1, 2, 1, 3};
BOOST_CHECK(!checkAllElementsIdenticalOrOne(list));
std::vector<std::pair<unsigned, std::string>> list = {{1, ""},
{2, ""},
{1, ""},
{2, ""},
{1, ""},
{3, ""}};
BOOST_CHECK(!Utils::checkAllElementsIdenticalOrOne(list));
}

BOOST_AUTO_TEST_CASE(test_compare_function_three_distinct_values_KO)
{
using namespace Antares::Solver::TimeSeriesNumbers;
std::vector<uint> list = {1, 2, 1, 3, 2};
BOOST_CHECK(!checkAllElementsIdenticalOrOne(list));
std::vector<std::pair<unsigned, std::string>> list = {{1, ""},
{2, ""},
{1, ""},
{3, ""},
{2, ""},
{1, ""}};
BOOST_CHECK(!Utils::checkAllElementsIdenticalOrOne(list));
}

BOOST_AUTO_TEST_CASE(two_areas_with_5_ready_made_ts_on_load___check_intra_modal_consistency_OK)
Expand Down
Loading