From 6c2b437c12ff9b167d6a66ce0dc09906777385d4 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 7 Jun 2024 15:37:53 +0200 Subject: [PATCH 01/21] Add a validate function for hydro prepro --- src/libs/antares/study/area/list.cpp | 1 + .../antares/study/parts/hydro/prepro.h | 1 + src/libs/antares/study/parts/hydro/prepro.cpp | 91 +++++++++---------- 3 files changed, 43 insertions(+), 50 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index e7bd727287..1679440081 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -944,6 +944,7 @@ static bool AreaListLoadFromFolderSingleArea(Study& study, // if changes are required, please update reloadXCastData() buffer.clear() << study.folderInput << SEP << "hydro" << SEP << "prepro"; ret = area.hydro.prepro->loadFromFolder(study, area.id, buffer.c_str()) && ret; + ret = area.hydro.prepro->validate(area.id) && ret; } auto* hydroSeries = area.hydro.series; diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h index dbc015ecce..7a53da65d6 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h @@ -97,6 +97,7 @@ class PreproHydro */ bool loadFromFolder(Study& s, const AreaName& areaID, const char folder[]); + bool validate(const std::string& areaID) const; /*! ** \brief Save hydro settings for the prepro into a folder ** diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index d8ddb72352..6ff599c6d8 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -178,74 +178,65 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* f buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; ret = data.loadFromCSVFile(buffer, hydroPreproMax, 12, mtrxOption, &s.dataBuffer) && ret; - if (JIT::enabled) - { - return ret; - } + return ret; +} + +bool PreproHydro::validate(const std::string& areaID) const +{ + bool ret = true; - // Checks + const auto& col = data[powerOverWater]; + for (unsigned i = 0; i != data.height; ++i) { - auto& col = data[powerOverWater]; - for (uint i = 0; i != data.height; ++i) + const double d = col[i]; + if (d < 0. || d > 1.) { - const double d = col[i]; - if (d < 0. || d > 1.) - { - logs.error() << "Hydro: Prepro: " << areaID - << ": invalid value for ROR (line: " << (i + 1) << ")"; - } + logs.error() << "Hydro: Prepro: " << areaID + << ": invalid value for ROR (line: " << (i + 1) << ")"; } } - { - auto& colMin = data[minimumEnergy]; - auto& colMax = data[maximumEnergy]; + const auto& colMin = data[minimumEnergy]; + const auto& colMax = data[maximumEnergy]; - for (uint i = 0; i != data.height; ++i) + for (unsigned i = 0; i != data.height; ++i) + { + if (colMin[i] < 0.) { - if (colMin[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: minimum energy: At least one value is negative (line: " - << (i + 1) << ')'; - continue; - } - if (colMin[i] > colMax[i]) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: the minimum energy must be less than the maximum energy (line: " - << (i + 1) << ')'; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: minimum energy: At least one value is negative (line: " + << (i + 1) << ')'; + continue; + } + if (colMin[i] > colMax[i]) + { + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: the minimum energy must be less than the maximum energy (line: " + << (i + 1) << ')'; } } + const auto& colExp = data[expectation]; + for (unsigned i = 0; i != data.height; i++) { - auto& colExp = data[expectation]; - - for (uint i = 0; i != data.height; i++) + if (colExp[i] < 0.) { - if (colExp[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: invalid value for expectation (line: " << (i + 1) << ")"; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: invalid value for expectation (line: " << (i + 1) << ")"; } } + const auto& colStdDev = data[stdDeviation]; + for (unsigned i = 0; i != data.height; i++) { - auto& colStdDev = data[stdDeviation]; - - for (uint i = 0; i != data.height; i++) + if (colStdDev[i] < 0.) { - if (colStdDev[i] < 0.) - { - ret = false; - logs.error() << "Hydro: Prepro: `" << areaID - << "`: invalid value for standard deviation (line: " << (i + 1) << ")"; - } + ret = false; + logs.error() << "Hydro: Prepro: `" << areaID + << "`: invalid value for standard deviation (line: " << (i + 1) << ")"; } } From 76fe48827c2dee7098e21fc3b6ba04020a65c008 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Fri, 7 Jun 2024 15:59:01 +0200 Subject: [PATCH 02/21] Move more check to validate prepro hydro --- .../antares/study/parts/hydro/prepro.h | 4 +-- src/libs/antares/study/parts/hydro/prepro.cpp | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h index 7a53da65d6..b35798f862 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/prepro.h @@ -95,9 +95,9 @@ class PreproHydro ** \param folder The source folder (ex: `input/hydro/prepro`) ** \return A non-zero value if the operation succeeded, 0 otherwise */ - bool loadFromFolder(Study& s, const AreaName& areaID, const char folder[]); + bool loadFromFolder(Study& s, const AreaName& areaID, const std::string& folder); - bool validate(const std::string& areaID) const; + bool validate(const std::string& areaID); /*! ** \brief Save hydro settings for the prepro into a folder ** diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index 6ff599c6d8..53db16d875 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -145,11 +145,10 @@ bool PreproHydro::saveToFolder(const AreaName& areaID, const char* folder) return false; } -bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* folder) +bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::string& folder) { /* Asserts */ - assert(folder); - assert('\0' != *folder); + assert(!folder.empty()); enum { @@ -161,6 +160,17 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* f buffer.clear() << folder << SEP << areaID << SEP << "prepro.ini"; bool ret = PreproHydroLoadSettings(this, buffer); + + buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, 12, mtrxOption, &s.dataBuffer) && ret; + + return ret; +} + +bool PreproHydro::validate(const std::string& areaID) +{ + bool ret = true; + if (intermonthlyCorrelation < 0. || intermonthlyCorrelation > 1.) { logs.error() << "Hydro: Prepro: `" << areaID @@ -175,16 +185,6 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const char* f } } - buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, 12, mtrxOption, &s.dataBuffer) && ret; - - return ret; -} - -bool PreproHydro::validate(const std::string& areaID) const -{ - bool ret = true; - const auto& col = data[powerOverWater]; for (unsigned i = 0; i != data.height; ++i) { From f2b01b379d6dbc71ff4f733014ebead11f4b9b8b Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 10 Jun 2024 10:26:18 +0200 Subject: [PATCH 03/21] Add check hydro power --- .../parts/hydro/hydromaxtimeseriesreader.cpp | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp index b7864e5b31..f26ef89936 100644 --- a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp +++ b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp @@ -47,6 +47,24 @@ HydroMaxTimeSeriesReader::HydroMaxTimeSeriesReader(PartHydro& hydro, dailyMaxPumpAndGen.reset(4U, DAYS_PER_YEAR, true); } +static bool checkPower(const Matrix<>& dailyMaxPumpAndGen, const std::string& areaName) +{ + for (uint i = 0; i < 4U; ++i) + { + auto& col = dailyMaxPumpAndGen[i]; + for (uint day = 0; day < DAYS_PER_YEAR; ++day) + { + if (col[day] < 0. || (i % 2U /*column hours*/ && col[day] > 24.)) + { + logs.error() << areaName << ": invalid power or energy value"; + return false; + } + } + } + + return true; +} + bool HydroMaxTimeSeriesReader::loadDailyMaxPowersAndEnergies(const AnyString& folder, bool usedBySolver) { @@ -90,21 +108,8 @@ bool HydroMaxTimeSeriesReader::loadDailyMaxPowersAndEnergies(const AnyString& fo Matrix<>::optFixedSize, &fileContent) && ret; + ret = checkPower(dailyMaxPumpAndGen, areaName_) && ret; - bool errorPowers = false; - for (uint i = 0; i < 4U; ++i) - { - auto& col = dailyMaxPumpAndGen[i]; - for (uint day = 0; day < DAYS_PER_YEAR; ++day) - { - if (!errorPowers && (col[day] < 0. || (i % 2U /*column hours*/ && col[day] > 24.))) - { - logs.error() << areaName_ << ": invalid power or energy value"; - errorPowers = true; - ret = false; - } - } - } } return ret; } From 6df0fd97373537ded13bb65146ebda974a6e1def Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 10 Jun 2024 16:05:55 +0200 Subject: [PATCH 04/21] Add function load Properties --- .../antares/study/parts/hydro/container.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index e86b32a568..9b8ef61afe 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -106,6 +106,34 @@ void PartHydro::reset() } } +using setProp = std::function; + +static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, setProp f) +{ + if (!property) + return false; + + bool ret = true; + + // Browse all properties + for (; property; property = property->next) + { + AreaName id = property->key; + id.toLower(); + + Area* area = study.areas.find(id); + if (area) + { + f(property, area->hydro); + } + else + { + logs.warning() << filename << ": `" << id << "`: Unknown area"; + } + } + return ret; +} + bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) { auto& buffer = study.bufferLoadingTS; @@ -402,6 +430,13 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) } } } + + auto setIntermonthlyBreakdown = [&ret](IniFile::Property* p, PartHydro& h){ + ret = p->value.to(h.intermonthlyBreakdown) && ret; + }; + + loadProperties(study, section->firstProperty, buffer, setIntermonthlyBreakdown); + if ((section = ini.find("follow load"))) { if ((property = section->firstProperty)) From 660372ccd745e9fb32f30668ba1d8194ec8790aa Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 10 Jun 2024 17:27:24 +0200 Subject: [PATCH 05/21] Use area instead of parthdyro, more prop --- .../antares/study/parts/hydro/container.cpp | 92 +++++-------------- 1 file changed, 22 insertions(+), 70 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 9b8ef61afe..29082e9c8c 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -106,9 +106,9 @@ void PartHydro::reset() } } -using setProp = std::function; +using setProperty = std::function; -static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, setProp f) +static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, setProperty funcToSetProperty) { if (!property) return false; @@ -124,7 +124,7 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: Area* area = study.areas.find(id); if (area) { - f(property, area->hydro); + funcToSetProperty(property, area); } else { @@ -276,34 +276,17 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) return false; } - const char* const sectionName = "inter-daily-breakdown"; - IniFile::Section* section; IniFile::Property* property; - if ((section = ini.find(sectionName))) + if ((section = ini.find("inter-daily-breakdown"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - Area* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.interDailyBreakdown) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.intermonthlyBreakdown) && ret; + }); } + if ((section = ini.find("intra-daily-modulation"))) { if ((property = section->firstProperty)) @@ -338,53 +321,21 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("reservoir"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.reservoirManagement) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.reservoirManagement) && ret; + }); } if ((section = ini.find("reservoir capacity"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.reservoirCapacity) && ret; + if (area->hydro.reservoirCapacity < 1e-6) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.reservoirCapacity) && ret; - if (area->hydro.reservoirCapacity < 1e-6) - { - logs.error() << area->id << ": Invalid reservoir capacity."; - area->hydro.reservoirCapacity = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << area->id << ": Invalid reservoir capacity."; + area->hydro.reservoirCapacity = 0.; } - } + }); } // Check on reservoir capacity (has to be done after reservoir management and capacity reading, @@ -431,11 +382,12 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) } } - auto setIntermonthlyBreakdown = [&ret](IniFile::Property* p, PartHydro& h){ - ret = p->value.to(h.intermonthlyBreakdown) && ret; - }; + /* auto setIntermonthlyBreakdown = [&ret](IniFile::Property* p, PartHydro& h){ */ + /* ret = p->value.to(h.intermonthlyBreakdown) && ret; */ + /* }; */ + + /* loadProperties(study, section->firstProperty, buffer, setIntermonthlyBreakdown); */ - loadProperties(study, section->firstProperty, buffer, setIntermonthlyBreakdown); if ((section = ini.find("follow load"))) { From c0b5a8c221c0f201149e6fea00a51f6d5f81a758 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 11 Jun 2024 11:13:37 +0200 Subject: [PATCH 06/21] Finish refactor load container hydro --- .../antares/study/parts/hydro/container.cpp | 329 ++++-------------- 1 file changed, 68 insertions(+), 261 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 29082e9c8c..17427d6795 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -289,34 +289,16 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("intra-daily-modulation"))) { - if ((property = section->firstProperty)) - { - AreaName id; - - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.intraDailyModulation) && ret; + if (area->hydro.intraDailyModulation < 1.) { - id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.intraDailyModulation) && ret; - if (area->hydro.intraDailyModulation < 1.) - { - logs.error() - << area->id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area->hydro.intraDailyModulation << " (truncated to 1)"; - area->hydro.intraDailyModulation = 1.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() + << area->id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area->hydro.intraDailyModulation << " (truncated to 1)"; + area->hydro.intraDailyModulation = 1.; } - } + }); } if ((section = ini.find("reservoir"))) @@ -356,256 +338,97 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("inter-monthly-breakdown"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.intermonthlyBreakdown) && ret; + if (area->hydro.intermonthlyBreakdown < 0) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.intermonthlyBreakdown) && ret; - if (area->hydro.intermonthlyBreakdown < 0) - { - logs.error() << area->id << ": Invalid intermonthly breakdown"; - area->hydro.intermonthlyBreakdown = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << area->id << ": Invalid intermonthly breakdown"; + area->hydro.intermonthlyBreakdown = 0.; } - } + }); } - /* auto setIntermonthlyBreakdown = [&ret](IniFile::Property* p, PartHydro& h){ */ - /* ret = p->value.to(h.intermonthlyBreakdown) && ret; */ - /* }; */ - - /* loadProperties(study, section->firstProperty, buffer, setIntermonthlyBreakdown); */ - - if ((section = ini.find("follow load"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.followLoadModulations) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.followLoadModulations) && ret; + }); } + if ((section = ini.find("use water"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useWaterValue) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.useWaterValue) && ret; + }); } + if ((section = ini.find("hard bounds"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.hardBoundsOnRuleCurves) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.hardBoundsOnRuleCurves) && ret; + }); } + if ((section = ini.find("use heuristic"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useHeuristicTarget) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.useHeuristicTarget) && ret; + }); } + if ((section = ini.find("power to level"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.powerToLevel) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.powerToLevel) && ret; + }); } + if ((section = ini.find("initialize reservoir date"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.initializeReservoirLevelDate) && ret; + if (area->hydro.initializeReservoirLevelDate < 0) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.initializeReservoirLevelDate) && ret; - if (area->hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area->id << ": Invalid initialize reservoir date"; - area->hydro.initializeReservoirLevelDate = 0; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << area->id << ": Invalid initialize reservoir date"; + area->hydro.initializeReservoirLevelDate = 0; } - } + }); } + // Leeways : use leeway bounds (upper and lower) if ((section = ini.find("use leeway"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) - { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.useLeeway) && ret; - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } - } - } + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.useLeeway) && ret; + }); } + if ((section = ini.find("leeway low"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.leewayLowerBound) && ret; + if (area->hydro.leewayLowerBound < 0.) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.leewayLowerBound) && ret; - if (area->hydro.leewayLowerBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area->hydro.leewayLowerBound; - area->hydro.leewayLowerBound = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() + << area->id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area->hydro.leewayLowerBound; + area->hydro.leewayLowerBound = 0.; } - } + }); } + if ((section = ini.find("leeway up"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.leewayUpperBound) && ret; + if (area->hydro.leewayUpperBound < 0.) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.leewayUpperBound) && ret; - if (area->hydro.leewayUpperBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area->hydro.leewayUpperBound; - area->hydro.leewayUpperBound = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() + << area->id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area->hydro.leewayUpperBound; + area->hydro.leewayUpperBound = 0.; } - } + }); } // they are too small (< 1e-6). We cannot allow these areas to have reservoir management = @@ -621,30 +444,14 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("pumping efficiency"))) { - if ((property = section->firstProperty)) - { - // Browse all properties - for (; property; property = property->next) + loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ + ret = p->value.to(area->hydro.pumpingEfficiency) && ret; + if (area->hydro.pumpingEfficiency < 0) { - AreaName id = property->key; - id.toLower(); - - auto* area = study.areas.find(id); - if (area) - { - ret = property->value.to(area->hydro.pumpingEfficiency) && ret; - if (area->hydro.pumpingEfficiency < 0) - { - logs.error() << area->id << ": Invalid pumping efficiency"; - area->hydro.pumpingEfficiency = 0.; - } - } - else - { - logs.warning() << buffer << ": `" << id << "`: Unknown area"; - } + logs.error() << area->id << ": Invalid pumping efficiency"; + area->hydro.pumpingEfficiency = 0.; } - } + }); } study.areas.each( From 5eebab1d1b1e8d1625f788543f83c6c1d496df62 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 11 Jun 2024 15:10:38 +0200 Subject: [PATCH 07/21] Move ret out of lambda --- .../antares/study/parts/hydro/container.cpp | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 17427d6795..68324ab29a 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -106,7 +106,7 @@ void PartHydro::reset() } } -using setProperty = std::function; +using setProperty = std::function; static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, setProperty funcToSetProperty) { @@ -124,7 +124,7 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: Area* area = study.areas.find(id); if (area) { - funcToSetProperty(property, area); + ret = funcToSetProperty(property, area) && ret; } else { @@ -277,20 +277,19 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) } IniFile::Section* section; - IniFile::Property* property; if ((section = ini.find("inter-daily-breakdown"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.intermonthlyBreakdown) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.intermonthlyBreakdown); + }) && ret; } if ((section = ini.find("intra-daily-modulation"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.intraDailyModulation) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.intraDailyModulation); if (area->hydro.intraDailyModulation < 1.) { logs.error() @@ -298,26 +297,26 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) << area->hydro.intraDailyModulation << " (truncated to 1)"; area->hydro.intraDailyModulation = 1.; } - }); + }) && ret; } if ((section = ini.find("reservoir"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.reservoirManagement) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.reservoirManagement); + }) && ret; } if ((section = ini.find("reservoir capacity"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.reservoirCapacity) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.reservoirCapacity); if (area->hydro.reservoirCapacity < 1e-6) { logs.error() << area->id << ": Invalid reservoir capacity."; area->hydro.reservoirCapacity = 0.; } - }); + }) && ret; } // Check on reservoir capacity (has to be done after reservoir management and capacity reading, @@ -338,75 +337,75 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("inter-monthly-breakdown"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.intermonthlyBreakdown) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.intermonthlyBreakdown); if (area->hydro.intermonthlyBreakdown < 0) { logs.error() << area->id << ": Invalid intermonthly breakdown"; area->hydro.intermonthlyBreakdown = 0.; } - }); + }) && ret; } if ((section = ini.find("follow load"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.followLoadModulations) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.followLoadModulations); + }) && ret; } if ((section = ini.find("use water"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.useWaterValue) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.useWaterValue); + }) && ret; } if ((section = ini.find("hard bounds"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.hardBoundsOnRuleCurves) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.hardBoundsOnRuleCurves); + }) && ret; } if ((section = ini.find("use heuristic"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.useHeuristicTarget) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.useHeuristicTarget); + }) && ret; } if ((section = ini.find("power to level"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.powerToLevel) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.powerToLevel); + }) && ret; } if ((section = ini.find("initialize reservoir date"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.initializeReservoirLevelDate) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.initializeReservoirLevelDate); if (area->hydro.initializeReservoirLevelDate < 0) { logs.error() << area->id << ": Invalid initialize reservoir date"; area->hydro.initializeReservoirLevelDate = 0; } - }); + }) && ret; } // Leeways : use leeway bounds (upper and lower) if ((section = ini.find("use leeway"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.useLeeway) && ret; - }); + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.useLeeway); + }) && ret; } if ((section = ini.find("leeway low"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.leewayLowerBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.leewayLowerBound); if (area->hydro.leewayLowerBound < 0.) { logs.error() @@ -414,13 +413,13 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) << area->hydro.leewayLowerBound; area->hydro.leewayLowerBound = 0.; } - }); + }) && ret; } if ((section = ini.find("leeway up"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.leewayUpperBound) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.leewayUpperBound); if (area->hydro.leewayUpperBound < 0.) { logs.error() @@ -428,7 +427,7 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) << area->hydro.leewayUpperBound; area->hydro.leewayUpperBound = 0.; } - }); + }) && ret; } // they are too small (< 1e-6). We cannot allow these areas to have reservoir management = @@ -444,14 +443,14 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("pumping efficiency"))) { - loadProperties(study, section->firstProperty, buffer, [&ret](IniFile::Property* p, Area* area){ - ret = p->value.to(area->hydro.pumpingEfficiency) && ret; + ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ + return p->value.to(area->hydro.pumpingEfficiency); if (area->hydro.pumpingEfficiency < 0) { logs.error() << area->id << ": Invalid pumping efficiency"; area->hydro.pumpingEfficiency = 0.; } - }); + }) && ret; } study.areas.each( From 70b3924556ef6eaaaa4e9121f0fe35c13b5057ac Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 11 Jun 2024 16:02:03 +0200 Subject: [PATCH 08/21] fix prop --- src/libs/antares/study/parts/hydro/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 68324ab29a..a2ddd40637 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -281,7 +281,7 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) if ((section = ini.find("inter-daily-breakdown"))) { ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.intermonthlyBreakdown); + return p->value.to(area->hydro.interDailyBreakdown); }) && ret; } From e6f453749962f943ec711f4237ef3f0fabf8ff61 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Tue, 11 Jun 2024 16:54:25 +0200 Subject: [PATCH 09/21] comments --- src/libs/antares/study/parts/hydro/prepro.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/prepro.cpp b/src/libs/antares/study/parts/hydro/prepro.cpp index 53db16d875..9370c562fa 100644 --- a/src/libs/antares/study/parts/hydro/prepro.cpp +++ b/src/libs/antares/study/parts/hydro/prepro.cpp @@ -147,13 +147,11 @@ bool PreproHydro::saveToFolder(const AreaName& areaID, const char* folder) bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::string& folder) { - /* Asserts */ - assert(!folder.empty()); - enum { mtrxOption = Matrix<>::optFixedSize | Matrix<>::optImmediate, }; + constexpr int maxNbOfLineToLoad = 12; data.resize(hydroPreproMax, 12, true); String& buffer = s.bufferLoadingTS; @@ -162,7 +160,7 @@ bool PreproHydro::loadFromFolder(Study& s, const AreaName& areaID, const std::st bool ret = PreproHydroLoadSettings(this, buffer); buffer.clear() << folder << SEP << areaID << SEP << "energy.txt"; - ret = data.loadFromCSVFile(buffer, hydroPreproMax, 12, mtrxOption, &s.dataBuffer) && ret; + ret = data.loadFromCSVFile(buffer, hydroPreproMax, maxNbOfLineToLoad, mtrxOption, &s.dataBuffer) && ret; return ret; } From 4c425285ac6bf6bc9decf3bdda9c3f9b15045822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Omn=C3=A8s?= Date: Wed, 12 Jun 2024 10:36:17 +0200 Subject: [PATCH 10/21] Use templated pointer-to-members instead of lambda-functions (#2157) Co-authored-by: Vincent Payet Co-authored-by: payetvin <113102157+payetvin@users.noreply.github.com> --- .../antares/study/parts/hydro/container.cpp | 175 +++++------------- 1 file changed, 42 insertions(+), 133 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index a2ddd40637..ddb6b093a4 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -108,13 +108,12 @@ void PartHydro::reset() using setProperty = std::function; -static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, setProperty funcToSetProperty) +template +static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, T PartHydro::*ptr) { if (!property) return false; - bool ret = true; - // Browse all properties for (; property; property = property->next) { @@ -124,14 +123,15 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: Area* area = study.areas.find(id); if (area) { - ret = funcToSetProperty(property, area) && ret; + return property->value.to(area->hydro.*ptr); } else { logs.warning() << filename << ": `" << id << "`: Unknown area"; + return false; } } - return ret; + return true; } bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) @@ -276,183 +276,92 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) return false; } - IniFile::Section* section; - - if ((section = ini.find("inter-daily-breakdown"))) + if (IniFile::Section* section = ini.find("inter-daily-breakdown")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.interDailyBreakdown); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::interDailyBreakdown) && ret; } - - if ((section = ini.find("intra-daily-modulation"))) + if (IniFile::Section* section = ini.find("intra-daily-modulation")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.intraDailyModulation); - if (area->hydro.intraDailyModulation < 1.) - { - logs.error() - << area->id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " - << area->hydro.intraDailyModulation << " (truncated to 1)"; - area->hydro.intraDailyModulation = 1.; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::intraDailyModulation) && ret; } - if ((section = ini.find("reservoir"))) + if (IniFile::Section* section = ini.find("reservoir")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.reservoirManagement); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirManagement) && ret; } - if ((section = ini.find("reservoir capacity"))) + if (IniFile::Section* section = ini.find("reservoir capacity")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.reservoirCapacity); - if (area->hydro.reservoirCapacity < 1e-6) - { - logs.error() << area->id << ": Invalid reservoir capacity."; - area->hydro.reservoirCapacity = 0.; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::reservoirCapacity) && ret; } - // Check on reservoir capacity (has to be done after reservoir management and capacity reading, - // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving - // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and - // capacity = 0 because of further division by capacity. reservoir management = no and capacity - // = 0 is possible (no use of capacity further) - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false && ret; - } - }); - - if ((section = ini.find("inter-monthly-breakdown"))) + if (IniFile::Section* section = ini.find("follow load")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.intermonthlyBreakdown); - if (area->hydro.intermonthlyBreakdown < 0) - { - logs.error() << area->id << ": Invalid intermonthly breakdown"; - area->hydro.intermonthlyBreakdown = 0.; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::followLoadModulations) && ret; } - if ((section = ini.find("follow load"))) + if (IniFile::Section* section = ini.find("use water")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.followLoadModulations); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useWaterValue) && ret; } - if ((section = ini.find("use water"))) + if (IniFile::Section* section = ini.find("hard bounds")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.useWaterValue); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::hardBoundsOnRuleCurves) && ret; } - if ((section = ini.find("hard bounds"))) + if (IniFile::Section* section = ini.find("use heuristic")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.hardBoundsOnRuleCurves); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useHeuristicTarget) && ret; } - if ((section = ini.find("use heuristic"))) + if (IniFile::Section* section = ini.find("power to level")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.useHeuristicTarget); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::powerToLevel) && ret; } - if ((section = ini.find("power to level"))) + if (IniFile::Section* section = ini.find("initialize reservoir date")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.powerToLevel); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::initializeReservoirLevelDate) && ret; } - if ((section = ini.find("initialize reservoir date"))) + if (IniFile::Section* section = ini.find("use leeway")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.initializeReservoirLevelDate); - if (area->hydro.initializeReservoirLevelDate < 0) - { - logs.error() << area->id << ": Invalid initialize reservoir date"; - area->hydro.initializeReservoirLevelDate = 0; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::useLeeway) && ret; } - // Leeways : use leeway bounds (upper and lower) - if ((section = ini.find("use leeway"))) + if (IniFile::Section* section = ini.find("leeway low")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.useLeeway); - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayLowerBound) && ret; } - if ((section = ini.find("leeway low"))) + if (IniFile::Section* section = ini.find("leeway up")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.leewayLowerBound); - if (area->hydro.leewayLowerBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway lower bound. It must be >= 0.0, Got " - << area->hydro.leewayLowerBound; - area->hydro.leewayLowerBound = 0.; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::leewayUpperBound) && ret; } - if ((section = ini.find("leeway up"))) + if (IniFile::Section* section = ini.find("pumping efficiency")) { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.leewayUpperBound); - if (area->hydro.leewayUpperBound < 0.) - { - logs.error() - << area->id << ": Invalid leeway upper bound. It must be >= 0.0, Got " - << area->hydro.leewayUpperBound; - area->hydro.leewayUpperBound = 0.; - } - }) && ret; + ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; } - // they are too small (< 1e-6). We cannot allow these areas to have reservoir management = - // true. + // Check on reservoir capacity (has to be done after reservoir management and capacity reading, + // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving + // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and + // capacity = 0 because of further division by capacity. reservoir management = no and capacity + // = 0 is possible (no use of capacity further) study.areas.each( [&](Data::Area& area) { - if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) { - logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false && ret; } }); - if ((section = ini.find("pumping efficiency"))) - { - ret = loadProperties(study, section->firstProperty, buffer, [](IniFile::Property* p, Area* area){ - return p->value.to(area->hydro.pumpingEfficiency); - if (area->hydro.pumpingEfficiency < 0) - { - logs.error() << area->id << ": Invalid pumping efficiency"; - area->hydro.pumpingEfficiency = 0.; - } - }) && ret; - } - study.areas.each( [&](Data::Area& area) { From 888fe91946daabb50cab80ee542ece9ef37e4cbd Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 11:08:37 +0200 Subject: [PATCH 11/21] Don't return on first prop --- src/libs/antares/study/parts/hydro/container.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index ddb6b093a4..6128316de7 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -114,6 +114,8 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: if (!property) return false; + ret = true; + // Browse all properties for (; property; property = property->next) { @@ -123,7 +125,7 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: Area* area = study.areas.find(id); if (area) { - return property->value.to(area->hydro.*ptr); + ret = property->value.to(area->hydro.*ptr) && ret; } else { @@ -131,7 +133,7 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: return false; } } - return true; + return ret; } bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) From 7f69b21ea89188df172eb0d8ea0fe978d1627580 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 11:08:55 +0200 Subject: [PATCH 12/21] fix compile --- src/libs/antares/study/parts/hydro/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 6128316de7..2b4bdb6136 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -114,7 +114,7 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: if (!property) return false; - ret = true; + bool ret = true; // Browse all properties for (; property; property = property->next) From 7233379bae4a431843e95471cb463b11b10097a0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 12:37:31 +0200 Subject: [PATCH 13/21] Add validate func to parthydro --- src/libs/antares/study/area/list.cpp | 1 + .../antares/study/parts/hydro/container.h | 10 +++- .../antares/study/parts/hydro/container.cpp | 59 ++++++++++--------- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/libs/antares/study/area/list.cpp b/src/libs/antares/study/area/list.cpp index 1679440081..417e60bae4 100644 --- a/src/libs/antares/study/area/list.cpp +++ b/src/libs/antares/study/area/list.cpp @@ -1161,6 +1161,7 @@ bool AreaList::loadFromFolder(const StudyLoadOptions& options) logs.info() << "Loading global hydro data..."; buffer.clear() << pStudy.folderInput << SEP << "hydro"; ret = PartHydro::LoadFromFolder(pStudy, buffer) && ret; + ret = PartHydro::validate(pStudy) && ret; } // Thermal data, specific to areas diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index 5d79c65d30..e4890bfdd2 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -52,7 +52,6 @@ class PartHydro pumpMod, }; -public: /*! ** \brief Load data for hydro container from a folder ** @@ -61,6 +60,13 @@ class PartHydro */ static bool LoadFromFolder(Study& study, const AnyString& folder); + /*! + ** \brief Check and validate the loaded datas + ** + ** \return A non-zero value if the operation succeeded, 0 otherwise + */ + static bool validate(Study& study); + /*! ** \brief Save data from several containers to a folder (except data for the prepro and *time-series) @@ -71,7 +77,6 @@ class PartHydro */ static bool SaveToFolder(const AreaList& areas, const AnyString& folder); -public: /*! ** \brief Default Constructor */ @@ -100,7 +105,6 @@ class PartHydro bool CheckDailyMaxEnergy(const AnyString& areaName); -public: //! Inter-daily breakdown (previously called Smoothing Factor or alpha) double interDailyBreakdown; //! Intra-daily modulation diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 2b4bdb6136..d75861a875 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -106,8 +106,6 @@ void PartHydro::reset() } } -using setProperty = std::function; - template static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, T PartHydro::*ptr) { @@ -136,6 +134,36 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: return ret; } +bool PartHydro::validate(Study& study) +{ + bool ret = true; + + // Check on reservoir capacity (has to be done after reservoir management and capacity reading, + // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving + // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and + // capacity = 0 because of further division by capacity. reservoir management = no and capacity + // = 0 is possible (no use of capacity further) + study.areas.each( + [&](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false && ret; + } + + if (not area.hydro.useHeuristicTarget && not area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false && ret; + } + }); + + return ret; +} + bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) { auto& buffer = study.bufferLoadingTS; @@ -348,33 +376,6 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) ret = loadProperties(study, section->firstProperty, buffer, &PartHydro::pumpingEfficiency) && ret; } - // Check on reservoir capacity (has to be done after reservoir management and capacity reading, - // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving - // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and - // capacity = 0 because of further division by capacity. reservoir management = no and capacity - // = 0 is possible (no use of capacity further) - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false && ret; - } - }); - - study.areas.each( - [&](Data::Area& area) - { - if (not area.hydro.useHeuristicTarget && not area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false && ret; - } - }); - return ret; } From 2fccc96a80081f7d6e06bf8f7d6f394699278478 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 12:39:23 +0200 Subject: [PATCH 14/21] Better syntax --- .../antares/study/parts/hydro/container.cpp | 65 ++++++++++--------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index d75861a875..3b4114d39a 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -107,7 +107,10 @@ void PartHydro::reset() } template -static bool loadProperties(Study& study, IniFile::Property* property, const std::string& filename, T PartHydro::*ptr) +static bool loadProperties(Study& study, + IniFile::Property* property, + const std::string& filename, + T PartHydro::*ptr) { if (!property) return false; @@ -134,36 +137,6 @@ static bool loadProperties(Study& study, IniFile::Property* property, const std: return ret; } -bool PartHydro::validate(Study& study) -{ - bool ret = true; - - // Check on reservoir capacity (has to be done after reservoir management and capacity reading, - // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving - // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and - // capacity = 0 because of further division by capacity. reservoir management = no and capacity - // = 0 is possible (no use of capacity further) - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false && ret; - } - - if (not area.hydro.useHeuristicTarget && not area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false && ret; - } - }); - - return ret; -} - bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) { auto& buffer = study.bufferLoadingTS; @@ -379,6 +352,36 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) return ret; } +bool PartHydro::validate(Study& study) +{ + bool ret = true; + + // Check on reservoir capacity (has to be done after reservoir management and capacity reading, + // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving + // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and + // capacity = 0 because of further division by capacity. reservoir management = no and capacity + // = 0 is possible (no use of capacity further) + study.areas.each( + [&](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; + } + + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } + }); + + return ret; +} + bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) { if (!folder) From 83131dbb47b4ea7a9815e29c80d4c7cd17898f17 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 14:10:56 +0200 Subject: [PATCH 15/21] indent --- .../antares/study/parts/hydro/container.cpp | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 3b4114d39a..799d727025 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -361,23 +361,31 @@ bool PartHydro::validate(Study& study) // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and // capacity = 0 because of further division by capacity. reservoir management = no and capacity // = 0 is possible (no use of capacity further) - study.areas.each( - [&](Data::Area& area) - { - if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) - { - logs.error() << area.name - << ": reservoir capacity not defined. Impossible to manage."; - ret = false; - } + study.areas.each([&ret](Data::Area& area) + { + if (area.hydro.reservoirCapacity < 1e-3 && area.hydro.reservoirManagement) + { + logs.error() << area.name + << ": reservoir capacity not defined. Impossible to manage."; + ret = false; + } - if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) - { - logs.error() << area.name - << " : use water value = no conflicts with use heuristic target = no"; - ret = false; - } - }); + if (!area.hydro.useHeuristicTarget && !area.hydro.useWaterValue) + { + logs.error() << area.name + << " : use water value = no conflicts with use heuristic target = no"; + ret = false; + } + + if (area.hydro.intraDailyModulation < 1.) + { + logs.error() + << area.id << ": Invalid intra-daily modulation. It must be >= 1.0, Got " + << area.hydro.intraDailyModulation << " (truncated to 1)"; + area.hydro.intraDailyModulation = 1.; + } + + }); return ret; } From 8806510fc8e7e9f958da9629da49a941b3914e88 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 14:14:24 +0200 Subject: [PATCH 16/21] move some validation --- .../antares/study/parts/hydro/container.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 799d727025..d78bf33fae 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -385,6 +385,45 @@ bool PartHydro::validate(Study& study) area.hydro.intraDailyModulation = 1.; } + if (area.hydro.reservoirCapacity < 1e-6) + { + logs.error() << area.id << ": Invalid reservoir capacity."; + area.hydro.reservoirCapacity = 0.; + } + + if (area.hydro.intermonthlyBreakdown < 0) + { + logs.error() << area.id << ": Invalid intermonthly breakdown"; + area.hydro.intermonthlyBreakdown = 0.; + } + + if (area.hydro.initializeReservoirLevelDate < 0) + { + logs.error() << area.id << ": Invalid initialize reservoir date"; + area.hydro.initializeReservoirLevelDate = 0; + } + + if (area.hydro.leewayLowerBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway lower bound. It must be >= 0.0, Got " + << area.hydro.leewayLowerBound; + area.hydro.leewayLowerBound = 0.; + } + + if (area.hydro.leewayUpperBound < 0.) + { + logs.error() + << area.id << ": Invalid leeway upper bound. It must be >= 0.0, Got " + << area.hydro.leewayUpperBound; + area.hydro.leewayUpperBound = 0.; + } + + if (area.hydro.pumpingEfficiency < 0) + { + logs.error() << area.id << ": Invalid pumping efficiency"; + area.hydro.pumpingEfficiency = 0.; + } }); return ret; From 67e74fe09503206b004478fa9d95875b1b5159fa Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 14:36:17 +0200 Subject: [PATCH 17/21] rest of validation --- .../antares/study/parts/hydro/container.cpp | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index d78bf33fae..09a7368533 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -231,46 +231,6 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) Matrix<>::optFixedSize, &study.dataBuffer) && ret; - - if (study.usedByTheSolver) - { - auto& col = area.hydro.inflowPattern[0]; - bool errorInflow = false; - for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) - { - if (col[day] < 0 && !errorInflow) - { - logs.error() << area.name << ": invalid inflow value"; - errorInflow = true; - ret = false; - } - } - bool errorLevels = false; - auto& colMin = area.hydro.reservoirLevel[minimum]; - auto& colAvg = area.hydro.reservoirLevel[average]; - auto& colMax = area.hydro.reservoirLevel[maximum]; - for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) - { - if (!errorLevels - && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] - || colAvg[day] > 100 || colMax[day] > 100)) - { - logs.error() << area.name << ": invalid reservoir level value"; - errorLevels = true; - ret = false; - } - } - - for (int i = 0; i < 101; i++) - { - if ((area.hydro.creditModulation[i][0] < 0) - || (area.hydro.creditModulation[i][1] < 0)) - { - logs.error() << area.name << ": invalid credit modulation value"; - ret = false; - } - } - } }); IniFile ini; @@ -356,6 +316,51 @@ bool PartHydro::validate(Study& study) { bool ret = true; + /* study.areas.each([&ret, &study](Data::Area& area) */ + for (const auto& [areaName, area] : study.areas) + { + if (!study.usedByTheSolver) + break; + + auto& col = area->hydro.inflowPattern[0]; + bool errorInflow = false; + for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) + { + if (col[day] < 0 && !errorInflow) + { + logs.error() << areaName << ": invalid inflow value"; + errorInflow = true; + ret = false; + } + } + bool errorLevels = false; + auto& colMin = area->hydro.reservoirLevel[minimum]; + auto& colAvg = area->hydro.reservoirLevel[average]; + auto& colMax = area->hydro.reservoirLevel[maximum]; + for (unsigned int day = 0; day < DAYS_PER_YEAR; day++) + { + if (!errorLevels + && (colMin[day] < 0 || colAvg[day] < 0 || colMin[day] > colMax[day] + || colAvg[day] > 100 || colMax[day] > 100)) + { + logs.error() << areaName << ": invalid reservoir level value"; + errorLevels = true; + ret = false; + } + } + + for (int i = 0; i < 101; i++) + { + if ((area->hydro.creditModulation[i][0] < 0) + || (area->hydro.creditModulation[i][1] < 0)) + { + logs.error() << areaName << ": invalid credit modulation value"; + ret = false; + } + } + }; + + // Check on reservoir capacity (has to be done after reservoir management and capacity reading, // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving // the study, because they are too small (< 1e-6). We cannot have reservoir management = yes and From 3c75a2617eddb282dc34994751f3954834f6058d Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Wed, 12 Jun 2024 16:19:25 +0200 Subject: [PATCH 18/21] Try fix non valid error --- src/libs/antares/study/parts/hydro/container.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 09a7368533..82a732bbb1 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -390,7 +390,7 @@ bool PartHydro::validate(Study& study) area.hydro.intraDailyModulation = 1.; } - if (area.hydro.reservoirCapacity < 1e-6) + if (area.hydro.reservoirCapacity < 0) { logs.error() << area.id << ": Invalid reservoir capacity."; area.hydro.reservoirCapacity = 0.; From f9a4f2eb695d9bdd3c6c49b4277fb869871f2fa1 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 13 Jun 2024 10:10:35 +0200 Subject: [PATCH 19/21] Move checkpower --- .../antares/study/parts/hydro/hydromaxtimeseriesreader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp index f26ef89936..fa2827fc88 100644 --- a/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp +++ b/src/libs/antares/study/parts/hydro/hydromaxtimeseriesreader.cpp @@ -108,8 +108,6 @@ bool HydroMaxTimeSeriesReader::loadDailyMaxPowersAndEnergies(const AnyString& fo Matrix<>::optFixedSize, &fileContent) && ret; - ret = checkPower(dailyMaxPumpAndGen, areaName_) && ret; - } return ret; } @@ -143,6 +141,7 @@ void HydroMaxTimeSeriesReader::copyDailyMaxPumpingEnergy() const bool HydroMaxTimeSeriesReader::read(const AnyString& folder, bool usedBySolver) { bool ret = loadDailyMaxPowersAndEnergies(folder, usedBySolver); + ret = checkPower(dailyMaxPumpAndGen, areaName_) && ret; copyDailyMaxEnergy(); hydro_.series->buildHourlyMaxPowerFromDailyTS(dailyMaxPumpAndGen[genMaxP], dailyMaxPumpAndGen[pumpMaxP]); From 4446cfed2d29a72dbace3081130bd193e4501ae0 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Thu, 13 Jun 2024 10:35:34 +0200 Subject: [PATCH 20/21] split validate in 2 functions --- .../antares/study/parts/hydro/container.h | 4 ++++ .../antares/study/parts/hydro/container.cpp | 19 +++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libs/antares/study/include/antares/study/parts/hydro/container.h b/src/libs/antares/study/include/antares/study/parts/hydro/container.h index e4890bfdd2..c19da3d2bc 100644 --- a/src/libs/antares/study/include/antares/study/parts/hydro/container.h +++ b/src/libs/antares/study/include/antares/study/parts/hydro/container.h @@ -165,6 +165,10 @@ class PartHydro Matrix dailyNbHoursAtGenPmax; Matrix dailyNbHoursAtPumpPmax; +private: + static bool checkReservoirLevels(const Study& study); + static bool checkProperties(Study& study); + }; // class PartHydro // Interpolates a water value from a table according to a level and a day. diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 82a732bbb1..7bee60a348 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -312,15 +312,14 @@ bool PartHydro::LoadFromFolder(Study& study, const AnyString& folder) return ret; } -bool PartHydro::validate(Study& study) +bool PartHydro::checkReservoirLevels(const Study& study) { bool ret = true; - /* study.areas.each([&ret, &study](Data::Area& area) */ for (const auto& [areaName, area] : study.areas) { if (!study.usedByTheSolver) - break; + return true; auto& col = area->hydro.inflowPattern[0]; bool errorInflow = false; @@ -358,8 +357,14 @@ bool PartHydro::validate(Study& study) ret = false; } } - }; + } + return ret; +} + +bool PartHydro::checkProperties(Study& study) +{ + bool ret = true; // Check on reservoir capacity (has to be done after reservoir management and capacity reading, // not before). Some areas reservoir capacities may not be printed in hydro ini file when saving @@ -434,6 +439,12 @@ bool PartHydro::validate(Study& study) return ret; } +bool PartHydro::validate(Study& study) +{ + bool ret = checkReservoirLevels(study); + return checkProperties(study) && ret; +} + bool PartHydro::SaveToFolder(const AreaList& areas, const AnyString& folder) { if (!folder) From 988fd79d3d82fe18897552a88140f270ed213223 Mon Sep 17 00:00:00 2001 From: Vincent Payet Date: Mon, 17 Jun 2024 12:55:50 +0200 Subject: [PATCH 21/21] leeway check --- src/libs/antares/study/parts/hydro/container.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/antares/study/parts/hydro/container.cpp b/src/libs/antares/study/parts/hydro/container.cpp index 7bee60a348..d5d2412f69 100644 --- a/src/libs/antares/study/parts/hydro/container.cpp +++ b/src/libs/antares/study/parts/hydro/container.cpp @@ -429,6 +429,11 @@ bool PartHydro::checkProperties(Study& study) area.hydro.leewayUpperBound = 0.; } + if (area.hydro.leewayLowerBound > area.hydro.leewayUpperBound) + { + logs.error() << area.id << ": Leeway lower bound greater than leeway upper bound."; + } + if (area.hydro.pumpingEfficiency < 0) { logs.error() << area.id << ": Invalid pumping efficiency";