From 975fc4c75d49cc812dc7a21c8b4d7efbfbc825de Mon Sep 17 00:00:00 2001
From: "Praetorius, Simon" <simon.praetorius@tu-dresden.de>
Date: Mon, 16 Dec 2019 13:35:21 +0100
Subject: [PATCH] replaced implementation of static Size template with generic
 constexpr function

---
 src/amdis/common/Apply.hpp                    |   2 +-
 src/amdis/common/ForEach.hpp                  |   2 +-
 src/amdis/common/HybridSize.hpp               |  85 +++--
 src/amdis/common/MultiTypeMatrix.hpp          |  37 +-
 src/amdis/common/MultiTypeVector.hpp          |  29 +-
 src/amdis/common/QuadMath.hpp                 |  19 +-
 src/amdis/common/Range.hpp                    |   5 -
 src/amdis/common/StaticSize.hpp               | 360 ++++++++++++------
 .../gridfunctions/DiscreteFunction.inc.hpp    |   2 +-
 src/amdis/io/VTKWriter.hpp                    |   2 +-
 .../ConvectionDiffusionOperator.hpp           |   8 +-
 .../localoperators/FirstOrderDivTestvec.hpp   |   2 +-
 .../localoperators/FirstOrderGradTest.hpp     |   2 +-
 .../localoperators/FirstOrderPartialTest.hpp  |   2 +-
 .../FirstOrderTestDivTrialvec.hpp             |   2 +-
 .../FirstOrderTestGradTrial.hpp               |   2 +-
 .../FirstOrderTestPartialTrial.hpp            |   2 +-
 .../FirstOrderTestvecGradTrial.hpp            |   2 +-
 .../SecondOrderDivTestvecDivTrialvec.hpp      |   2 +-
 .../SecondOrderGradTestGradTrial.hpp          |   2 +-
 .../SecondOrderPartialTestPartialTrial.hpp    |   2 +-
 src/amdis/localoperators/StokesOperator.hpp   |   2 +-
 src/amdis/localoperators/ZeroOrderTest.hpp    |   2 +-
 .../localoperators/ZeroOrderTestTrial.hpp     |   2 +-
 .../localoperators/ZeroOrderTestTrialvec.hpp  |   4 +-
 src/amdis/localoperators/ZeroOrderTestvec.hpp |   2 +-
 .../ZeroOrderTestvecTrialvec.hpp              |   4 +-
 test/HybridSizeTest.cpp                       |  26 +-
 test/StaticSizeTest.cpp                       |  44 +--
 29 files changed, 391 insertions(+), 266 deletions(-)

diff --git a/src/amdis/common/Apply.hpp b/src/amdis/common/Apply.hpp
index 46073a01..195c90a5 100644
--- a/src/amdis/common/Apply.hpp
+++ b/src/amdis/common/Apply.hpp
@@ -32,7 +32,7 @@ namespace AMDiS
     constexpr decltype(auto) apply(F&& f, Tuple&& t)
     {
       return Impl_::apply_impl(FWD(f), FWD(t),
-          std::make_index_sequence<Size_v<std::remove_reference_t<Tuple>>>{});
+          std::make_index_sequence<static_size_v<Tuple>>{});
     }
 
     template <class Functor, class... Args>
diff --git a/src/amdis/common/ForEach.hpp b/src/amdis/common/ForEach.hpp
index 1cbba6f8..cd735ac9 100644
--- a/src/amdis/common/ForEach.hpp
+++ b/src/amdis/common/ForEach.hpp
@@ -41,7 +41,7 @@ namespace AMDiS
     template <class Tuple, class Functor>
     constexpr void for_each(Tuple&& tuple, Functor&& f)
     {
-      Tools::for_each(std::make_index_sequence<Size_v<std::remove_reference_t<Tuple>>>{}, FWD(tuple), FWD(f));
+      Tools::for_each(std::make_index_sequence<static_size_v<Tuple>>{}, FWD(tuple), FWD(f));
     }
 
 
diff --git a/src/amdis/common/HybridSize.hpp b/src/amdis/common/HybridSize.hpp
index d26fdba2..b93c622a 100644
--- a/src/amdis/common/HybridSize.hpp
+++ b/src/amdis/common/HybridSize.hpp
@@ -2,13 +2,11 @@
 
 #include <utility>
 
-#include <dune/common/indices.hh>
 #include <dune/common/rangeutilities.hh>
 #include <dune/common/typeutilities.hh>
 
 #include <amdis/common/Access.hpp>
 #include <amdis/common/Concepts.hpp>
-#include <amdis/common/Index.hpp>
 #include <amdis/common/StaticSize.hpp>
 
 namespace AMDiS
@@ -33,10 +31,10 @@ namespace AMDiS
    * of entries as integer value. Otherwise a `std::integral_constant` is returned.
    **/
   template <class Vector>
-  implementation-defined hybridSize(Vector const& vec);
+  implementation-defined hybrid_size(Vector const& vec);
 
   /// Return either an IntegralRange or a StaticIntegralRange of the indices to
-  /// access the vector, depending on the type of \ref hybridSize(vec)
+  /// access the vector, depending on the type of \ref hybrid_size(vec)
   template <class Vector>
   implementation-defined hybridElements(Vector const& vec);
 
@@ -46,10 +44,10 @@ namespace AMDiS
    * of rows as integer value. Otherwise a `std::integral_constant` is returned.
    **/
   template <class Matrix>
-  implementation-defined hybridNumRows(Matrix const& mat);
+  implementation-defined hybrid_num_rows(Matrix const& mat);
 
   /// Return either an IntegralRange or a StaticIntegralRange of the indices to
-  /// access the rows of the matrix, depending on the type of \ref hybridNumRows(mat)
+  /// access the rows of the matrix, depending on the type of \ref hybrid_num_rows(mat)
   template <class Matrix>
   implementation-defined hybridRows(Matrix const& mat);
 
@@ -59,10 +57,10 @@ namespace AMDiS
    * of columns as integer value. Otherwise a `std::integral_constant` is returned.
    **/
   template <class Matrix>
-  implementation-defined hybridNumCols(Matrix const& mat);
+  implementation-defined hybrid_num_cols(Matrix const& mat);
 
   /// Return either an IntegralRange or a StaticIntegralRange of the indices to
