From dd7e8ed34b446d1f14d7125e98e42d2d2040553c Mon Sep 17 00:00:00 2001
From: Oliver Sander <oliver.sander@tu-dresden.de>
Date: Wed, 9 Dec 2015 23:09:49 +0100
Subject: [PATCH] Implement the infinity_norm method for the
 MultiTypeBlockVector class

---
 dune/istl/multitypeblockvector.hh          | 39 ++++++++++++++++++++++
 dune/istl/test/multitypeblockvectortest.cc |  3 ++
 2 files changed, 42 insertions(+)

diff --git a/dune/istl/multitypeblockvector.hh b/dune/istl/multitypeblockvector.hh
index 85a896e47..dfc72d2fe 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 5fdf98fc2..e0d1386d8 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;
 
-- 
GitLab