diff --git a/dumux/common/math.hh b/dumux/common/math.hh index 64a0472e6c9519aa984b6b1772277f3526e47526..24fd0f05cea1740cd0a091b4923e01a3b25bfa9d 100644 --- a/dumux/common/math.hh +++ b/dumux/common/math.hh @@ -573,13 +573,17 @@ struct LinearTable * \param begin The first value in the vector * \param end The last value in the vector * \param samples The size of the vector + * \param endPoint if the range is including the interval's end point or not */ template <class Scalar> -std::vector<Scalar> linspace(const Scalar begin, const Scalar end, std::size_t samples) +std::vector<Scalar> linspace(const Scalar begin, const Scalar end, + std::size_t samples, + bool endPoint = true) { using std::max; samples = max(std::size_t{2}, samples); // only makes sense for 2 or more samples - const Scalar delta = (end-begin)/static_cast<Scalar>(samples-1); + const Scalar divisor = endPoint ? samples-1 : samples; + const Scalar delta = (end-begin)/divisor; std::vector<Scalar> vec(samples); for (std::size_t i = 0; i < samples; ++i) vec[i] = begin + i*delta; diff --git a/test/common/math/test_math.cc b/test/common/math/test_math.cc index 043034fccaafaa06d7184dd10d0c0e376cd05102..934dc7f4ec08764be95f7251fdaf8b597f8fca41 100644 --- a/test/common/math/test_math.cc +++ b/test/common/math/test_math.cc @@ -32,6 +32,7 @@ #include <iostream> #include <utility> +#include <algorithm> #include <dune/common/float_cmp.hh> #include <dune/common/fmatrix.hh> @@ -186,6 +187,33 @@ int main() try Test::checkTableInterpolation(1.5, 2.0, table); Test::checkTableInterpolation(2.0, 3.0, table); Test::checkTableInterpolation(3.0, 3.0, table); + + ////////////////////////////////////////////////////////////////// + ///// Dumux::linspace //////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + { + const auto v = Dumux::linspace(1.0, 2.0, 100); + if (!Dune::FloatCmp::eq(v.back(), 2.0)) + DUNE_THROW(Dune::Exception, "[linspace] Last point not included!"); + if (!Dune::FloatCmp::eq(v.front(), 1.0)) + DUNE_THROW(Dune::Exception, "[linspace] First point not included!"); + if (v.size() != 100) + DUNE_THROW(Dune::Exception, "[linspace] Size incorrect!"); + if (!std::is_sorted(v.begin(), v.end())) + DUNE_THROW(Dune::Exception, "[linspace] Not sorted in ascending order!"); + } + { + const auto v = Dumux::linspace(1.0, 2.0, 100, /*endPoint=*/false); + if (!Dune::FloatCmp::eq(v.back(), 2.0-0.01)) + DUNE_THROW(Dune::Exception, "[linspace] Last point not correct!"); + if (!Dune::FloatCmp::eq(v.front(), 1.0)) + DUNE_THROW(Dune::Exception, "[linspace] First point not included!"); + if (v.size() != 100) + DUNE_THROW(Dune::Exception, "[linspace] Size incorrect!"); + if (!std::is_sorted(v.begin(), v.end())) + DUNE_THROW(Dune::Exception, "[linspace] Not sorted in ascending order!"); + } + } catch (Dune::Exception& e) { std::cerr << e << std::endl;