-  /// access the columns of the matrix, depending on the type of \ref hybridNumCols(mat)
+  /// access the columns of the matrix, depending on the type of \ref hybrid_num_cols(mat)
   template <class Matrix>
   implementation-defined hybridCols(Matrix const& mat);
 #else
@@ -71,29 +69,32 @@ namespace AMDiS
   {
     template <class Vector,
       REQUIRES(Concepts::DynamicVectorAccessible_t<Vector>::value)>
-    auto hybridSize(Vector const& vec, Dune::PriorityTag<3>)
+    auto hybrid_size(Vector const& vec, Dune::PriorityTag<2>)
       -> decltype(vec.size()) { return vec.size(); }
 
     template <class Vector,
-      REQUIRES(not Concepts::DynamicVectorAccessible_t<Vector>::value)>
-    constexpr index_t<Vector::dimension> hybridSize(Vector const& vec, Dune::PriorityTag<2>) { return {}; }
+      REQUIRES(Concepts::DynamicVectorAccessible_t<Vector>::value)>
+    auto hybrid_size(Vector const& vec, Dune::PriorityTag<1>)
+      -> decltype(size(vec)) { return size(vec); }
 
-    template <class Vector,
-      REQUIRES(not Concepts::DynamicVectorAccessible_t<Vector>::value)>
-    constexpr Size_t<Vector> hybridSize(Vector const& vec, Dune::PriorityTag<1>) { return {}; }
+    template <class Vector>
+    auto hybrid_size(Vector const& vec, Dune::PriorityTag<0>)
+    {
+      return AMDiS::static_size(vec);
+    }
 
   } // end namespace Impl
 
   template <class Vector>
-  auto hybridSize(Vector const& vec)
+  auto hybrid_size(Vector const& vec)
   {
-    return Impl::hybridSize(vec, Dune::PriorityTag<42>{});
+    return Impl::hybrid_size(vec, Dune::PriorityTag<42>{});
   }
 
   template <class Vector>
   auto hybridElements(Vector const& vec)
   {
-    return Dune::range(hybridSize(vec));
+    return Dune::range(hybrid_size(vec));
   }
 
 
@@ -101,39 +102,42 @@ namespace AMDiS
   {
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<5>)
+    auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<5>)
       -> decltype(mat.num_rows()) { return mat.num_rows(); }
 
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<4>)
+    auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<4>)
       -> decltype(mat.N()) { return mat.N(); }
 
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<3>)
+    auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<3>)
       -> decltype(mat.rows()) { return mat.rows(); }
 
     template <class Matrix,
-      REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    constexpr index_t<Matrix::rows> hybridNumRows(Matrix const& mat, Dune::PriorityTag<2>) { return {}; }
+      REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
+    auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<2>)
+      -> decltype(num_rows(mat)) { return num_rows(mat); }
 
-    template <class Matrix,
-      REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    constexpr Rows_t<Matrix> hybridNumRows(Matrix const& mat, Dune::PriorityTag<1>) { return {}; }
+    template <class Matrix>
+    auto hybrid_num_rows(Matrix const& mat, Dune::PriorityTag<0>)
+    {
+      return AMDiS::static_num_rows(mat);
+    }
 
   } // end namespace Impl
 
   template <class Matrix>
-  auto hybridNumRows(Matrix const& mat)
+  auto hybrid_num_rows(Matrix const& mat)
   {
-    return Impl::hybridNumRows(mat, Dune::PriorityTag<42>{});
+    return Impl::hybrid_num_rows(mat, Dune::PriorityTag<42>{});
   }
 
   template <class Matrix>
   auto hybridRows(Matrix const& mat)
   {
-    return Dune::range(hybridNumRows(mat));
+    return Dune::range(hybrid_num_rows(mat));
   }
 
 
@@ -141,39 +145,42 @@ namespace AMDiS
   {
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<5>)
+    auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<5>)
       -> decltype(mat.num_rows()) { return mat.num_cols(); }
 
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<4>)
+    auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<4>)
       -> decltype(mat.M()) { return mat.M(); }
 
     template <class Matrix,
       REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<3>)
+    auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<3>)
       -> decltype(mat.cols()) { return mat.cols(); }
 
     template <class Matrix,
-      REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    constexpr index_t<Matrix::cols> hybridNumCols(Matrix const& mat, Dune::PriorityTag<2>) { return {}; }
+      REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
+    auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<2>)
+      -> decltype(num_cols(mat)) { return num_cols(mat); }
 
-    template <class Matrix,
-      REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
-    constexpr Cols_t<Matrix> hybridNumCols(Matrix const& mat, Dune::PriorityTag<1>) { return {}; }
+    template <class Matrix>
+    auto hybrid_num_cols(Matrix const& mat, Dune::PriorityTag<0>)
+    {
+      return AMDiS::static_num_cols(mat);
+    }
 
   } // end namespace Impl
 
   template <class Matrix>
-  auto hybridNumCols(Matrix const& mat)
+  auto hybrid_num_cols(Matrix const& mat)
   {
-    return Impl::hybridNumCols(mat, Dune::PriorityTag<42>{});
+    return Impl::hybrid_num_cols(mat, Dune::PriorityTag<42>{});
   }
 
   template <class Matrix>
   auto hybridCols(Matrix const& mat)
   {
-    return Dune::range(hybridNumCols(mat));
+    return Dune::range(hybrid_num_cols(mat));
   }
 
 #endif // DOXYGEN
diff --git a/src/amdis/common/MultiTypeMatrix.hpp b/src/amdis/common/MultiTypeMatrix.hpp
index e8a46ec8..a3a56828 100644
--- a/src/amdis/common/MultiTypeMatrix.hpp
+++ b/src/amdis/common/MultiTypeMatrix.hpp
@@ -72,7 +72,7 @@ namespace AMDiS
     /// Assignment of real number to all tuple elements
     MultiTypeMatrix& operator=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv = value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv = value; });
       return *this;
     }
 
@@ -93,44 +93,44 @@ namespace AMDiS
     // Scaling of all tuple elements by a constant value
     MultiTypeMatrix& operator*=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv *= value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv *= value; });
       return *this;
     }
 
     // Scaling of all tuple elements by the inverse of a constant value
     MultiTypeMatrix& operator/=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv /= value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv /= value; });
       return *this;
     }
 
     /// Const access to the tuple elements
     template <std::size_t I, std::size_t J>
