diff --git a/src/solver/simulation/hydro-remix-new.cpp b/src/solver/simulation/hydro-remix-new.cpp new file mode 100644 index 0000000000..e44edd813b --- /dev/null +++ b/src/solver/simulation/hydro-remix-new.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace Antares::Solver::Simulation +{ + +bool new_remix_hydro() +{ + return true; +} + +int find_min_index(const vector& G_plus_H, + const vector& new_D, + const vector& new_H, + const vector& tried_creux, + const vector& P_max, + double top) +{ + double min_val = top; + int min_idx = -1; + for (size_t i = 0; i < G_plus_H.size(); ++i) + { + if (new_D[i] > 0 && new_H[i] < P_max[i] && tried_creux[i] == 0) + { + if (G_plus_H[i] < min_val) + { + min_val = G_plus_H[i]; + min_idx = i; + } + } + } + return min_idx; +} + +int find_max_index(const vector& G_plus_H, + const vector& new_H, + const vector& tried_pic, + const vector& P_min, + double ref_value, + double eps) +{ + double max_val = 0; + int max_idx = -1; + for (size_t i = 0; i < G_plus_H.size(); ++i) + { + if (new_H[i] > P_min[i] && G_plus_H[i] >= ref_value + eps && tried_pic[i] == 0) + { + if (G_plus_H[i] > max_val) + { + max_val = G_plus_H[i]; + max_idx = i; + } + } + } + return max_idx; +} + +pair, vector> new_remix_hydro(const vector& G, + const vector& H, + const vector& D, + const vector& P_max, + const vector& P_min, + double initial_level, + double capa, + const vector& inflow) +{ + vector new_H = H; + vector new_D = D; + + int loop = 1000; + double eps = 1e-2; + double top = *max_element(G.begin(), G.end()) + *max_element(H.begin(), H.end()) + + *max_element(D.begin(), D.end()) + 1; + + vector G_plus_H(G.size()); + transform(G.begin(), G.end(), new_H.begin(), G_plus_H.begin(), plus<>()); + + vector level(G.size()); + level[0] = initial_level + inflow[0] - new_H[0]; + for (size_t i = 1; i < level.size(); ++i) + { + level[i] = level[i - 1] + inflow[i] - new_H[i]; + } + + while (loop-- > 0) + { + vector tried_creux(G.size(), 0); + double delta = 0; + + while (true) + { + int idx_creux = find_min_index(G_plus_H, new_D, new_H, tried_creux, P_max, top); + if (idx_creux == -1) + { + break; + } + + vector tried_pic(G.size(), 0); + while (true) + { + int idx_pic = find_max_index(G_plus_H, + new_H, + tried_pic, + P_min, + G_plus_H[idx_creux], + eps); + if (idx_pic == -1) + { + break; + } + + vector intermediate_level(level.begin() + min(idx_creux, idx_pic), + level.begin() + max(idx_creux, idx_pic)); + + double max_pic = min(new_H[idx_pic] - P_min[idx_pic], + capa + - *max_element(intermediate_level.begin(), + intermediate_level.end())); + double max_creux = min( + {P_max[idx_creux] - new_H[idx_creux], + new_D[idx_creux], + *min_element(intermediate_level.begin(), intermediate_level.end())}); + double dif_pic_creux = max(G_plus_H[idx_pic] - G_plus_H[idx_creux], 0.0); + + delta = max(min({max_pic, max_creux, dif_pic_creux / 2.0}), 0.0); + + if (delta > 0) + { + new_H[idx_pic] -= delta; + new_H[idx_creux] += delta; + new_D[idx_pic] = H[idx_pic] + D[idx_pic] - new_H[idx_pic]; + new_D[idx_creux] = H[idx_creux] + D[idx_creux] - new_H[idx_creux]; + break; + } + else + { + tried_pic[idx_pic] = 1; + } + } + + if (delta > 0) + { + break; + } + tried_creux[idx_creux] = 1; + } + + if (delta == 0) + { + break; + } + + transform(G.begin(), G.end(), new_H.begin(), G_plus_H.begin(), plus<>()); + level[0] = initial_level + inflow[0] - new_H[0]; + for (size_t i = 1; i < level.size(); ++i) + { + level[i] = level[i - 1] + inflow[i] - new_H[i]; + } + } + + return {new_H, new_D}; +} + +} // End namespace Antares::Solver::Simulation diff --git a/src/tests/src/solver/simulation/CMakeLists.txt b/src/tests/src/solver/simulation/CMakeLists.txt index 294005454b..10ef79b619 100644 --- a/src/tests/src/solver/simulation/CMakeLists.txt +++ b/src/tests/src/solver/simulation/CMakeLists.txt @@ -4,27 +4,27 @@ set(src_solver_hydro "${CMAKE_SOURCE_DIR}/solver/hydro") set(src_libs_antares_study "${CMAKE_SOURCE_DIR}/libs/antares/study") set(SRC_TS_NUMBERS - # For confort in IDE, but not necessary - ${src_solver_simulation}/include/antares/solver/simulation/timeseries-numbers.h - - # Necessary cpp files - ${src_solver_simulation}/timeseries-numbers.cpp - ${src_solver_simulation}/include/antares/solver/simulation/ITimeSeriesNumbersWriter.h) + # For confort in IDE, but not necessary + ${src_solver_simulation}/include/antares/solver/simulation/timeseries-numbers.h + + # Necessary cpp files + ${src_solver_simulation}/timeseries-numbers.cpp + ${src_solver_simulation}/include/antares/solver/simulation/ITimeSeriesNumbersWriter.h) add_executable(tests-ts-numbers tests-ts-numbers.cpp ${SRC_TS_NUMBERS}) target_include_directories(tests-ts-numbers - PRIVATE - "${src_solver_simulation}" - "${src_libs_antares_study}" + PRIVATE + "${src_solver_simulation}" + "${src_libs_antares_study}" ) target_link_libraries(tests-ts-numbers - PRIVATE - Antares::utils - Boost::unit_test_framework - model_antares - antares-solver-simulation - antares-solver-ts-generator + PRIVATE + Antares::utils + Boost::unit_test_framework + model_antares + antares-solver-simulation + antares-solver-ts-generator ) # Storing tests-ts-numbers under the folder Unit-tests in the IDE @@ -38,23 +38,23 @@ set_property(TEST ts-numbers PROPERTY LABELS unit) # Tests on area's store-timeseries-number # =================================== set(SRC_STORE_TS - test-store-timeseries-number.cpp - ) + test-store-timeseries-number.cpp +) add_executable(test-store-timeseries-number ${SRC_STORE_TS}) target_link_libraries(test-store-timeseries-number - PRIVATE - Boost::unit_test_framework + PRIVATE + Boost::unit_test_framework test_utils_unit - antares-solver-simulation - Antares::study - Antares::result_writer - ) + antares-solver-simulation + Antares::study + Antares::result_writer +) # Linux -if(UNIX AND NOT APPLE) - target_link_libraries(test-store-timeseries-number PRIVATE stdc++fs) -endif() +if (UNIX AND NOT APPLE) + target_link_libraries(test-store-timeseries-number PRIVATE stdc++fs) +endif () set_target_properties(test-store-timeseries-number PROPERTIES FOLDER Unit-tests) @@ -66,22 +66,22 @@ set_property(TEST store-timeseries-number PROPERTY LABELS unit) # Tests on time series # =================================== set(SRC_STORE_TS - test-time_series.cpp - ) + test-time_series.cpp +) add_executable(test-time_series ${SRC_STORE_TS}) target_link_libraries(test-time_series - PRIVATE - Boost::unit_test_framework + PRIVATE + Boost::unit_test_framework test_utils_unit - antares-solver-simulation - Antares::study - ) + antares-solver-simulation + Antares::study +) # Linux -if(UNIX AND NOT APPLE) - target_link_libraries(test-time_series PRIVATE stdc++fs) -endif() +if (UNIX AND NOT APPLE) + target_link_libraries(test-time_series PRIVATE stdc++fs) +endif () set_target_properties(test-time_series PROPERTIES FOLDER Unit-tests) @@ -97,26 +97,49 @@ set_property(TEST time_series PROPERTY LABELS unit) add_executable(test-hydro_final test-hydro-final-reservoir-level-functions.cpp) target_include_directories(test-hydro_final - PRIVATE - "${src_solver_simulation}" - "${src_libs_antares_study}" - "${src_solver_hydro}" + PRIVATE + "${src_solver_simulation}" + "${src_libs_antares_study}" + "${src_solver_hydro}" ) target_link_libraries(test-hydro_final - PRIVATE - Boost::unit_test_framework - Antares::study - antares-solver-simulation - Antares::array + PRIVATE + Boost::unit_test_framework + Antares::study + antares-solver-simulation + Antares::array ) # Linux -if(UNIX AND NOT APPLE) - target_link_libraries(test-hydro_final PRIVATE stdc++fs) -endif() +if (UNIX AND NOT APPLE) + target_link_libraries(test-hydro_final PRIVATE stdc++fs) +endif () set_target_properties(test-hydro_final PROPERTIES FOLDER Unit-tests) add_test(NAME hydro_final COMMAND test-hydro_final) -set_property(TEST hydro_final PROPERTY LABELS unit) \ No newline at end of file +set_property(TEST hydro_final PROPERTY LABELS unit) + + +# =================================== +# Tests on hydro remix algorithm +# =================================== +add_executable(test-hydro-remix + test-hydro-remix.cpp + ${src_solver_simulation}/hydro-remix-new.cpp +) + +target_link_libraries(test-hydro-remix + PRIVATE + Boost::unit_test_framework +) + +# gp : do we need this ? +if (UNIX AND NOT APPLE) + target_link_libraries(test-hydro_final PRIVATE stdc++fs) +endif () + +set_target_properties(test-hydro-remix PROPERTIES FOLDER Unit-tests) +add_test(NAME hydro_remix COMMAND test-hydro-remix) +set_property(TEST hydro_remix PROPERTY LABELS unit) \ No newline at end of file diff --git a/src/tests/src/solver/simulation/test-hydro-remix.cpp b/src/tests/src/solver/simulation/test-hydro-remix.cpp new file mode 100644 index 0000000000..4ca8773c4a --- /dev/null +++ b/src/tests/src/solver/simulation/test-hydro-remix.cpp @@ -0,0 +1,46 @@ +#define BOOST_TEST_MODULE hydro remix + +#define WIN32_LEAN_AND_MEAN + +#include + +#include + +namespace Antares::Solver::Simulation +{ +bool new_remix_hydro(); +std::pair, std::vector> new_remix_hydro( + const std::vector& G, + const std::vector& H, + const std::vector& D, + const std::vector& P_max, + const std::vector& P_min, + double initial_level, + double capa, + const std::vector& inflow); +} // namespace Antares::Solver::Simulation + +using namespace Antares::Solver::Simulation; +using namespace std; + +BOOST_AUTO_TEST_CASE(my_first_unit_test) +{ + BOOST_CHECK(new_remix_hydro()); +} + +BOOST_AUTO_TEST_CASE(my_second_unit_test) +{ + vector G = {1.0, 2.0, 3.0, 4.0, 5.0}; + vector H = {2.0, 3.0, 4.0, 5.0, 6.0}; + vector D = {1.0, 1.5, 2.0, 2.5, 3.0}; + vector P_max = {10.0, 10.0, 10.0, 10.0, 10.0}; + vector P_min = {0.0, 0.0, 0.0, 0.0, 0.0}; + double initial_level = 5.0; + double capa = 20.0; + vector inflow = {3.0, 3.0, 3.0, 3.0, 3.0}; + + // Call the function + auto [new_H, new_D] = new_remix_hydro(G, H, D, P_max, P_min, initial_level, capa, inflow); + + BOOST_CHECK(true); +}