diff --git a/opm/core/linalg/ParallelIstlInformation.hpp b/opm/core/linalg/ParallelIstlInformation.hpp index 97c191b3..49504dff 100644 --- a/opm/core/linalg/ParallelIstlInformation.hpp +++ b/opm/core/linalg/ParallelIstlInformation.hpp @@ -185,6 +185,7 @@ public: /// to compute a reduction. Or with tuples of them to compute multiple reductions with only /// one global communication. /// The possible functors needed can be constructed with Opm::Reduction::makeGlobalMaxFunctor(), + /// Opm::Reduction::makeLInfinityNormFunctor(), /// Opm::Reduction::makeGlobalMinFunctor(), and /// Opm::Reduction::makeGlobalSumFunctor(). /// \tparam type of the container or the tuple of containers. @@ -574,6 +575,30 @@ private: (std::pointer_to_binary_function ((const T&(*)(const T&, const T&))std::max)); } + + namespace detail + { + /// \brief Computes the maximum of theabsolute values of two values. + template + struct MaxAbsFunctor + { + typedef T result_type; + + result_type operator()(const T& t1, const T& t2) + { + return std::max(std::abs(t1),std::abs(t2)); + } + }; + } + /// \brief Create a functor for computing a global L infinity norm + /// + /// To be used with ParallelISTLInformation::computeReduction. + template + MaskIDOperator > + makeLInfinityNormFunctor() + { + return MaskIDOperator >(); + } /// \brief Create a functor for computing a global minimum. /// /// To be used with ParallelISTLInformation::computeReduction. diff --git a/tests/test_parallelistlinformation.cpp b/tests/test_parallelistlinformation.cpp index 6bd92700..8258ad32 100644 --- a/tests/test_parallelistlinformation.cpp +++ b/tests/test_parallelistlinformation.cpp @@ -45,12 +45,13 @@ void runSumMaxMinTest(const T offset) assert(comm.indexSet()->size()==x.size()); for(auto it=comm.indexSet()->begin(), itend=comm.indexSet()->end(); it!=itend; ++it) x[it->local()]=it->global()+offset; - auto containers = std::make_tuple(x, x, x, x); + auto containers = std::make_tuple(x, x, x, x, x); auto operators = std::make_tuple(Opm::Reduction::makeGlobalSumFunctor(), Opm::Reduction::makeGlobalMaxFunctor(), Opm::Reduction::makeGlobalMinFunctor(), - Opm::Reduction::makeInnerProductFunctor()); - auto values = std::tuple(0,0,100000, 0); + Opm::Reduction::makeInnerProductFunctor(), + Opm::Reduction::makeLInfinityNormFunctor()); + auto values = std::tuple(0,0,100000, 0, 0); auto oldvalues = values; start = offset; end = start+N; @@ -59,10 +60,12 @@ void runSumMaxMinTest(const T offset) BOOST_CHECK(std::get<1>(values)==std::max(N+offset-1, std::get<1>(oldvalues))); BOOST_CHECK(std::get<2>(values)==std::min(offset, std::get<2>(oldvalues))); BOOST_CHECK(std::get<3>(values)==((end-1)*end*(2*end-1)-(start-1)*start*(2*start-1))/6+std::get<3>(oldvalues)); + BOOST_CHECK(std::get<4>(values)==std::max(std::abs(offset),std::abs(N+offset-1))); } BOOST_AUTO_TEST_CASE(tupleReductionTestInt) { + runSumMaxMinTest(-200); runSumMaxMinTest(0); runSumMaxMinTest(20); runSumMaxMinTest(-20); @@ -75,6 +78,7 @@ BOOST_AUTO_TEST_CASE(tupleReductionTestUnsignedInt) } BOOST_AUTO_TEST_CASE(tupleReductionTestFloat) { + runSumMaxMinTest(-200); runSumMaxMinTest(0); runSumMaxMinTest(20); runSumMaxMinTest(-20);