-    decltype(auto) operator()(const index_t<I>&, const index_t<J>&) const
+    decltype(auto) operator()(index_t<I> const i, index_t<J> const j) const
     {
-      return std::get<J>(std::get<I>(*this));
+      return (*this)[i][j];
     }
 
     /// Mutable access to the tuple elements
     template <std::size_t I, std::size_t J>
-    decltype(auto) operator()(const index_t<I>&, const index_t<J>&)
+    decltype(auto) operator()(index_t<I> const i, index_t<J> const j)
     {
-      return std::get<J>(std::get<I>(*this));
+      return (*this)[i][j];
     }
 
 
     /// Const access to the rows
     template <std::size_t I>
-    decltype(auto) operator[](const index_t<I>&) const
+    decltype(auto) operator[](index_t<I> const) const
     {
-      return std::get<I>(*this);
+      return std::get<I>(as_tuple());
     }
 
     /// Mutable access to the rows
     template <std::size_t I>
-    decltype(auto) operator[](const index_t<I>&)
+    decltype(auto) operator[](index_t<I> const)
     {
-      return std::get<I>(*this);
+      return std::get<I>(as_tuple());
     }
 
     /// Return number of elements of the tuple
@@ -149,17 +149,10 @@ namespace AMDiS
     {
       return rows;
     }
-  };
 
-  namespace Impl
-  {
-    template <class... Rows>
-    struct RowsImpl<MultiTypeMatrix<Rows...>>
-        : std::integral_constant<std::size_t, sizeof...(Rows) > {};
-
-    template <class Row0, class... Rows>
-    struct ColsImpl<MultiTypeMatrix<Row0, Rows...>>
-        : SizeImpl<Row0> {};
-  }
+  private:
+    std::tuple<Rows...>&       as_tuple()       { return *this; }
+    std::tuple<Rows...> const& as_tuple() const { return *this; }
+  };
 
 } // end namespace AMDiS
diff --git a/src/amdis/common/MultiTypeVector.hpp b/src/amdis/common/MultiTypeVector.hpp
index 7bec7543..72345347 100644
--- a/src/amdis/common/MultiTypeVector.hpp
+++ b/src/amdis/common/MultiTypeVector.hpp
@@ -65,50 +65,50 @@ namespace AMDiS
     /// Assignment of real number to all tuple elements
     MultiTypeVector& operator=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv = value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv = value; });
       return *this;
     }
 
     // Compound assignment operator +=
     MultiTypeVector& operator+=(MultiTypeVector const& that)
     {
-      Tools::for_range<0,dimension>([&that,this](auto const _i) { (*this)[_i] += that[_i]; });
+      Tools::for_range<0,dimension>([&that,this](auto const i) { (*this)[i] += that[i]; });
       return *this;
     }
 
     // Compound assignment operator -=
     MultiTypeVector& operator-=(MultiTypeVector const& that)
     {
-      Tools::for_range<0,dimension>([&that,this](auto const _i) { (*this)[_i] -= that[_i]; });
+      Tools::for_range<0,dimension>([&that,this](auto const i) { (*this)[i] -= that[i]; });
       return *this;
     }
 
     // Scaling of all tuple elements by a constant value
     MultiTypeVector& operator*=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv *= value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv *= value; });
       return *this;
     }
 
     // Scaling of all tuple elements by the inverse of a constant value
     MultiTypeVector& operator/=(real_type value)
     {
-      Tools::for_each(*this, [value](auto& fv) { fv /= value; });
+      Tools::for_each(as_tuple(), [value](auto& fv) { fv /= value; });
       return *this;
     }
 
     /// Const access to the tuple elements
     template <std::size_t I>
-    decltype(auto) operator[](const index_t<I>&) const
+    decltype(auto) operator[](index_t<I> const) const
     {
-      return std::get<I>(*this);
+      return std::get<I>(as_tuple());
     }
 
     /// Mutable access to the tuple elements
     template <std::size_t I>
-    decltype(auto) operator[](const index_t<I>&)
+    decltype(auto) operator[](index_t<I> const)
     {
-      return std::get<I>(*this);
+      return std::get<I>(as_tuple());
     }
 
     /// Const access to the vector using multi-indices
@@ -132,13 +132,10 @@ namespace AMDiS
     {
       return dimension;
     }
-  };
 
-  namespace Impl
-  {
-    template <class... Ts>
-    struct SizeImpl<MultiTypeVector<Ts...>>
-        : std::integral_constant<std::size_t, sizeof...(Ts) > {};
-  }
+  private:
+    std::tuple<FV...>&       as_tuple()       { return *this; }
+    std::tuple<FV...> const& as_tuple() const { return *this; }
+  };
 
 } // end namespace AMDiS
diff --git a/src/amdis/common/QuadMath.hpp b/src/amdis/common/QuadMath.hpp
index 1c0ba7e0..c954831b 100644
--- a/src/amdis/common/QuadMath.hpp
+++ b/src/amdis/common/QuadMath.hpp
@@ -86,15 +86,24 @@ namespace AMDiS
   {
     template <>
     struct SizeImpl<Dune::Float128>
-        : std::integral_constant<std::size_t, 1> {};
+    {
+      static constexpr auto eval(Dune::Float128)
+        -> std::integral_constant<std::size_t, 1> { return {}; }
+    };
 
     template <>
-    struct RowsImpl<Dune::Float128>
-        : std::integral_constant<std::size_t, 1> {};
+    struct NumRowsImpl<Dune::Float128>
+    {
+      static constexpr auto eval(Dune::Float128)
+        -> std::integral_constant<std::size_t, 1> { return {}; }
+    };
 
     template <>
-    struct ColsImpl<Dune::Float128>
-        : std::integral_constant<std::size_t, 1> {};
+    struct NumColsImpl<Dune::Float128>
+    {
+      static constexpr auto eval(Dune::Float128)
+        -> std::integral_constant<std::size_t, 1> { return {}; }
+    };
 
   } // end namespace Impl
 
