diff --git a/dune/istl/multitypeblockvector.hh b/dune/istl/multitypeblockvector.hh index 85a896e47edfb1f8af9f8eeb477b4d183adae7f0..dfc72d2feb8fe445d8a17b8a26686abb43fb93ee 100644 --- a/dune/istl/multitypeblockvector.hh +++ b/dune/istl/multitypeblockvector.hh @@ -228,6 +228,38 @@ namespace Dune { static real_type result (const T&) {return 0.0;} }; + /** \brief Calculate the \infty-norm + + Each element of the vector has to provide the method "infinity_norm()" + in order to calculate the whole vector's norm. + */ + template<int count, typename T> + class MultiTypeBlockVector_InfinityNorm { + public: + typedef typename T::field_type field_type; + typedef typename FieldTraits<field_type>::real_type real_type; + + /** + * Take the maximum over all elements' norms + */ + static real_type result (const T& a) + { + using std::max; + return max(std::get<count-1>(a).infinity_norm(), MultiTypeBlockVector_InfinityNorm<count-1,T>::result(a)); + } + }; + + template<typename T> //recursion end + class MultiTypeBlockVector_InfinityNorm<0,T> { + public: + typedef typename T::field_type field_type; + typedef typename FieldTraits<field_type>::real_type real_type; + static real_type result (const T&) + { + return 0.0; + } + }; + /** @brief A Vector class to support different block types @@ -377,6 +409,13 @@ namespace Dune { */ typename FieldTraits<field_type>::real_type two_norm() const {return sqrt(this->two_norm2());} + /** \brief Compute the maximum norm + */ + typename FieldTraits<field_type>::real_type infinity_norm() const + { + return MultiTypeBlockVector_InfinityNorm<sizeof...(Args),type>::result(*this); + } + /** \brief Axpy operation on this vector (*this += a * y) * * \tparam Ta Type of the scalar 'a' diff --git a/dune/istl/test/multitypeblockvectortest.cc b/dune/istl/test/multitypeblockvectortest.cc index 5fdf98fc2f671c4eb85aae0a0b6ecdf6f7659017..e0d1386d8ce2b4dd362d8bdc36e203f733a1e7a5 100644 --- a/dune/istl/test/multitypeblockvectortest.cc +++ b/dune/istl/test/multitypeblockvectortest.cc @@ -69,6 +69,9 @@ int main(int argc, char** argv) try // Test two_norm2 std::cout << "multivector2 has two_norm2: " << multiVector2.two_norm2() << std::endl; + // Test infinity_norm + std::cout << "multivector2 has infinity_norm: " << multiVector2.infinity_norm() << std::endl; + // Test operator* std::cout << multiVector * multiVector2 << std::endl;