From 2f4376794dcb3052af8f036ec6dcb6a4b73e018c Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Mon, 11 Dec 2023 13:53:45 +0100 Subject: [PATCH 1/7] Tentative clang 14 fix. --- include/heyoka/step_callback.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/heyoka/step_callback.hpp b/include/heyoka/step_callback.hpp index c9e1cbbd7..ea0e36490 100644 --- a/include/heyoka/step_callback.hpp +++ b/include/heyoka/step_callback.hpp @@ -95,7 +95,10 @@ struct HEYOKA_DLL_PUBLIC_INLINE_CLASS step_cb_ref_iface { template struct HEYOKA_DLL_PUBLIC_INLINE_CLASS step_cb_ifaceT { template - using type = tanuki::composite_wrap_interfaceT, pre_hook_wrap_t>::template type; + // NOTE: clang 14 requires typename here, hopefully it does + // not do any harm in other compilers. + using type = + typename tanuki::composite_wrap_interfaceT, pre_hook_wrap_t>::template type; }; // Configuration. From d252ca0d5650ba4ee67d9c211c6843330f8b6ba4 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Tue, 12 Dec 2023 11:31:16 +0100 Subject: [PATCH 2/7] Minor optimisations in dfloat for mppp::real. --- include/heyoka/detail/dfloat.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/heyoka/detail/dfloat.hpp b/include/heyoka/detail/dfloat.hpp index 988ebed07..3504775ce 100644 --- a/include/heyoka/detail/dfloat.hpp +++ b/include/heyoka/detail/dfloat.hpp @@ -103,7 +103,7 @@ inline std::pair eft_add_dekker(F a, F b) auto x = a + b; auto y = (a - x) + b; - return {x, y}; + return std::make_pair(std::move(x), std::move(y)); } // Error-free transformation of the sum of two floating point numbers. @@ -114,9 +114,9 @@ inline std::pair eft_add_knuth(F a, F b) { auto x = a + b; auto z = x - a; - auto y = (a - (x - z)) + (b - z); + auto y = (a - (x - z)) + (std::move(b) - z); - return {x, y}; + return std::make_pair(std::move(x), std::move(y)); } // Normalise a double-length float. @@ -124,7 +124,7 @@ inline std::pair eft_add_knuth(F a, F b) // https://github.com/fhajji/ntl/blob/6918e6b80336cee34f2131fcf71a58c72b931174/src/quad_float.cpp#L125 // NOTE: this is based on the error-free trasformation requiring abs(x.hi) >= abs(x.lo). template -inline dfloat normalise(const dfloat &x) +inline dfloat normalise(dfloat x) { // LCOV_EXCL_START #if !defined(NDEBUG) @@ -136,9 +136,9 @@ inline dfloat normalise(const dfloat &x) #endif // LCOV_EXCL_STOP - auto [u, v] = eft_add_dekker(x.hi, x.lo); + auto [u, v] = eft_add_dekker(std::move(x.hi), std::move(x.lo)); - return dfloat(u, v); + return dfloat(std::move(u), std::move(v)); } // NOTE: taken with minimal adaptations from NTL. @@ -161,7 +161,7 @@ inline dfloat operator+(const dfloat &a, const dfloat &b) auto [u, v] = eft_add_dekker(x_hi, y_hi + x_lo); std::tie(u, v) = eft_add_dekker(u, v + y_lo); - return dfloat(u, v); + return dfloat(std::move(u), std::move(v)); } // Subtraction. From f7c7349e20dd3bd070fe0554267ff26c0077d515 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Tue, 12 Dec 2023 11:31:43 +0100 Subject: [PATCH 3/7] Small doc tweak. --- doc/install.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/install.rst b/doc/install.rst index 230a1c1a9..47a7c7b63 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -7,9 +7,9 @@ Introduction ------------ heyoka is written in modern C++, and it requires a compiler able to understand -at least C++20. The library is regularly tested on -a continuous integration pipeline which currently includes several -compilers (GCC, Clang, MSVC) on several operating systems (Linux, OSX, Windows) +at least C++20. Specifically, heyoka currently targets GCC>=10, clang>=14 and MSVC>=2022. +The library is regularly tested on a continuous integration pipeline +which includes several operating systems (Linux, OSX, Windows) and several CPU architectures (x86-64, 64-bit ARM and 64-bit PowerPC). heyoka has the following **mandatory** dependencies: From b67864a34cbd801fc5cf26439d7610ba7edaf907 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Tue, 12 Dec 2023 13:47:26 +0100 Subject: [PATCH 4/7] propagate_grid() will now error out if the first point in the grid is different from the current time. --- src/taylor_00.cpp | 49 ++++++++++---- test/dfloat_time.cpp | 4 ++ test/step_callback.cpp | 5 +- test/taylor_adaptive.cpp | 78 ++++++++-------------- test/taylor_adaptive_batch.cpp | 117 +++++++++++++-------------------- test/taylor_adaptive_mp.cpp | 57 +++++++--------- 6 files changed, 139 insertions(+), 171 deletions(-) diff --git a/src/taylor_00.cpp b/src/taylor_00.cpp index 0e59db946..4298cf08c 100644 --- a/src/taylor_00.cpp +++ b/src/taylor_00.cpp @@ -1645,6 +1645,7 @@ taylor_adaptive::propagate_grid_impl(std::vector grid, std::size_t max_ste #if defined(HEYOKA_HAVE_REAL) + // Ensure all grid points have the correct precision for real. if constexpr (std::is_same_v) { for (auto &val : grid) { val.prec_round(this->get_prec()); @@ -1678,15 +1679,19 @@ taylor_adaptive::propagate_grid_impl(std::vector grid, std::size_t max_ste } } + // Require that the user provides a grid starting from the + // current integrator time, modulo the double-length correction. + if (m_time.hi != grid[0]) { + throw std::invalid_argument( + fmt::format("When invoking propagate_grid(), the first element of the time grid " + "must match the current time coordinate - however, the first element of the time grid has a " + "value of {}, while the current time coordinate is {}", + grid[0], m_time.hi)); + } + // Pre-allocate the return value. std::vector retval; - // LCOV_EXCL_START - if (get_dim() > std::numeric_limits::max() / grid.size()) { - throw std::overflow_error("Overflow detected in the creation of the return value of propagate_grid() in an " - "adaptive Taylor integrator"); - } - // LCOV_EXCL_STOP - retval.reserve(grid.size() * get_dim()); + retval.reserve(boost::safe_numerics::safe(grid.size()) * get_dim()); // Initial values for the counters // and the min/max abs of the integration @@ -1701,6 +1706,10 @@ taylor_adaptive::propagate_grid_impl(std::vector grid, std::size_t max_ste T min_h = detail::num_inf_like(max_delta_t), max_h = detail::num_zero_like(max_delta_t); // Propagate the system up to the first grid point. + // This is necessary in order to account for the fact + // that the user cannot pass as starting point in the grid + // a time coordinate which is *exactly* equal to m_time, + // due to the usage of a double-length representation. // NOTE: we pass write_tc = true because some grid // points after the first one might end up being // calculated via dense output *before* @@ -3572,17 +3581,25 @@ std::vector taylor_adaptive_batch::propagate_grid_impl(const std::vector retval; - // LCOV_EXCL_START - if (get_dim() > std::numeric_limits::max() / grid.size()) { - throw std::overflow_error("Overflow detected in the creation of the return value of propagate_grid() in an " - "adaptive Taylor integrator in batch mode"); - } - // LCOV_EXCL_STOP // NOTE: fill with NaNs, so that the missing entries // are signalled with NaN if we exit early. - retval.resize(grid.size() * get_dim(), std::numeric_limits::quiet_NaN()); + retval.resize(boost::safe_numerics::safe(grid.size()) * get_dim(), + std::numeric_limits::quiet_NaN()); // NOTE: this is a buffer of size m_batch_size // that is used in various places as temp storage. @@ -3590,6 +3607,10 @@ std::vector taylor_adaptive_batch::propagate_grid_impl(const std::vector(m_batch_size)); // Propagate the system up to the first batch of grid points. + // This is necessary in order to account for the fact + // that the user cannot pass as starting point in the grid + // a time coordinate which is *exactly* equal to m_time, + // due to the usage of a double-length representation. // NOTE: we pass write_tc = true because some grid // points after the first one might end up being // calculated via dense output *before* diff --git a/test/dfloat_time.cpp b/test/dfloat_time.cpp index beff5ab4c..a97edab3f 100644 --- a/test/dfloat_time.cpp +++ b/test/dfloat_time.cpp @@ -123,6 +123,7 @@ TEST_CASE("scalar test") const auto grid = std::vector{fp_t{1.}, fp_t{10.}, final_time}; + ta.propagate_until(fp_t{1.}); const auto out = std::get<4>(ta.propagate_grid(grid)); for (auto j = 0u; j < 3u; ++j) { @@ -147,6 +148,7 @@ TEST_CASE("scalar test") const auto grid = std::vector{fp_t{-1.}, fp_t{-10.}, -final_time}; + ta.propagate_until(fp_t{-1.}); const auto out = std::get<4>(ta.propagate_grid(grid)); for (auto j = 0u; j < 3u; ++j) { @@ -251,6 +253,7 @@ TEST_CASE("batch test") const auto grid = std::vector{fp_t{1.}, fp_t{2.}, fp_t{10.}, fp_t{20.}, fp_t(10000.), fp_t(11000.)}; + ta.propagate_until({fp_t{1.}, fp_t{2}}); const auto out = ta.propagate_grid(grid); for (auto j = 0u; j < 3u; ++j) { @@ -281,6 +284,7 @@ TEST_CASE("batch test") const auto grid = std::vector{fp_t{-1.}, fp_t{-2.}, fp_t{-10.}, fp_t{-20.}, fp_t(-10000.), fp_t(-11000.)}; + ta.propagate_until({fp_t{-1.}, fp_t{-2}}); const auto out = ta.propagate_grid(grid); for (auto j = 0u; j < 3u; ++j) { diff --git a/test/step_callback.cpp b/test/step_callback.cpp index 7ae23bcb4..1f395a416 100644 --- a/test/step_callback.cpp +++ b/test/step_callback.cpp @@ -438,7 +438,7 @@ TEST_CASE("step_callback pre_hook") REQUIRE(ta0.get_pars()[0] == 1.5); REQUIRE_THROWS_MATCHES( - ta0.propagate_grid({3., 4.}, kw::callback = tm_cb{}), std::runtime_error, + ta0.propagate_grid({ta0.get_time(), ta0.get_time() + 1}, kw::callback = tm_cb{}), std::runtime_error, Message("The invocation of the callback passed to propagate_grid() resulted in the alteration of the " "time coordinate of the integrator - this is not supported")); } @@ -479,7 +479,8 @@ TEST_CASE("step_callback pre_hook") REQUIRE(ta0.get_pars()[1] == 1.5); REQUIRE_THROWS_MATCHES( - ta0.propagate_grid({3., 3., 4., 4.}, kw::callback = tm_cb{}), std::runtime_error, + ta0.propagate_grid({ta0.get_time()[0], ta0.get_time()[1], 4., 4.}, kw::callback = tm_cb{}), + std::runtime_error, Message("The invocation of the callback passed to propagate_grid() resulted in the alteration of the " "time coordinate of the integrator - this is not supported")); } diff --git a/test/taylor_adaptive.cpp b/test/taylor_adaptive.cpp index 5b605e5f7..9ad78c67b 100644 --- a/test/taylor_adaptive.cpp +++ b/test/taylor_adaptive.cpp @@ -163,11 +163,16 @@ TEST_CASE("propagate grid scalar") REQUIRE_THROWS_MATCHES( ta.propagate_grid({0., 1., 2., 2.}), std::invalid_argument, Message("A non-monotonic time grid was passed to propagate_grid() in an adaptive Taylor integrator")); + REQUIRE_THROWS_MATCHES( + ta.propagate_grid({1.}), std::invalid_argument, + Message("When invoking propagate_grid(), the first element of the time grid " + "must match the current time coordinate - however, the first element of the time grid has a " + "value of 1, while the current time coordinate is 0")); // Set an infinity in the state. ta.get_state_data()[0] = std::numeric_limits::infinity(); - auto out = ta.propagate_grid({.2}); + auto out = ta.propagate_grid({ta.get_time(), .2}); REQUIRE(std::get<0>(out) == taylor_outcome::err_nf_state); REQUIRE(std::get<4>(out).empty()); @@ -210,20 +215,22 @@ TEST_CASE("propagate grid scalar") ta.set_time(10.); ta.get_state_data()[0] = std::sin(10.); ta.get_state_data()[1] = std::cos(10.); + grid.push_back(10.); std::reverse(grid.begin(), grid.end()); out = ta.propagate_grid(grid); REQUIRE(std::get<0>(out) == taylor_outcome::time_limit); - REQUIRE(std::get<4>(out).size() == 2000u); + REQUIRE(std::get<4>(out).size() == grid.size() * 2u); REQUIRE(ta.get_time() == grid.back()); - for (auto i = 0u; i < 1000u; ++i) { + for (auto i = 0u; i < grid.size(); ++i) { REQUIRE(std::get<4>(out)[2u * i] == approximately(std::sin(grid[i]), 10000.)); REQUIRE(std::get<4>(out)[2u * i + 1u] == approximately(std::cos(grid[i]), 10000.)); } // Random testing. + grid.resize(1000u); ta.set_time(0.); ta.get_state_data()[0] = 0.; ta.get_state_data()[1] = 1.; @@ -270,32 +277,18 @@ TEST_CASE("propagate grid scalar") // A test with a sparse grid. ta = taylor_adaptive{{prime(x) = v, prime(v) = -x}, {0., 1.}}; - out = ta.propagate_grid({.1, 10., 100.}); + out = ta.propagate_grid({0., 0.1, 10., 100.}); - REQUIRE(std::get<4>(out).size() == 6u); + REQUIRE(std::get<4>(out).size() == 8u); REQUIRE(ta.get_time() == 100.); - REQUIRE(std::get<4>(out)[0] == approximately(std::sin(.1), 100.)); - REQUIRE(std::get<4>(out)[1] == approximately(std::cos(.1), 100.)); - REQUIRE(std::get<4>(out)[2] == approximately(std::sin(10.), 100.)); - REQUIRE(std::get<4>(out)[3] == approximately(std::cos(10.), 100.)); - REQUIRE(std::get<4>(out)[4] == approximately(std::sin(100.), 1000.)); - REQUIRE(std::get<4>(out)[5] == approximately(std::cos(100.), 1000.)); - - // A case in which the initial propagate_until() to bring the system - // to grid[0] interrupts the integration. - ta = taylor_adaptive{{prime(x) = v, prime(v) = -x}, {0., 1.}, kw::t_events = {t_event(v - 0.999)}}; - out = ta.propagate_grid({10., 100.}); - REQUIRE(std::get<0>(out) == taylor_outcome{-1}); - REQUIRE(std::get<4>(out).empty()); - - ta = taylor_adaptive{ - {prime(x) = v, prime(v) = -x}, - {0., 1.}, - kw::t_events = {t_event( - v - 0.999, kw::callback = [](taylor_adaptive &, bool, int) { return false; })}}; - out = ta.propagate_grid({10., 100.}); - REQUIRE(std::get<0>(out) == taylor_outcome{-1}); - REQUIRE(std::get<4>(out).empty()); + REQUIRE(std::get<4>(out)[0] == approximately(std::sin(.0), 100.)); + REQUIRE(std::get<4>(out)[1] == approximately(std::cos(.0), 100.)); + REQUIRE(std::get<4>(out)[2] == approximately(std::sin(.1), 100.)); + REQUIRE(std::get<4>(out)[3] == approximately(std::cos(.1), 100.)); + REQUIRE(std::get<4>(out)[4] == approximately(std::sin(10.), 100.)); + REQUIRE(std::get<4>(out)[5] == approximately(std::cos(10.), 100.)); + REQUIRE(std::get<4>(out)[6] == approximately(std::sin(100.), 1000.)); + REQUIRE(std::get<4>(out)[7] == approximately(std::cos(100.), 1000.)); // A case in which we have a callback which never stops and a terminal event // which triggers. @@ -1037,7 +1030,7 @@ TEST_CASE("propagate trivial") REQUIRE(std::get<0>(ta.propagate_for(1.2)) == taylor_outcome::time_limit); REQUIRE(std::get<0>(ta.propagate_until(2.3)) == taylor_outcome::time_limit); - REQUIRE(std::get<0>(ta.propagate_grid({3, 4, 5, 6, 7.})) == taylor_outcome::time_limit); + REQUIRE(std::get<0>(ta.propagate_grid({2.3, 3, 4, 5, 6, 7.})) == taylor_outcome::time_limit); } struct cb_functor_until { @@ -1271,44 +1264,26 @@ TEST_CASE("propagate grid") auto counter = 0ul; auto [oc, _1, _2, _3, out] = ta.propagate_grid( - {1., 5., 10.}, kw::max_delta_t = 1e-4, kw::callback = [&counter](taylor_adaptive &) { + {0., 1., 5., 10.}, kw::max_delta_t = 1e-4, kw::callback = [&counter](taylor_adaptive &) { ++counter; return true; }); - auto [oc_copy, _4, _5, _6, out_copy] = ta_copy.propagate_grid({1., 5., 10.}); REQUIRE(ta.get_time() == 10.); - REQUIRE(counter == 90000ul); + REQUIRE(counter == 100000ul); REQUIRE(oc == taylor_outcome::time_limit); - REQUIRE(ta_copy.get_time() == 10.); - REQUIRE(oc_copy == taylor_outcome::time_limit); - - for (auto i = 0u; i < 3u; ++i) { - REQUIRE(out[2u * i] == approximately(out_copy[2u * i], 1000.)); - REQUIRE(out[2u * i + 1u] == approximately(out_copy[2u * i + 1u], 1000.)); - } - // Backwards. std::tie(oc, _1, _2, _3, out) = ta.propagate_grid( {10., 5., 1.}, kw::max_delta_t = 1e-4, kw::callback = [&counter](taylor_adaptive &) { ++counter; return true; }); - std::tie(oc_copy, _4, _5, _6, out_copy) = ta_copy.propagate_grid({10., 5., 1.}); REQUIRE(ta.get_time() == 1); - REQUIRE(counter == 180000ul); + REQUIRE(counter == 190000ul); REQUIRE(oc == taylor_outcome::time_limit); - REQUIRE(ta_copy.get_time() == 1); - REQUIRE(oc_copy == taylor_outcome::time_limit); - - for (auto i = 0u; i < 3u; ++i) { - REQUIRE(out[2u * i] == approximately(out_copy[2u * i], 1000.)); - REQUIRE(out[2u * i + 1u] == approximately(out_copy[2u * i + 1u], 1000.)); - } - // Test the callback is not copied if it is already a step_callback. step_callback f_cb_grid(cb_functor_grid{}); f_cb_grid.extract()->n_copies_after = f_cb_grid.extract()->n_copies; @@ -1470,6 +1445,7 @@ TEST_CASE("cb interrupt") // propagate_grid(). { + ta.set_time(10.); auto res = ta.propagate_grid( {10., 11., 12.}, kw::callback = [](auto &) { return false; }); @@ -1479,6 +1455,7 @@ TEST_CASE("cb interrupt") REQUIRE(ta.get_time() < 11.); auto counter = 0u; + ta.set_dtime(11., 1e-16); res = ta.propagate_grid( {11., 12., 13., 14, 15, 16, 17, 18, 19}, kw::callback = [&counter](auto &) { return counter++ != 5u; }); @@ -1489,6 +1466,7 @@ TEST_CASE("cb interrupt") // Check that stopping via cb still processes the grid points // within the last taken step. + ta.propagate_until(11.); res = ta.propagate_grid( {11., 11. + 1e-6, 11. + 2e-6, 12., 13., 14, 15, 16, 17, 18, 19}, kw::callback = [](auto &) { return false; }); @@ -1958,6 +1936,8 @@ TEST_CASE("propagate_grid tc issue") auto ta = taylor_adaptive({prime(x) = v, prime(v) = -x}, {0., 1}); + ta.propagate_until(-.5); + ta.set_dtime(-.5, -1e-20); std::vector t_grid = {-.5, -.4999, .1, .2}; auto [oc, _1, _2, _3, out] = ta.propagate_grid(t_grid); diff --git a/test/taylor_adaptive_batch.cpp b/test/taylor_adaptive_batch.cpp index 1e8d10d3d..79de8e3c1 100644 --- a/test/taylor_adaptive_batch.cpp +++ b/test/taylor_adaptive_batch.cpp @@ -165,6 +165,12 @@ TEST_CASE("propagate grid") ta.propagate_grid({1., 2., 3., 4., 5.}), std::invalid_argument, Message("Invalid grid size detected in propagate_grid() for an adaptive Taylor integrator in batch mode: " "the grid has a size of 5, which is not a multiple of the batch size (4)")); + REQUIRE_THROWS_MATCHES( + ta.propagate_grid({0., 0., 1., 4.}), std::invalid_argument, + Message("When invoking propagate_grid(), the first element of the time grid " + "must match the current time coordinate - however, the first element of the time grid at " + "batch index 2 has a " + "value of 1, while the current time coordinate is 0")); ta.set_time({0., 0., std::numeric_limits::infinity(), 0.}); @@ -209,7 +215,7 @@ TEST_CASE("propagate grid") // Set an infinity in the state. ta.get_state_data()[0] = std::numeric_limits::infinity(); - auto ret = ta.propagate_grid({.2, .2, .2, .2}); + auto ret = ta.propagate_grid({.0, .0, .0, .0}); REQUIRE(ret.size() == 8u); REQUIRE(std::get<0>(ta.get_propagate_res()[0]) == taylor_outcome::err_nf_state); REQUIRE(std::get<0>(ta.get_propagate_res()[1]) == taylor_outcome::time_limit); @@ -241,7 +247,9 @@ TEST_CASE("propagate grid") for (auto i = 0u; i < 1000u; ++i) { for (auto j = 0; j < 4; ++j) { grid.push_back(i / 100.); - grid.back() += j / 10.; + if (i != 0u) { + grid.back() += j / 10.; + } } } @@ -267,7 +275,9 @@ TEST_CASE("propagate grid") for (auto i = 0u; i < 1000u; ++i) { for (auto j = 0; j < 4; ++j) { grid.push_back(i / -100.); - grid.back() += j / -10.; + if (i != 0u) { + grid.back() += j / -10.; + } } } @@ -339,47 +349,22 @@ TEST_CASE("propagate grid") } } - // A case in which the initial propagate_until() to bring the system - // to grid[0] interrupts the integration. - ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = -x}, - {0., 0.01, 0.02, 0.03, 1., 1.01, 1.02, 1.03}, - 4, - kw::t_events = {t_event_batch(v - 0.999)}}; - auto out = ta.propagate_grid({10., 10., 10., 10., 100., 100., 100., 100.}); - REQUIRE(out.size() == 16u); - REQUIRE(std::all_of(out.begin(), out.end(), [](const auto &vel) { return std::isnan(vel); })); - REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), - [](const auto &t) { return std::get<0>(t) == taylor_outcome{-1}; })); - - ta = taylor_adaptive_batch{ - {prime(x) = v, prime(v) = -x}, - {0., 0.01, 0.02, 0.03, 1., 1.01, 1.02, 1.03}, - 4, - kw::t_events = {t_event_batch( - v - 0.999, kw::callback = [](auto &, bool, int, std::uint32_t) { return false; })}, - }; - out = ta.propagate_grid({10., 10., 10., 10., 100., 100., 100., 100.}); - REQUIRE(out.size() == 16u); - REQUIRE(std::all_of(out.begin(), out.end(), [](const auto &vel) { return std::isnan(vel); })); - REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), - [](const auto &t) { return std::get<0>(t) == taylor_outcome{-1}; })); - // Test the callback is not copied if it is already a step_callback. ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = -x}, {0., 0.01, 0.02, 0.03, 1., 1.01, 1.02, 1.03}, 4}; step_callback_batch f_cb_grid(cb_functor_grid{}); f_cb_grid.extract()->n_copies_after = f_cb_grid.extract()->n_copies; - ta.propagate_grid({10., 10., 10., 10., 100., 100., 100., 100.}, kw::callback = f_cb_grid); + ta.propagate_grid({0., 0., 0., 0., 10., 10., 10., 10., 100., 100., 100., 100.}, kw::callback = f_cb_grid); // Callback attempts to change the time coordinate. ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = -x}, {0., 0.01, 0.02, 0.03, 1., 1.01, 1.02, 1.03}, 4}; REQUIRE_THROWS_MATCHES( ta.propagate_grid( - {10., 10., 10., 10., 100., 100., 100., 100.}, kw::callback = - [](auto &tint) { - tint.set_time(-100.); + {0., 0., 0., 0., 10., 10., 10., 10., 100., 100., 100., 100.}, kw::callback = + [](auto &tint) { + tint.set_time(-100.); - return true; - }), + return true; + }), std::runtime_error, Message("The invocation of the callback passed to propagate_grid() resulted in the alteration of the " "time coordinate of the integrator - this is not supported")); @@ -388,7 +373,7 @@ TEST_CASE("propagate grid") ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = -x}, {0., 0.01, 0.02, 0.03, 1., 1.01, 1.02, 1.03}, 4}; REQUIRE_THROWS_MATCHES( ta.propagate_grid( - {10., 10., 10., 10., 100., 100., 100., 100.}, + {0., 0., 0., 0., 10., 10., 10., 10., 100., 100., 100., 100.}, kw::callback = [](auto &tint) { tint.set_time({tint.get_time()[0], -100., tint.get_time()[2], tint.get_time()[3]}); @@ -416,7 +401,8 @@ TEST_CASE("propagate trivial") REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); - ta.propagate_grid({5, 6, 7, 8.}); + ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = 1_dbl}, {0, 0, 0.1, 0.1}, 2}; + ta.propagate_grid({0., 0., 5, 6, 7, 8.}); REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); } @@ -740,51 +726,29 @@ TEST_CASE("propagate grid 2") }; auto out - = ta.propagate_grid({1., 1.5, 5., 5.6, 10., 11.}, kw::max_delta_t = std::vector{1e-4, 5e-5}, kw::callback = cb); - auto out_copy = ta_copy.propagate_grid({1., 1.5, 5., 5.6, 10., 11.}); + = ta.propagate_grid({0., 0., 5., 5.6, 10., 11.}, kw::max_delta_t = std::vector{1e-4, 5e-5}, kw::callback = cb); REQUIRE(ta.get_time() == std::vector{10., 11.}); - REQUIRE(counter0 == 90000ul); - REQUIRE(counter1 == 190000ul); + REQUIRE(counter0 == 100000ul); + REQUIRE(counter1 == 220000ul); REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); - REQUIRE(ta_copy.get_time() == std::vector{10., 11.}); - REQUIRE(std::all_of(ta_copy.get_propagate_res().begin(), ta_copy.get_propagate_res().end(), - [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); - - for (auto i = 0u; i < 3u; ++i) { - REQUIRE(out[4u * i + 0u] == approximately(out_copy[4u * i + 0u], 1000.)); - REQUIRE(out[4u * i + 1u] == approximately(out_copy[4u * i + 1u], 1000.)); - REQUIRE(out[4u * i + 2u] == approximately(out_copy[4u * i + 2u], 1000.)); - REQUIRE(out[4u * i + 3u] == approximately(out_copy[4u * i + 3u], 1000.)); - } - // Do backward in time too. out = ta.propagate_grid({10., 11., 5., 5.6, 1., 1.5}, kw::max_delta_t = std::vector{1e-4, 5e-5}, kw::callback = cb); - out_copy = ta_copy.propagate_grid({10., 11., 5., 5.6, 1., 1.5}); REQUIRE(ta.get_time() == std::vector{1., 1.5}); - REQUIRE(counter0 == 180000ul); - REQUIRE(counter1 == 380000ul); + REQUIRE(counter0 == 190000ul); + REQUIRE(counter1 == 410000ul); REQUIRE(std::all_of(ta.get_propagate_res().begin(), ta.get_propagate_res().end(), [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); - REQUIRE(ta_copy.get_time() == std::vector{1., 1.5}); - REQUIRE(std::all_of(ta_copy.get_propagate_res().begin(), ta_copy.get_propagate_res().end(), - [](const auto &t) { return std::get<0>(t) == taylor_outcome::time_limit; })); - - for (auto i = 0u; i < 3u; ++i) { - REQUIRE(out[4u * i + 0u] == approximately(out_copy[4u * i + 0u], 1000.)); - REQUIRE(out[4u * i + 1u] == approximately(out_copy[4u * i + 1u], 1000.)); - REQUIRE(out[4u * i + 2u] == approximately(out_copy[4u * i + 2u], 1000.)); - REQUIRE(out[4u * i + 3u] == approximately(out_copy[4u * i + 3u], 1000.)); - } - // Test also with scalar max_delta_t. ta_copy = ta; - out = ta.propagate_grid({1., 1.5, 5., 5.6, 10., 11.}, kw::max_delta_t = std::vector{1e-4, 1e-4}); - out_copy = ta_copy.propagate_grid({1., 1.5, 5., 5.6, 10., 11.}, kw::max_delta_t = 1e-4); + ta.set_time(0.); + ta_copy.set_time(0.); + out = ta.propagate_grid({0., 0., 5., 5.6, 10., 11.}, kw::max_delta_t = std::vector{1e-4, 1e-4}); + auto out_copy = ta_copy.propagate_grid({0., 0., 5., 5.6, 10., 11.}, kw::max_delta_t = 1e-4); REQUIRE(out == out_copy); } @@ -794,10 +758,11 @@ TEST_CASE("cb interrupt") { auto [x, v] = make_vars("x", "v"); - auto ta = taylor_adaptive_batch{{prime(x) = v, prime(v) = -9.8 * sin(x)}, {0.05, 0.06, 0.025, 0.026}, 2u}; - // propagate_for/until(). { + auto ta + = taylor_adaptive_batch{{prime(x) = v, prime(v) = -9.8 * sin(x)}, {0.05, 0.06, 0.025, 0.026}, 2u}; + ta.propagate_until( {1., 1.1}, kw::callback = [](auto &) { return false; }); @@ -826,8 +791,11 @@ TEST_CASE("cb interrupt") // propagate_grid(). { + auto ta + = taylor_adaptive_batch{{prime(x) = v, prime(v) = -9.8 * sin(x)}, {0.05, 0.06, 0.025, 0.026}, 2u}; + auto res = ta.propagate_grid( - {10., 10.1, 11., 11.1, 12., 12.1}, kw::callback = [](auto &) { return false; }); + {0., 0., 11., 11.1, 12., 12.1}, kw::callback = [](auto &) { return false; }); REQUIRE(std::all_of(res.begin() + 4, res.end(), [](double val) { return std::isnan(val); })); @@ -842,7 +810,8 @@ TEST_CASE("cb interrupt") auto counter = 0u; res = ta.propagate_grid( - {20., 20.1, 21., 21.1, 32., 32.1}, kw::callback = [&counter](auto &) { return counter++ != 5u; }); + {ta.get_time()[0], ta.get_time()[1], 21., 21.1, 32., 32.1}, + kw::callback = [&counter](auto &) { return counter++ != 5u; }); REQUIRE(std::get<0>(ta.get_propagate_res()[0]) == taylor_outcome::cb_stop); REQUIRE(std::get<0>(ta.get_propagate_res()[1]) == taylor_outcome::cb_stop); @@ -857,8 +826,11 @@ TEST_CASE("cb interrupt") // Check that stopping via cb still processes the grid points // within the last taken step. { + auto ta + = taylor_adaptive_batch{{prime(x) = v, prime(v) = -9.8 * sin(x)}, {0.05, 0.06, 0.025, 0.026}, 2u}; + auto res = ta.propagate_grid( - {10., 10.1, 10. + 1e-6, 21.1, 10. + 2e-6, 32.1}, kw::callback = [](auto &) { return false; }); + {0., 0., 1e-6, 21.1, 2e-6, 32.1}, kw::callback = [](auto &) { return false; }); REQUIRE(std::get<0>(ta.get_propagate_res()[0]) == taylor_outcome::cb_stop); REQUIRE(std::get<0>(ta.get_propagate_res()[1]) == taylor_outcome::cb_stop); @@ -1856,6 +1828,7 @@ TEST_CASE("propagate_grid tc issue") auto ta = taylor_adaptive_batch({prime(x) = v, prime(v) = -x}, {0., 0., 1., 1.}, 2); + ta.propagate_until({-.5, -.5}); std::vector t_grid = {-.5, -.5, -.1, -.4999, .1, .1, .2, .2}; auto out = ta.propagate_grid(t_grid); diff --git a/test/taylor_adaptive_mp.cpp b/test/taylor_adaptive_mp.cpp index 6343e2d93..22b2c3a4b 100644 --- a/test/taylor_adaptive_mp.cpp +++ b/test/taylor_adaptive_mp.cpp @@ -34,6 +34,8 @@ #include "heyoka/kw.hpp" #include "test_utils.hpp" +#include + using namespace heyoka; using namespace heyoka_test; @@ -462,7 +464,7 @@ TEST_CASE("propagate trivial") kw::compact_mode = true}; REQUIRE(std::get<0>(ta.propagate_for(fp_t(1.2, prec))) == taylor_outcome::time_limit); - REQUIRE(std::get<0>(ta.propagate_until(fp_t(2.3, prec))) == taylor_outcome::time_limit); + REQUIRE(std::get<0>(ta.propagate_until(fp_t(3, prec))) == taylor_outcome::time_limit); REQUIRE(std::get<0>( ta.propagate_grid({fp_t(3, prec), fp_t(4, prec), fp_t(5, prec), fp_t(6, prec), fp_t(7., prec)})) == taylor_outcome::time_limit); @@ -750,7 +752,7 @@ TEST_CASE("propagate grid scalar") // Set an infinity in the state. ta.get_state_data()[0] = fp_t(std::numeric_limits::infinity(), prec); - auto out = ta.propagate_grid({fp_t(.2, prec)}); + auto out = ta.propagate_grid({fp_t(.0, prec)}); REQUIRE(std::get<0>(out) == taylor_outcome::err_nf_state); REQUIRE(std::get<4>(out).empty()); @@ -773,7 +775,7 @@ TEST_CASE("propagate grid scalar") REQUIRE(ta.get_time() == 0.); REQUIRE_THROWS_MATCHES( - ta.propagate_grid({fp_t(2., prec), fp_t(std::numeric_limits::infinity(), prec)}), + ta.propagate_grid({fp_t(0., prec), fp_t(std::numeric_limits::infinity(), prec)}), std::invalid_argument, Message("A non-finite time value was passed to propagate_grid() in an adaptive Taylor integrator")); @@ -818,6 +820,7 @@ TEST_CASE("propagate grid scalar") ta.set_time(fp_t(10., prec)); ta.get_state_data()[0] = sin(fp_t(10., prec)); ta.get_state_data()[1] = cos(fp_t(10., prec)); + grid.back() = fp_t(10., prec); std::reverse(grid.begin(), grid.end()); out = ta.propagate_grid(grid); @@ -842,6 +845,10 @@ TEST_CASE("propagate grid scalar") grid[i] = grid[i - 1u] + fp_t(rdist(rng), prec); } + ta = taylor_adaptive{{prime(x) = v, prime(v) = -x}, + {fp_t(0., prec), fp_t(1., prec)}, + kw::opt_level = opt_level, + kw::compact_mode = true}; out = ta.propagate_grid(grid); REQUIRE(std::get<0>(out) == taylor_outcome::time_limit); @@ -864,6 +871,10 @@ TEST_CASE("propagate grid scalar") grid[i] = grid[i - 1u] + fp_t(rdist(rng), prec); } + ta = taylor_adaptive{{prime(x) = v, prime(v) = -x}, + {fp_t(0., prec), fp_t(1., prec)}, + kw::opt_level = opt_level, + kw::compact_mode = true}; out = ta.propagate_grid(grid); REQUIRE(std::get<0>(out) == taylor_outcome::time_limit); @@ -881,38 +892,16 @@ TEST_CASE("propagate grid scalar") kw::opt_level = opt_level, kw::compact_mode = true}; - out = ta.propagate_grid({fp_t(.1, prec), fp_t(10., prec), fp_t(100., prec)}); + out = ta.propagate_grid({fp_t(0., prec), fp_t(.1, prec), fp_t(10., prec), fp_t(100., prec)}); - REQUIRE(std::get<4>(out).size() == 6u); + REQUIRE(std::get<4>(out).size() == 8u); REQUIRE(ta.get_time() == 100.); - REQUIRE(std::get<4>(out)[0] == approximately(sin(fp_t(.1, prec)), fp_t(100., prec))); - REQUIRE(std::get<4>(out)[1] == approximately(cos(fp_t(.1, prec)), fp_t(100., prec))); - REQUIRE(std::get<4>(out)[2] == approximately(sin(fp_t(10, prec)), fp_t(100., prec))); - REQUIRE(std::get<4>(out)[3] == approximately(cos(fp_t(10, prec)), fp_t(100, prec))); - REQUIRE(std::get<4>(out)[4] == approximately(sin(fp_t(100, prec)), fp_t(1000, prec))); - REQUIRE(std::get<4>(out)[5] == approximately(cos(fp_t(100, prec)), fp_t(1000, prec))); - - // A case in which the initial propagate_until() to bring the system - // to grid[0] interrupts the integration. - ta = taylor_adaptive{{prime(x) = v, prime(v) = -x}, - {fp_t(0., prec), fp_t(1., prec)}, - kw::opt_level = opt_level, - kw::compact_mode = true, - kw::t_events = {t_event(v - 0.999)}}; - out = ta.propagate_grid({fp_t(10., prec), fp_t(100., prec)}); - REQUIRE(std::get<0>(out) == taylor_outcome{-1}); - REQUIRE(std::get<4>(out).empty()); - - ta = taylor_adaptive{ - {prime(x) = v, prime(v) = -x}, - {fp_t(0., prec), fp_t(1., prec)}, - kw::opt_level = opt_level, - kw::compact_mode = true, - kw::t_events = {t_event( - v - 0.999, kw::callback = [](taylor_adaptive &, bool, int) { return false; })}}; - out = ta.propagate_grid({fp_t(10., prec), fp_t(100., prec)}); - REQUIRE(std::get<0>(out) == taylor_outcome{-1}); - REQUIRE(std::get<4>(out).empty()); + REQUIRE(std::get<4>(out)[2] == approximately(sin(fp_t(.1, prec)), fp_t(100., prec))); + REQUIRE(std::get<4>(out)[3] == approximately(cos(fp_t(.1, prec)), fp_t(100., prec))); + REQUIRE(std::get<4>(out)[4] == approximately(sin(fp_t(10, prec)), fp_t(100., prec))); + REQUIRE(std::get<4>(out)[5] == approximately(cos(fp_t(10, prec)), fp_t(100, prec))); + REQUIRE(std::get<4>(out)[6] == approximately(sin(fp_t(100, prec)), fp_t(1000, prec))); + REQUIRE(std::get<4>(out)[7] == approximately(cos(fp_t(100, prec)), fp_t(1000, prec))); // A case in which we have a callback which never stops and a terminal event // which triggers. @@ -924,7 +913,7 @@ TEST_CASE("propagate grid scalar") kw::t_events = {t_event( v - .1, kw::callback = [](taylor_adaptive &, bool, int) { return false; })}}; out = ta.propagate_grid( - {fp_t(10., prec), fp_t(100., prec)}, kw::callback = [](const auto &) { return true; }); + {fp_t(0., prec), fp_t(10., prec), fp_t(100., prec)}, kw::callback = [](const auto &) { return true; }); REQUIRE(std::get<0>(out) == taylor_outcome{-1}); } } From ab93176d58d3af96c105dc6b46bb09ffc86aefe0 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 16 Dec 2023 11:00:04 +0100 Subject: [PATCH 5/7] Update changelog, internal docs. --- doc/breaking_changes.rst | 14 ++++++++++++++ doc/changelog.rst | 5 +++++ include/heyoka/step_callback.hpp | 2 +- include/heyoka/taylor.hpp | 9 +++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/doc/breaking_changes.rst b/doc/breaking_changes.rst index 7c2847ab4..4f1dc8657 100644 --- a/doc/breaking_changes.rst +++ b/doc/breaking_changes.rst @@ -10,6 +10,20 @@ Breaking changes heyoka 4 includes several backwards-incompatible changes. +API/behaviour changes +~~~~~~~~~~~~~~~~~~~~~ + +``propagate_grid()`` +^^^^^^^^^^^^^^^^^^^^ + +The ``propagate_grid()`` functions of the adaptive integrators now require the first element of the +time grid to be equal to the current integrator time. Previously, in case of a difference between the +integration time and the first grid point, heyoka would propagate the state of the system up to the +first grid point with ``propagate_until()``. + +If you want to recover the previous behaviour, you will have to invoke manually ``propagate_until(grid[0])`` +before invoking ``propagate_grid()``. + General ~~~~~~~ diff --git a/doc/changelog.rst b/doc/changelog.rst index b236c456b..67ea91bdf 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,6 +7,11 @@ Changelog Changes ~~~~~~~ +- **BREAKING**: the ``propagate_grid()`` functions of the + adaptive integrators now require the first element of the + time grid to be equal to the current integrator time + (`#373 `__). + This is a :ref:`breaking change `. - Move the declarations of all :ref:`keyword arguments ` into the ``kw.hpp`` header (`#372 `__). diff --git a/include/heyoka/step_callback.hpp b/include/heyoka/step_callback.hpp index ea0e36490..0603a8db7 100644 --- a/include/heyoka/step_callback.hpp +++ b/include/heyoka/step_callback.hpp @@ -104,7 +104,7 @@ struct HEYOKA_DLL_PUBLIC_INLINE_CLASS step_cb_ifaceT { // Configuration. template inline constexpr auto step_cb_wrap_config = tanuki::config::template type>{ - // Similarly to std::function, ensure that callable can store + // Similarly to std::function, ensure that step_callback can store // in static storage pointers and reference wrappers. // NOTE: reference wrappers are not guaranteed to have the size // of a pointer, but in practice that should always be the case. diff --git a/include/heyoka/taylor.hpp b/include/heyoka/taylor.hpp index 29cc971e0..317b39c86 100644 --- a/include/heyoka/taylor.hpp +++ b/include/heyoka/taylor.hpp @@ -1292,6 +1292,15 @@ class HEYOKA_DLL_PUBLIC_INLINE_CLASS taylor_adaptive : public detail::taylor_ada // - continuous output, if requested (only for propagate_for/until()). // NOTE: the min/max timesteps are well-defined // only if at least 1-2 steps were taken successfully. + // NOTE: the propagate_*() functions are not guaranteed to bring + // the integrator time *exactly* to the requested final time. This + // ultimately stems from the fact that in floating-point arithmetics + // in general a + (b - a) != b, and this happens regardless of the + // use of a double-length time representation. This occurrence however + // seems to be pretty rare in practice, so for the time being we leave + // this as it is and just document the corner-case behaviour. Perhaps + // in the future we can offer a stronger guarantee, which however will + // result in a more complicated logic. template std::tuple>> propagate_until(T t, KwArgs &&...kw_args) From cb91a309743968d50c9bc05596a84c217744455d Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 16 Dec 2023 11:00:45 +0100 Subject: [PATCH 6/7] boost-cpp -> libboost-devel in the CI. --- .github/workflows/gha_ci.yml | 4 ++-- tools/circleci_conda_asan.sh | 2 +- tools/circleci_ubuntu_arm64.sh | 2 +- tools/gha_conda_clang_tidy.sh | 2 +- tools/gha_conda_coverage.sh | 2 +- tools/gha_conda_release.sh | 2 +- tools/gha_conda_release_static.sh | 2 +- tools/gha_llvm13_conda_asan.sh | 2 +- tools/gha_llvm14_conda_asan.sh | 2 +- tools/gha_llvm15_conda_asan.sh | 2 +- tools/gha_llvm16_conda_asan.sh | 2 +- tools/gha_osx.sh | 2 +- tools/gha_osx_static.sh | 2 +- tools/travis_ubuntu_ppc64.sh | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/gha_ci.yml b/.github/workflows/gha_ci.yml index b8413af89..869157153 100644 --- a/.github/workflows/gha_ci.yml +++ b/.github/workflows/gha_ci.yml @@ -34,7 +34,7 @@ jobs: - name: Build shell: pwsh run: | - conda install -y cmake 'llvmdev=13.*' tbb-devel tbb boost-cpp xtensor xtensor-blas blas blas-devel fmt spdlog sleef zlib libzlib 'mppp=1.*' + conda install -y cmake 'llvmdev=13.*' tbb-devel tbb libboost-devel xtensor xtensor-blas blas blas-devel fmt spdlog sleef zlib libzlib 'mppp=1.*' mkdir build cd build cmake ../ -G "Visual Studio 17 2022" -A x64 -DHEYOKA_BUILD_TESTS=yes -DHEYOKA_WITH_MPPP=yes -DHEYOKA_BUILD_TUTORIALS=ON -DHEYOKA_ENABLE_IPO=yes -DBoost_NO_BOOST_CMAKE=ON -DHEYOKA_WITH_SLEEF=yes -DMPPP_GMP_INCLUDE_DIR=C:\Miniconda\envs\test\Library\include -DMPPP_GMP_LIBRARY=C:\Miniconda\envs\test\Library\lib\mpir.lib @@ -56,7 +56,7 @@ jobs: - name: Build shell: pwsh run: | - conda install -y cmake 'llvmdev=14.*' tbb-devel tbb boost-cpp xtensor xtensor-blas blas blas-devel fmt spdlog sleef zlib libzlib 'mppp=1.*' + conda install -y cmake 'llvmdev=14.*' tbb-devel tbb libboost-devel xtensor xtensor-blas blas blas-devel fmt spdlog sleef zlib libzlib 'mppp=1.*' mkdir build cd build cmake ../ -G "Visual Studio 17 2022" -A x64 -DHEYOKA_BUILD_TESTS=yes -DHEYOKA_WITH_MPPP=yes -DHEYOKA_BUILD_TUTORIALS=ON -DHEYOKA_ENABLE_IPO=yes -DBoost_NO_BOOST_CMAKE=ON -DHEYOKA_WITH_SLEEF=yes -DMPPP_GMP_INCLUDE_DIR=C:\Miniconda\envs\test\Library\include -DMPPP_GMP_LIBRARY=C:\Miniconda\envs\test\Library\lib\mpir.lib diff --git a/tools/circleci_conda_asan.sh b/tools/circleci_conda_asan.sh index 9e0f14326..71c45d1b0 100644 --- a/tools/circleci_conda_asan.sh +++ b/tools/circleci_conda_asan.sh @@ -17,7 +17,7 @@ bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake \ - llvmdev tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor \ + llvmdev tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor \ xtensor-blas blas blas-devel fmt spdlog \ 'sphinxcontrib-bibtex=2.5.*' 'sphinx=6.*' 'sphinx-book-theme=1.*' source activate $deps_dir diff --git a/tools/circleci_ubuntu_arm64.sh b/tools/circleci_ubuntu_arm64.sh index 378d9853c..ddd15eb10 100644 --- a/tools/circleci_ubuntu_arm64.sh +++ b/tools/circleci_ubuntu_arm64.sh @@ -14,7 +14,7 @@ wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforg export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda -mamba create -y -p $deps_dir cxx-compiler c-compiler cmake llvmdev tbb-devel tbb boost-cpp sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' +mamba create -y -p $deps_dir cxx-compiler c-compiler cmake llvmdev tbb-devel tbb libboost-devel sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_conda_clang_tidy.sh b/tools/gha_conda_clang_tidy.sh index 049f6629e..9301b0199 100755 --- a/tools/gha_conda_clang_tidy.sh +++ b/tools/gha_conda_clang_tidy.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir cmake c-compiler cxx-compiler clang clangxx clang-tools llvmdev tbb-devel tbb boost-cpp 'mppp=1.*' sleef fmt spdlog ninja +conda create -y -q -p $deps_dir cmake c-compiler cxx-compiler clang clangxx clang-tools llvmdev tbb-devel tbb libboost-devel 'mppp=1.*' sleef fmt spdlog ninja source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_conda_coverage.sh b/tools/gha_conda_coverage.sh index fc8339cf0..4e30ef96c 100644 --- a/tools/gha_conda_coverage.sh +++ b/tools/gha_conda_coverage.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog lcov +conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog lcov source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_conda_release.sh b/tools/gha_conda_release.sh index d65d0b7dd..6010466d8 100644 --- a/tools/gha_conda_release.sh +++ b/tools/gha_conda_release.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog +conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_conda_release_static.sh b/tools/gha_conda_release_static.sh index 1f0efb70f..41f9e9334 100644 --- a/tools/gha_conda_release_static.sh +++ b/tools/gha_conda_release_static.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog zlib +conda create -y -q -p $deps_dir c-compiler cxx-compiler cmake llvmdev tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog zlib source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_llvm13_conda_asan.sh b/tools/gha_llvm13_conda_asan.sh index 3ae3b74ea..f0c679ea4 100644 --- a/tools/gha_llvm13_conda_asan.sh +++ b/tools/gha_llvm13_conda_asan.sh @@ -14,7 +14,7 @@ wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforg export deps_dir=$HOME/local export PATH="$HOME/mambaforge/bin:$PATH" bash mambaforge.sh -b -p $HOME/mambaforge -mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=13.*' tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog +mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=13.*' tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_llvm14_conda_asan.sh b/tools/gha_llvm14_conda_asan.sh index d74617642..9993c0b65 100644 --- a/tools/gha_llvm14_conda_asan.sh +++ b/tools/gha_llvm14_conda_asan.sh @@ -14,7 +14,7 @@ wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforg export deps_dir=$HOME/local export PATH="$HOME/mambaforge/bin:$PATH" bash mambaforge.sh -b -p $HOME/mambaforge -mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=14.*' tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog +mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=14.*' tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_llvm15_conda_asan.sh b/tools/gha_llvm15_conda_asan.sh index 576177156..5da15ff87 100644 --- a/tools/gha_llvm15_conda_asan.sh +++ b/tools/gha_llvm15_conda_asan.sh @@ -14,7 +14,7 @@ wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforg export deps_dir=$HOME/local export PATH="$HOME/mambaforge/bin:$PATH" bash mambaforge.sh -b -p $HOME/mambaforge -mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=15.*' tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog +mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=15.*' tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_llvm16_conda_asan.sh b/tools/gha_llvm16_conda_asan.sh index 9f12b7f44..fd53f9c01 100755 --- a/tools/gha_llvm16_conda_asan.sh +++ b/tools/gha_llvm16_conda_asan.sh @@ -14,7 +14,7 @@ wget https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforg export deps_dir=$HOME/local export PATH="$HOME/mambaforge/bin:$PATH" bash mambaforge.sh -b -p $HOME/mambaforge -mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=16.*' tbb-devel tbb boost-cpp 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog +mamba create -y -q -p $deps_dir c-compiler cxx-compiler cmake 'llvmdev=16.*' tbb-devel tbb libboost-devel 'mppp=1.*' sleef xtensor xtensor-blas blas blas-devel fmt spdlog source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_osx.sh b/tools/gha_osx.sh index 1552c131d..62fbdc0f1 100644 --- a/tools/gha_osx.sh +++ b/tools/gha_osx.sh @@ -13,7 +13,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir c-compiler cxx-compiler libcxx cmake llvmdev tbb-devel tbb boost-cpp sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' +conda create -y -q -p $deps_dir c-compiler cxx-compiler libcxx cmake llvmdev tbb-devel tbb libboost-devel sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/gha_osx_static.sh b/tools/gha_osx_static.sh index 287f1d11e..63b7e6392 100644 --- a/tools/gha_osx_static.sh +++ b/tools/gha_osx_static.sh @@ -13,7 +13,7 @@ export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge conda config --set channel_priority strict -conda create -y -q -p $deps_dir c-compiler zlib cxx-compiler libcxx cmake llvmdev tbb-devel tbb boost-cpp sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' +conda create -y -q -p $deps_dir c-compiler zlib cxx-compiler libcxx cmake llvmdev tbb-devel tbb libboost-devel sleef xtensor xtensor-blas blas blas-devel fmt spdlog 'mppp=1.*' source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/travis_ubuntu_ppc64.sh b/tools/travis_ubuntu_ppc64.sh index ff6216989..c92ba8447 100755 --- a/tools/travis_ubuntu_ppc64.sh +++ b/tools/travis_ubuntu_ppc64.sh @@ -11,7 +11,7 @@ curl -L -o miniconda.sh https://github.com/conda-forge/miniforge/releases/latest export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda -conda create -y -q -p $deps_dir cxx-compiler c-compiler cmake llvmdev tbb-devel tbb boost-cpp sleef xtensor xtensor-blas blas blas-devel fmt spdlog make mppp +conda create -y -q -p $deps_dir cxx-compiler c-compiler cmake llvmdev tbb-devel tbb libboost-devel sleef xtensor xtensor-blas blas blas-devel fmt spdlog make mppp source activate $deps_dir # Create the build dir and cd into it. From b78f1611c39d56e64aa51f26e36f937cb8f47a61 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 16 Dec 2023 18:49:41 +0100 Subject: [PATCH 7/7] Minor. --- doc/breaking_changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/breaking_changes.rst b/doc/breaking_changes.rst index 4f1dc8657..a51248183 100644 --- a/doc/breaking_changes.rst +++ b/doc/breaking_changes.rst @@ -18,7 +18,7 @@ API/behaviour changes The ``propagate_grid()`` functions of the adaptive integrators now require the first element of the time grid to be equal to the current integrator time. Previously, in case of a difference between the -integration time and the first grid point, heyoka would propagate the state of the system up to the +integrator time and the first grid point, heyoka would propagate the state of the system up to the first grid point with ``propagate_until()``. If you want to recover the previous behaviour, you will have to invoke manually ``propagate_until(grid[0])``