diff --git a/src/amdis/common/Range.hpp b/src/amdis/common/Range.hpp
index 6464a002..62477776 100644
--- a/src/amdis/common/Range.hpp
+++ b/src/amdis/common/Range.hpp
@@ -39,11 +39,6 @@ namespace AMDiS
     template <std::size_t I, class Int, Int begin, Int end>
     constexpr auto get(range_impl<Int, begin, end> const& r) { return r[index_<I>]; }
 
-    /// Return the size of the range
-    template <class Int, Int I, Int J>
-    struct SizeImpl<range_impl<Int,I,J>>
-        : std::integral_constant<std::size_t, std::size_t(J-I)> {};
-
   } // end namespace Impl
 
   template <std::size_t I, std::size_t J>
diff --git a/src/amdis/common/StaticSize.hpp b/src/amdis/common/StaticSize.hpp
index 187880c2..dca64234 100644
--- a/src/amdis/common/StaticSize.hpp
+++ b/src/amdis/common/StaticSize.hpp
@@ -4,152 +4,276 @@
 #include <tuple>
 #include <type_traits>
 
+#include <dune/common/typeutilities.hh>
 #include <amdis/common/TypeTraits.hpp>
 
-namespace Dune
-{
-  // forward declarations
-  template <class T, int N, int M>
-  class FieldMatrix;
-
-  template <class T, int N>
-  class FieldVector;
-
-  template <class... Ts>
-  class TupleVector;
-
-  template <class Row0, class... Rows>
-  class MultiTypeBlockMatrix;
-
-  template <class... Ts>
-  class MultiTypeBlockVector;
-}
-
-namespace Eigen
-{
-  template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-  class Matrix;
-}
+#if HAVE_MTL
+#include <boost/numeric/mtl/operation/static_size.hpp>
+#endif
 
 namespace AMDiS
 {
   namespace Impl
   {
-    template <class Tuple, class = void>
-    struct SizeImpl : std::integral_constant<std::size_t, 0> {};
-
-    template <class... Args>
-    struct SizeImpl<std::tuple<Args...>>
-        : std::integral_constant<std::size_t, sizeof...(Args) > {};
-
-    template <class Arg0, class Arg1>
-    struct SizeImpl<std::pair<Arg0, Arg1>>
-        : std::integral_constant<std::size_t, 2> {};
-
-    template <class T, std::size_t N>
-    struct SizeImpl<std::array<T,N>>
-        : std::integral_constant<std::size_t, N> {};
-
-    template <class T, int N>
-    struct SizeImpl<Dune::FieldVector<T,N>>
-        : std::integral_constant<std::size_t, N> {};
-
-    template <class T, int N, int M>
-    struct SizeImpl<Dune::FieldMatrix<T,N,M>>
-        : std::integral_constant<std::size_t, N*M> {};
-
-    template <class... Ts>
-    struct SizeImpl<Dune::TupleVector<Ts...>>
-        : std::integral_constant<std::size_t, sizeof...(Ts)> {};
-
-    template <class... Ts>
-    struct SizeImpl<Dune::MultiTypeBlockVector<Ts...>>
-        : std::integral_constant<std::size_t, sizeof...(Ts)> {};
-
-    template <class T, int N, int... opts>
-    struct SizeImpl<Eigen::Matrix<T,N,1,opts...>>
-        : std::integral_constant<std::size_t, (N >= 0 ? std::size_t(N) : 0u)> {};
-
-    template <class T, int N, int... opts>
-    struct SizeImpl<Eigen::Matrix<T,1,N,opts...>>
-        : std::integral_constant<std::size_t, (N >= 0 ? std::size_t(N) : 0u)> {};
-
-    // Specialization for arithmetic types
-    template <class T>
-    struct SizeImpl<T, std::enable_if_t<std::is_arithmetic<T>::value> >
-        : std::integral_constant<std::size_t, 1> {};
+    template <class Container>
+    struct SizeImpl
+    {
+#if HAVE_MTL
+      // MTL4: Try if a mtl::static_size is specialized for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<6>)
+        -> decltype(std::integral_constant<std::size_t,(mtl::static_num_rows<T>::value * mtl::static_num_cols<T>::value)>{})
+      {
+        return {};
+      }
+#endif
+
+      // Eigen: Try if a static SizeAtCompileTime constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<5>)
+        -> decltype(std::integral_constant<std::size_t,T::SizeAtCompileTime>{})
+      {
+        return {};
+      }
+
+      // Try if tuple_size is implemented for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<4>)
+        -> decltype(std::integral_constant<std::size_t,std::tuple_size<T>::value>{})
+      {
+        return {};
+      }
+
+      // Try if a static dimension constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<3>)
+        -> decltype(std::integral_constant<std::size_t,T::dimension>{})
+      {
+        return {};
+      }
+
+      // Try if a static rows and cols constants are specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<2>)
+        -> decltype(std::integral_constant<std::size_t,(T::rows * T::cols)>{})
+      {
+        return {};
+      }
+
+      // Try if there's a static constexpr size()
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<1>)
+        -> decltype(std::integral_constant<std::size_t,T::size()>{})
+      {
+        return {};
+      }
+
+      // Arithmetic types have size 1 otherwise size is 0
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<0>)
+        -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic<T>::value ? 1 : 0)>{})
+      {
+        return {};
+      }
+
+      static constexpr auto eval(Container const& container)
+      {
+        return eval(container, Dune::PriorityTag<42>{});
+      }
+    };
 
   } // end namespace Impl
 
-  /// Get the number of elements in a tuple / pair / array / ...
-  template <class T>
-  constexpr std::size_t Size_v = Impl::SizeImpl<remove_cvref_t<T>>::value;
-
-  template <class T>
-  using Size_t = Impl::SizeImpl<remove_cvref_t<T>>;
 
-
-  namespace Impl
+  /**
+  * \brief Return a static constant size of the container
+  *
+  * \param container Container whose size is queried
+  * \return Size of t
+  *
+  * If the size of t is known at compile time the size is
+  * returned as std::integral_constant<std::size_t, size>.
+  * Otherwise 0 is returned by default, or 1 for arithmetic types.
+  */
+  template <class Container>
+  constexpr auto static_size(Container const& container)
   {
-    template <class Tuple, class = void>
-    struct RowsImpl : std::integral_constant<std::size_t, 0> {};
+    return Impl::SizeImpl<Container>::eval(container);
+  }
 
-    template <class T, int N, int M>
-    struct RowsImpl<Dune::FieldMatrix<T,N,M>>
-        : std::integral_constant<std::size_t, N> {};
+  template <class Container>
+  constexpr std::size_t static_size_v
+    = decltype(static_size(std::declval<remove_cvref_t<Container>>()))::value;
 
-    template <class... Rows>
-    struct RowsImpl<Dune::MultiTypeBlockMatrix<Rows...>>
-        : std::integral_constant<std::size_t, sizeof...(Rows)> {};
+  template <class T, std::size_t S0, std::size_t S1 = static_size_v<T>>
+  struct CheckSize
+  {
+    static_assert(S0 == S1, "Non-matching size");
+  };
 
-    // Specialization for arithmetic types
-    template <class T>
-    struct RowsImpl<T, std::enable_if_t<std::is_arithmetic<T>::value> >
-        : std::integral_constant<std::size_t, 1> {};
 
-    template <class T, int N, int M, int... opts>
-    struct RowsImpl<Eigen::Matrix<T,N,M,opts...>>
-        : std::integral_constant<std::size_t, (N >= 0 ? std::size_t(N) : 0u)> {};
+  namespace Impl
+  {
+    template <class Matrix>
+    struct NumRowsImpl
+    {
+#if HAVE_MTL
+      // MTL4: Try if a mtl::static_num_rows is specialized for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<4>)
+        -> decltype(std::integral_constant<std::size_t,mtl::static_num_rows<T>::value>{})
+      {
+        return {};
+      }
+#endif
+
+      // Eigen: Try if a static RowsAtCompileTime constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<3>)
+        -> decltype(std::integral_constant<std::size_t,T::RowsAtCompileTime>{})
+      {
+        return {};
+      }
+
+      // Try if a static rows constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<2>)
+        -> decltype(std::integral_constant<std::size_t,T::rows>{})
+      {
+        return {};
+      }
+
+      // Try if there's a static constexpr N()
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<1>)
+        -> decltype(std::integral_constant<std::size_t,T::N()>{})
+      {
+        return {};
+      }
+
+      // Fallback-size is 1 for arithmetic types or 0
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<0>)
+        -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic<T>::value ? 1 : 0)>{})
+      {
+        return {};
+      }
+
+      static constexpr auto eval(Matrix const& matrix)
+      {
+        return eval(matrix, Dune::PriorityTag<42>{});
+      }
+    };
 
   } // end namespace Impl
 
-  /// Get the number of rows in a fixed-size matrix
-  template <class T>
-  constexpr std::size_t Rows_v = Impl::RowsImpl<remove_cvref_t<T>>::value;
 
-  template <class T>
-  using Rows_t = Impl::RowsImpl<remove_cvref_t<T>>;
+  /**
+  * \brief Return a static constant rows of the matrix
+  *
+  * \param container Matrix whose number of rows is queried
+  * \return Number of rows of matrix
+  *
+  * If the size of t is known at compile time the number of rows is
+  * returned as std::integral_constant<std::size_t, size>.
+  * Otherwise 0 is returned by default, or 1 for arithmetic types.
+  */
+  template <class Matrix>
+  constexpr auto static_num_rows(Matrix const& matrix)
+  {
+    return Impl::NumRowsImpl<Matrix>::eval(matrix);
+  }
+
+  template <class Matrix>
+  constexpr std::size_t static_num_rows_v
+    = decltype(static_num_rows(std::declval<remove_cvref_t<Matrix>>()))::value;
 
+  template <class T, std::size_t S0, std::size_t S1 = static_num_rows<T>>
+  struct CheckNumRows
+  {
+    static_assert(S0 == S1, "Non-matching num rows");
+  };
 
   namespace Impl
   {
-    template <class Tuple, class = void>
-    struct ColsImpl : std::integral_constant<std::size_t, 0> {};
-
-    template <class T, int N, int M>
-    struct ColsImpl<Dune::FieldMatrix<T,N,M>>
-        : std::integral_constant<std::size_t, M> {};
-
-    template <class Row0, class... Rows>
-    struct ColsImpl<Dune::MultiTypeBlockMatrix<Row0, Rows...>>
-        : SizeImpl<Row0> {};
+    template <class Matrix>
+    struct NumColsImpl
+    {
+#if HAVE_MTL
+      // MTL4: Try if a mtl::static_num_cols is specialized for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<4>)
+        -> decltype(std::integral_constant<std::size_t,mtl::static_num_cols<T>::value>{})
+      {
+        return {};
+      }
+#endif
+
+      // Eigen: Try if a static ColsAtCompileTime constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<3>)
+        -> decltype(std::integral_constant<std::size_t,T::ColsAtCompileTime>{})
+      {
+        return {};
+      }
+
+      // Try if a static cols constant is specified for class
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<2>)
+        -> decltype(std::integral_constant<std::size_t,T::cols>{})
+      {
+        return {};
+      }
+
+      // Try if there's a static constexpr M()
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<1>)
+        -> decltype(std::integral_constant<std::size_t,T::M()>{})
+      {
+        return {};
+      }
+
+      // Fallback-size is 0
+      template <class T>
+      static constexpr auto eval(T const&, Dune::PriorityTag<0>)
+        -> decltype(std::integral_constant<std::size_t, (std::is_arithmetic<T>::value ? 1 : 0)>{})
+      {
+        return {};
+      }
+
+      static constexpr auto eval(Matrix const& matrix)
+      {
+        return eval(matrix, Dune::PriorityTag<42>{});
+      }
+    };
 
-    // Specialization for arithmetic types
-    template <class T>
-    struct ColsImpl<T, std::enable_if_t<std::is_arithmetic<T>::value> >
-        : std::integral_constant<std::size_t, 1> {};
+  } // end namespace Impl
 
-    template <class T, int N, int M, int... opts>
-    struct ColsImpl<Eigen::Matrix<T,N,M,opts...>>
-        : std::integral_constant<std::size_t, (M >= 0 ? std::size_t(M) : 0u)> {};
 
-  } // end namespace Impl
+  /**
+  * \brief Return a static constant columns of the matrix
+  *
+  * \param container Matrix whose number of columns is queried
+  * \return Number of columns of matrix
+  *
+  * If the size of matrix is known at compile time the number if cols is
+  * returned as std::integral_constant<std::size_t, size>.
+  * Otherwise 0 is returned by default, or 1 for arithmetic types.
+  */
+  template <class Matrix>
+  constexpr auto static_num_cols(Matrix const& matrix)
+  {
+    return Impl::NumColsImpl<Matrix>::eval(matrix);
+  }
 
-  /// Get the number of columns in a fixed-size matrix
-  template <class T>
-  constexpr std::size_t Cols_v = Impl::ColsImpl<remove_cvref_t<T>>::value;
+  template <class Matrix>
+  constexpr std::size_t static_num_cols_v
+    = decltype(static_num_cols(std::declval<remove_cvref_t<Matrix>>()))::value;
 
-  template <class T>
-  using Cols_t = Impl::ColsImpl<remove_cvref_t<T>>;
+  template <class T, std::size_t S0, std::size_t S1 = static_num_cols<T>>
+  struct CheckNumCols
+  {
+    static_assert(S0 == S1, "Non-matching num rows");
+  };
 
 } // end namespace AMDiS
diff --git a/src/amdis/gridfunctions/DiscreteFunction.inc.hpp b/src/amdis/gridfunctions/DiscreteFunction.inc.hpp
index 7d52d04c..1a18c464 100644
--- a/src/amdis/gridfunctions/DiscreteFunction.inc.hpp
+++ b/src/amdis/gridfunctions/DiscreteFunction.inc.hpp
@@ -305,7 +305,7 @@ private:
 
   Range evaluate_node(Domain const& x, std::true_type) const
   {
-    static_assert(Size_v<Range> == 1, "Implemented for scalar coefficients only.");
+    static_assert(static_size_v<Range> == 1, "Implemented for scalar coefficients only.");
 
     assert( this->bound_ );
     Range dy(0);
diff --git a/src/amdis/io/VTKWriter.hpp b/src/amdis/io/VTKWriter.hpp
index d487ed56..c9b6bbab 100644
--- a/src/amdis/io/VTKWriter.hpp
+++ b/src/amdis/io/VTKWriter.hpp
@@ -51,7 +51,7 @@ namespace AMDiS
 
     template <class R>
     static constexpr std::size_t VTKFieldSize() {
-      return Size_v<R>;
+      return static_size_v<R>;
     }
 
   public:
diff --git a/src/amdis/localoperators/ConvectionDiffusionOperator.hpp b/src/amdis/localoperators/ConvectionDiffusionOperator.hpp
index d38a558e..247c0b58 100644
--- a/src/amdis/localoperators/ConvectionDiffusionOperator.hpp
+++ b/src/amdis/localoperators/ConvectionDiffusionOperator.hpp
@@ -27,16 +27,16 @@ namespace AMDiS
     static const int dow = ContextGeometry<LC>::dow;
 
     using A_range = typename GridFctA::Range;
-    static_assert( Size_v<A_range> == 1 || (Rows_v<A_range> == dow && Cols_v<A_range> == dow),
+    static_assert( static_size_v<A_range> == 1 || (static_num_rows_v<A_range> == dow && static_num_cols_v<A_range> == dow),
       "Expression A(x) must be of scalar or matrix type." );
     using b_range = typename GridFctB::Range;
-    static_assert( Size_v<b_range> == 1 || Size_v<b_range> == dow,
+    static_assert( static_size_v<b_range> == 1 || static_size_v<b_range> == dow,
       "Expression b(x) must be of scalar or vector type." );
     using c_range = typename GridFctC::Range;
-    static_assert( Size_v<c_range> == 1,
+    static_assert( static_size_v<c_range> == 1,
       "Expression c(x) must be of scalar type." );
     using f_range = typename GridFctF::Range;
-    static_assert( Size_v<f_range> == 1,
+    static_assert( static_size_v<f_range> == 1,
       "Expression f(x) must be of scalar type." );
 
   public:
diff --git a/src/amdis/localoperators/FirstOrderDivTestvec.hpp b/src/amdis/localoperators/FirstOrderDivTestvec.hpp
index fd749e47..07f1718b 100644
--- a/src/amdis/localoperators/FirstOrderDivTestvec.hpp
+++ b/src/amdis/localoperators/FirstOrderDivTestvec.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::divtestvec, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderGradTest.hpp b/src/amdis/localoperators/FirstOrderGradTest.hpp
index 150cbc0d..51818a85 100644
--- a/src/amdis/localoperators/FirstOrderGradTest.hpp
+++ b/src/amdis/localoperators/FirstOrderGradTest.hpp
@@ -29,7 +29,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
+    static_assert( static_size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
 
   public:
     GridFunctionOperator(tag::gradtest, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderPartialTest.hpp b/src/amdis/localoperators/FirstOrderPartialTest.hpp
index eb0192ef..db665e4b 100644
--- a/src/amdis/localoperators/FirstOrderPartialTest.hpp
+++ b/src/amdis/localoperators/FirstOrderPartialTest.hpp
@@ -29,7 +29,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::partialtest tag, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderTestDivTrialvec.hpp b/src/amdis/localoperators/FirstOrderTestDivTrialvec.hpp
index 94ca60f9..860c7f27 100644
--- a/src/amdis/localoperators/FirstOrderTestDivTrialvec.hpp
+++ b/src/amdis/localoperators/FirstOrderTestDivTrialvec.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::test_divtrialvec, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderTestGradTrial.hpp b/src/amdis/localoperators/FirstOrderTestGradTrial.hpp
index f59f7e39..750995cf 100644
--- a/src/amdis/localoperators/FirstOrderTestGradTrial.hpp
+++ b/src/amdis/localoperators/FirstOrderTestGradTrial.hpp
@@ -30,7 +30,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
+    static_assert( static_size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
 
   public:
     GridFunctionOperator(tag::test_gradtrial, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp b/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp
index 08a5c6f5..71161ba8 100644
--- a/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp
+++ b/src/amdis/localoperators/FirstOrderTestPartialTrial.hpp
@@ -36,7 +36,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::test_partialtrial tag, GridFct const& expr)
diff --git a/src/amdis/localoperators/FirstOrderTestvecGradTrial.hpp b/src/amdis/localoperators/FirstOrderTestvecGradTrial.hpp
index 53865860..921fb8cb 100644
--- a/src/amdis/localoperators/FirstOrderTestvecGradTrial.hpp
+++ b/src/amdis/localoperators/FirstOrderTestvecGradTrial.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::testvec_gradtrial, GridFct const& expr)
diff --git a/src/amdis/localoperators/SecondOrderDivTestvecDivTrialvec.hpp b/src/amdis/localoperators/SecondOrderDivTestvecDivTrialvec.hpp
index 25692c7f..7bac4c6b 100644
--- a/src/amdis/localoperators/SecondOrderDivTestvecDivTrialvec.hpp
+++ b/src/amdis/localoperators/SecondOrderDivTestvecDivTrialvec.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::divtestvec_divtrialvec, GridFct const& expr)
diff --git a/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp b/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp
index 29b71ec0..94418c3b 100644
--- a/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp
+++ b/src/amdis/localoperators/SecondOrderGradTestGradTrial.hpp
@@ -31,7 +31,7 @@ namespace AMDiS
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
     using expr_value_type = typename GridFct::Range;
-    static_assert( Size_v<expr_value_type> == 1 || (Rows_v<expr_value_type> == dow && Cols_v<expr_value_type> == dow),
+    static_assert( static_size_v<expr_value_type> == 1 || (static_num_rows_v<expr_value_type> == dow && static_num_cols_v<expr_value_type> == dow),
       "Expression must be of scalar or matrix type." );
 
   public:
diff --git a/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp b/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp
index 1724a6a9..0d0a1352 100644
--- a/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp
+++ b/src/amdis/localoperators/SecondOrderPartialTestPartialTrial.hpp
@@ -32,7 +32,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::partialtest_partialtrial tag, GridFct const& expr)
diff --git a/src/amdis/localoperators/StokesOperator.hpp b/src/amdis/localoperators/StokesOperator.hpp
index 1591f37c..6d5234bf 100644
--- a/src/amdis/localoperators/StokesOperator.hpp
+++ b/src/amdis/localoperators/StokesOperator.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, ViscosityExpr>;
 
-    static_assert( Size_v<typename ViscosityExpr::Range> == 1, "Viscosity must be of scalar type." );
+    static_assert( static_size_v<typename ViscosityExpr::Range> == 1, "Viscosity must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::stokes, ViscosityExpr const& expr, bool constViscosity = false)
diff --git a/src/amdis/localoperators/ZeroOrderTest.hpp b/src/amdis/localoperators/ZeroOrderTest.hpp
index a064d44f..54ac1e9b 100644
--- a/src/amdis/localoperators/ZeroOrderTest.hpp
+++ b/src/amdis/localoperators/ZeroOrderTest.hpp
@@ -27,7 +27,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::test, GridFct const& expr)
diff --git a/src/amdis/localoperators/ZeroOrderTestTrial.hpp b/src/amdis/localoperators/ZeroOrderTestTrial.hpp
index a9f4687b..7947c90b 100644
--- a/src/amdis/localoperators/ZeroOrderTestTrial.hpp
+++ b/src/amdis/localoperators/ZeroOrderTestTrial.hpp
@@ -27,7 +27,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
+    static_assert( static_size_v<typename GridFct::Range> == 1, "Expression must be of scalar type." );
 
   public:
     GridFunctionOperator(tag::test_trial, GridFct const& expr)
diff --git a/src/amdis/localoperators/ZeroOrderTestTrialvec.hpp b/src/amdis/localoperators/ZeroOrderTestTrialvec.hpp
index 95e7761f..e3e3bf7a 100644
--- a/src/amdis/localoperators/ZeroOrderTestTrialvec.hpp
+++ b/src/amdis/localoperators/ZeroOrderTestTrialvec.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
+    static_assert( static_size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
 
   public:
     GridFunctionOperator(tag::test_trialvec, GridFct const& expr)
@@ -42,7 +42,7 @@ namespace AMDiS
         "RN must be Leaf-Node and CN must be a Power-Node.");
 
       static const std::size_t CHILDREN = CN::CHILDREN;
-      static_assert( Size_v<typename GridFct::Range> == CHILDREN, "" );
+      static_assert( static_size_v<typename GridFct::Range> == CHILDREN, "" );
 
       auto const& quad = this->getQuadratureRule(contextGeo.type(), rowNode, colNode);
       auto const& rowLocalFE = rowNode.finiteElement();
diff --git a/src/amdis/localoperators/ZeroOrderTestvec.hpp b/src/amdis/localoperators/ZeroOrderTestvec.hpp
index 4b09b688..64651a7b 100644
--- a/src/amdis/localoperators/ZeroOrderTestvec.hpp
+++ b/src/amdis/localoperators/ZeroOrderTestvec.hpp
@@ -28,7 +28,7 @@ namespace AMDiS
     using Self = GridFunctionOperator;
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
-    static_assert( Size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
+    static_assert( static_size_v<typename GridFct::Range> == dow, "Expression must be of vector type." );
 
   public:
     GridFunctionOperator(tag::testvec, GridFct const& expr)
diff --git a/src/amdis/localoperators/ZeroOrderTestvecTrialvec.hpp b/src/amdis/localoperators/ZeroOrderTestvecTrialvec.hpp
index 2d04c6f3..4fa41337 100644
--- a/src/amdis/localoperators/ZeroOrderTestvecTrialvec.hpp
+++ b/src/amdis/localoperators/ZeroOrderTestvecTrialvec.hpp
@@ -30,7 +30,7 @@ namespace AMDiS
     using Super = GridFunctionOperatorBase<Self, LC, GridFct>;
 
     using expr_value_type = typename GridFct::Range;
-    static_assert( Size_v<expr_value_type> == 1 || (Rows_v<expr_value_type> == dow && Cols_v<expr_value_type> == dow),
+    static_assert( static_size_v<expr_value_type> == 1 || (static_num_rows_v<expr_value_type> == dow && static_num_cols_v<expr_value_type> == dow),
       "Expression must be of scalar or matrix type." );
 
   public:
@@ -154,7 +154,7 @@ namespace AMDiS
                                   Mat& elementMatrix, tag::matrix)
     {
       static const std::size_t CHILDREN = RN::CHILDREN;
-      static_assert(Rows_v<expr_value_type> == CHILDREN && Cols_v<expr_value_type> == CHILDREN, "" );
+      static_assert(static_num_rows_v<expr_value_type> == CHILDREN && static_num_cols_v<expr_value_type> == CHILDREN, "" );
 
       auto const& rowLocalFE = rowNode.child(0).finiteElement();
       auto const& colLocalFE = colNode.child(0).finiteElement();
diff --git a/test/HybridSizeTest.cpp b/test/HybridSizeTest.cpp
index 1a270382..7fbc9006 100644
--- a/test/HybridSizeTest.cpp
+++ b/test/HybridSizeTest.cpp
@@ -62,10 +62,10 @@ int main(int argc, char** argv)
   Vec1 vec1;
   Vec2 vec2;
 
-  AMDIS_TEST_EQ(std::size_t(hybridSize(vec1)),2);
-  AMDIS_TEST_EQ(std::size_t(hybridSize(vec2)),1);
+  AMDIS_TEST_EQ(std::size_t(hybrid_size(vec1)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_size(vec2)),1);
 
-  auto s = hybridSize(vec2);
+  auto s = hybrid_size(vec2);
   static_assert(VALUE(s) == 1, "");
 
   Mat1 mat1;
@@ -73,20 +73,20 @@ int main(int argc, char** argv)
   Mat3 mat3;
   Mat4 mat4;
 
-  AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat1)),2);
-  AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat1)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_rows(mat1)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_cols(mat1)),2);
 
-  AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat2)),2);
-  AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat2)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_rows(mat2)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_cols(mat2)),2);
 
-  AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat3)),2);
-  AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat3)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_rows(mat3)),2);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_cols(mat3)),2);
 
-  AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat4)),1);
-  AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat4)),1);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_rows(mat4)),1);
+  AMDIS_TEST_EQ(std::size_t(hybrid_num_cols(mat4)),1);
 
-  auto r = hybridNumRows(mat4);
-  auto c = hybridNumCols(mat4);
+  auto r = hybrid_num_rows(mat4);
+  auto c = hybrid_num_cols(mat4);
   static_assert(VALUE(r) == 1, "");
   static_assert(VALUE(c) == 1, "");
 
diff --git a/test/StaticSizeTest.cpp b/test/StaticSizeTest.cpp
index 0931fda7..9ef7284e 100644
--- a/test/StaticSizeTest.cpp
+++ b/test/StaticSizeTest.cpp
@@ -20,12 +20,12 @@ int main(int argc, char** argv)
 {
   Environment env(argc, argv);
 
-  static_assert(Size_v<double> == 1, "");
-  static_assert(Rows_v<double> == 1, "");
-  static_assert(Cols_v<double> == 1, "");
-  static_assert(Size_v<Null> == 0, "");
-  static_assert(Rows_v<Null> == 0, "");
-  static_assert(Cols_v<Null> == 0, "");
+  static_assert(static_size_v<double> == 1, "");
+  static_assert(static_num_rows_v<double> == 1, "");
+  static_assert(static_num_cols_v<double> == 1, "");
+  static_assert(static_size_v<Null> == 0, "");
+  static_assert(static_num_rows_v<Null> == 0, "");
+  static_assert(static_num_cols_v<Null> == 0, "");
 
   using Vec1 = Dune::FieldVector<double,2>;
   using Vec2 = Dune::MultiTypeBlockVector<double,double>;
@@ -33,34 +33,34 @@ int main(int argc, char** argv)
   using Vec4 = std::tuple<double,double>;
   using Vec5 = Dune::TupleVector<double,double>;
 
-  static_assert(Size_v<Vec1> == 2, "");
-  static_assert(Size_v<Vec2> == 2, "");
-  static_assert(Size_v<Vec3> == 2, "");
-  static_assert(Size_v<Vec4> == 2, "");
-  static_assert(Size_v<Vec5> == 2, "");
+  static_assert(static_size_v<Vec1> == 2, "");
+  static_assert(static_size_v<Vec2> == 2, "");
+  static_assert(static_size_v<Vec3> == 2, "");
+  static_assert(static_size_v<Vec4> == 2, "");
+  static_assert(static_size_v<Vec5> == 2, "");
 
   using Mat1 = Dune::FieldMatrix<double,2,2>;
   using Mat2 = Dune::MultiTypeBlockMatrix<Vec2,Vec2>;
 
-  static_assert(Rows_v<Mat1> == 2, "");
-  static_assert(Cols_v<Mat1> == 2, "");
-  static_assert(Rows_v<Mat2> == 2, "");
-  static_assert(Cols_v<Mat2> == 2, "");
+  static_assert(static_num_rows_v<Mat1> == 2, "");
+  static_assert(static_num_cols_v<Mat1> == 2, "");
+  static_assert(static_num_rows_v<Mat2> == 2, "");
+  static_assert(static_num_cols_v<Mat2> == 2, "");
 
 #if HAVE_EIGEN
   using Vec6 = Eigen::Vector2d;
   using Vec7 = Eigen::Matrix<double,2,1>;
   using Vec8 = Eigen::Matrix<double,1,2>;
-  static_assert(Size_v<Vec6> == 2, "");
-  static_assert(Size_v<Vec7> == 2, "");
-  static_assert(Size_v<Vec8> == 2, "");
+  static_assert(static_size_v<Vec6> == 2, "");
+  static_assert(static_size_v<Vec7> == 2, "");
+  static_assert(static_size_v<Vec8> == 2, "");
 
   using Mat3 = Eigen::Matrix2d;
   using Mat4 = Eigen::Matrix<double,2,2>;
-  static_assert(Rows_v<Mat3> == 2, "");
-  static_assert(Cols_v<Mat3> == 2, "");
-  static_assert(Rows_v<Mat4> == 2, "");
-  static_assert(Cols_v<Mat4> == 2, "");
+  static_assert(static_num_rows_v<Mat3> == 2, "");
+  static_assert(static_num_cols_v<Mat3> == 2, "");
+  static_assert(static_num_rows_v<Mat4> == 2, "");
+  static_assert(static_num_cols_v<Mat4> == 2, "");
 #endif
 
   return 0;
-- 
GitLab