diff --git a/cmake/modules/AddVcFlags.cmake b/cmake/modules/AddVcFlags.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0ca689adbb221979cae908a65c28548995753885
--- /dev/null
+++ b/cmake/modules/AddVcFlags.cmake
@@ -0,0 +1,31 @@
+# Defines the functions to use Vc
+#
+# Vc is a library for high-level Vectorization support in C++
+# see https://github.com/VcDevel/Vc
+#
+# .. cmake_function:: add_dune_vc_flags
+#
+#    .. cmake_param:: targets
+#       :positional:
+#       :single:
+#       :required:
+#
+#       A list of targets to use VC with.
+#
+
+function(add_dune_vc_flags _targets)
+  if(Vc_FOUND)
+    foreach(_target ${_targets})
+      target_link_libraries(${_target} ${Vc_LIBRARIES})
+      target_compile_options(${_target} PUBLIC ${Vc_ALL_FLAGS})
+      target_include_directories(${_target} SYSTEM PUBLIC ${Vc_INCLUDE_DIR})
+    endforeach(_target ${_targets})
+  endif(Vc_FOUND)
+endfunction(add_dune_vc_flags)
+
+if(Vc_FOUND)
+  dune_register_package_flags(COMPILE_OPTIONS "${Vc_ALL_FLAGS}"
+                              LIBRARIES "${Vc_LIBRARIES}"
+                              INCLUDE_DIRS "${Vc_INCLUDE_DIR}")
+endif(Vc_FOUND)
+set(HAVE_VC ${Vc_FOUND})
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index 9d0812e0ad4098d54eed1334448805929517fe0c..e8297679e3d13b779f78c05cf61a9abd0b9aafbd 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -5,6 +5,7 @@ install(FILES
   AddPTScotchFlags.cmake
   AddSuiteSparseFlags.cmake
   AddUMFPackFlags.cmake
+  AddVcFlags.cmake
   CheckCXXFeatures.cmake
   CheckForPthreads.c
   CMakeBuiltinFunctionsDocumentation.cmake
diff --git a/cmake/modules/DuneCommonMacros.cmake b/cmake/modules/DuneCommonMacros.cmake
index 6faa54a8952542da142784417e27b68a61db99e6..086f75698df71f2f4e7da7ea4e214cb7049e1311 100644
--- a/cmake/modules/DuneCommonMacros.cmake
+++ b/cmake/modules/DuneCommonMacros.cmake
@@ -24,3 +24,8 @@ include(AddGMPFlags)
 find_package(Inkscape)
 include(UseInkscape)
 include(FindMProtect)
+
+# try to find the Vc library
+find_package(Vc)
+include(AddVcFlags)
+set_package_info("Vc" "C++ Vectorization library" "https://github.com/VcDevel/Vc")
diff --git a/config.h.cmake b/config.h.cmake
index e34d1887c9a4c41a296c82dfc908469cdf95ae4d..6e1fd357d2a8f210f3977e7efa705015869816c9 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -45,6 +45,9 @@
    to facilitate activating and deactivating GMP using compile flags. */
 #cmakedefine HAVE_GMP ENABLE_GMP
 
+/* Define to 1 if you have the Vc library. */
+#cmakedefine HAVE_VC 1
+
 /* Define to 1 if you have the symbol mprotect. */
 #cmakedefine HAVE_MPROTECT 1
 
diff --git a/doc/doxygen/modules.txt b/doc/doxygen/modules.txt
index 3ff40607650c740d7d585df7f630bfefb63b2266..d70023de3b319c5b974b1d312eff76f5caebb12d 100644
--- a/doc/doxygen/modules.txt
+++ b/doc/doxygen/modules.txt
@@ -21,6 +21,15 @@
   @ingroup Utilities
 */
 
+/**
+ @defgroup RangeUtilities Range Utilities
+ @brief Utilities for reduction like operations on ranges
+
+ All these reduction operations work for appropriate ranges and scalar values
+
+ @ingroup Utilities
+*/
+
 /**
   @defgroup StringUtilities String Utilities
   @brief Utility functions for std::string
diff --git a/dune/common/CMakeLists.txt b/dune/common/CMakeLists.txt
index deadd0fb578fa8238090ca5efa2488211745d611..5b63b16237c22e8d4f4677d398bb90839d7cf0b4 100644
--- a/dune/common/CMakeLists.txt
+++ b/dune/common/CMakeLists.txt
@@ -34,6 +34,7 @@ install(FILES
         boundschecking.hh
         classname.hh
         concept.hh
+        conditional.hh
         debugallocator.hh
         debugstream.hh
         deprecated.hh
@@ -82,8 +83,10 @@ install(FILES
         propertymap.hh
         promotiontraits.hh
         proxymemberaccess.hh
+        rangeutilities.hh
         reservedvector.hh
         shared_ptr.hh
+        simd.hh
         singleton.hh
         sllist.hh
         stdstreams.hh
diff --git a/dune/common/conditional.hh b/dune/common/conditional.hh
new file mode 100644
index 0000000000000000000000000000000000000000..e4590f6845569ae969b41ef3cc63d395f6ca8cff
--- /dev/null
+++ b/dune/common/conditional.hh
@@ -0,0 +1,33 @@
+#ifndef DUNE_COMMON_CONDITIONAL_HH
+#define DUNE_COMMON_CONDITIONAL_HH
+
+namespace Dune
+{
+
+    /** \brief conditional evaluate
+
+        sometimes call immediate if, evaluates to
+
+        \code
+        if (b)
+           return v1;
+        else
+           return v2;
+        \endcode
+
+        In contrast to if-then-else the cond function can also be
+        evaluated for vector valued SIMD data types, see simd.hh.
+
+        \param b boolean value
+        \param v1 value of b==true
+        \param v2 value of b==false
+    */
+    template<typename T1, typename T2>
+    const T1 cond(bool b, const T1 & v1, const T2 & v2)
+    {
+        return (b ? v1 : v2);
+    }
+
+} // end namespace Dune
+
+#endif // DUNE_COMMON_CONDITIONAL_HH
diff --git a/dune/common/rangeutilities.hh b/dune/common/rangeutilities.hh
new file mode 100644
index 0000000000000000000000000000000000000000..09b44d266e2581f974a7a118118ffa17af902712
--- /dev/null
+++ b/dune/common/rangeutilities.hh
@@ -0,0 +1,114 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_COMMON_RANGE_UTILITIES_HH
+#define DUNE_COMMON_RANGE_UTILITIES_HH
+
+#include <dune/common/typetraits.hh>
+#include <utility>
+#include <type_traits>
+#include <bitset>
+
+/**
+ * \file
+ * \brief Utilities for reduction like operations on ranges
+ * \author Christian Engwer
+ */
+
+/**
+ * @addtogroup RangeUtilities
+ * @{
+ */
+
+namespace Dune
+{
+  /**
+     \brief compute the maximum value over a range
+
+     overloads for scalar values, and ranges exist
+  */
+  template <typename T,
+            typename std::enable_if<is_range<T>::value, int>::type = 0>
+  typename T::value_type
+  max_value(const T & v) {
+    using std::max;
+    typename T::value_type m;
+    for (const auto & e : v)
+      m = max(e,m);
+    return m;
+  };
+
+  template <typename T,
+            typename std::enable_if<!is_range<T>::value, int>::type = 0>
+  const T & max_value(const T & v) { return v; };
+
+  /**
+     \brief compute the minimum value over a range
+
+     overloads for scalar values, and ranges exist
+   */
+  template <typename T,
+            typename std::enable_if<is_range<T>::value, int>::type = 0>
+  typename T::value_type
+  min_value(const T & v) {
+    using std::min;
+    typename T::value_type m;
+    for (const auto & e : v)
+      m = min(e,m);
+    return m;
+  };
+
+  template <typename T,
+            typename std::enable_if<!is_range<T>::value, int>::type = 0>
+  T & min_value(const T & v) { return v; };
+
+  /**
+     \brief similar to std::bitset<N>::any() return true, if any entries is true
+
+     overloads for scalar values, ranges, and std::bitset<N> exist
+   */
+  template <typename T,
+            typename std::enable_if<is_range<T>::value, int>::type = 0>
+  bool any_true(const T & v) {
+    bool b = false;
+    for (const auto & e : v)
+      b = b or bool(e);
+    return b;
+  };
+
+  template <typename T,
+            typename std::enable_if<!is_range<T>::value, int>::type = 0>
+  bool any_true(const T & v) { return v; };
+
+  template<std::size_t N>
+  bool any_true(const std::bitset<N> & b)
+  {
+    return b.any();
+  }
+
+  /**
+     \brief similar to std::bitset<N>::all() return true, if any entries is true
+
+     overloads for scalar values, ranges, and std::bitset<N> exist
+   */
+  template <typename T,
+            typename std::enable_if<is_range<T>::value, int>::type = 0>
+  bool all_true(const T & v) {
+    bool b = true;
+    for (const auto & e : v)
+      b = b and bool(e);
+    return b;
+  };
+
+  template <typename T,
+            typename std::enable_if<!is_range<T>::value, int>::type = 0>
+  bool all_true(const T & v) { return v; };
+
+  template<std::size_t N>
+  bool all_true(const std::bitset<N> & b)
+  {
+    return b.all();
+  }
+
+}
+
+#endif // DUNE_COMMON_RANGE_UTILITIES_HH
diff --git a/dune/common/simd.hh b/dune/common/simd.hh
new file mode 100644
index 0000000000000000000000000000000000000000..f266559476473566fcbe15f5afc9996d84a93eac
--- /dev/null
+++ b/dune/common/simd.hh
@@ -0,0 +1,133 @@
+#ifndef DUNE_COMMON_SIMD_HH
+#define DUNE_COMMON_SIMD_HH
+
+/**
+   \file Abstractions for support of dedicated SIMD data types
+
+   Libraries like Vc (https://github.com/VcDevel/Vc) add high-level
+   data types for SIMD (or vectorization) support in C++.  Most of
+   these operations mimic the behavior of a numerical data type. Some
+   boolean operations can not be implemented in a compatible way to
+   trivial data types.
+
+   This header contains additional abstractions to help writing code
+   that works with trivial numericaldata types (like double) and Vc
+   vectorization data types.
+
+   See also the conditional.hh and range_utils.hh headers.
+ */
+
+#include <dune/common/rangeutilities.hh>
+#include <dune/common/conditional.hh>
+#if HAVE_VC
+#include <Vc/Vc>
+#endif
+
+namespace Dune
+{
+
+  template<typename T>
+  struct SimdScalarTypeTraits
+  {
+    using type = T;
+  };
+
+  template<typename T>
+  using SimdScalar = typename SimdScalarTypeTraits<T>::type;
+
+#if HAVE_VC
+  /*
+    Add Vc specializations for the SimdScalarTypeTraits trais class
+   */
+  template<typename T, typename A>
+  struct SimdScalarTypeTraits< Vc::Vector<T,A> >
+  {
+    using type = T;
+  };
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  struct SimdScalarTypeTraits< Vc::SimdArray<T,N,V,M> >
+  {
+    using type = T;
+  };
+#endif // HAVE_VC
+
+#if HAVE_VC
+  /*
+    Add Vc specializations for cond(), see conditional.hh
+   */
+  template<typename T, typename A>
+  Vc::Vector<T,A> cond(const Vc::Mask<T,A> & b,
+    const Vc::Vector<T,A> & v1,
+    const Vc::Vector<T,A> & v2)
+  {
+    return std::move(Vc::iif(b, v1, v2));
+  }
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  Vc::SimdArray<T,N,V,M> cond(const typename Vc::SimdArray<T,N,V,M>::mask_type & b,
+    const Vc::SimdArray<T,N,V,M> & v1,
+    const Vc::SimdArray<T,N,V,M> & v2)
+  {
+    return std::move(Vc::iif(b, v1, v2));
+  }
+#endif // HAVE_VC
+
+#if HAVE_VC
+  /*
+    Add Vc specializations for several boolean operations, see rangeutitlities.hh:
+
+    max_value, min_value, any_true, all_true
+   */
+  template<typename T, typename A>
+  T max_value(const Vc::Vector<T,A> & v)
+  {
+    return v.max();
+  }
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  double max_value(const Vc::SimdArray<T,N,V,M> & v)
+  {
+    return v.max();
+  }
+
+  template<typename T, typename A>
+  T min_value(const Vc::Vector<T,A> & v)
+  {
+    return v.min();
+  }
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  double min_value(const Vc::SimdArray<T,N,V,M> & v)
+  {
+    return v.min();
+  }
+
+  template<typename T, typename A>
+  bool any_true(const Vc::Mask<T,A> & v)
+  {
+    return Vc::any_of(v);
+  }
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  bool any_true(const Vc::SimdMaskArray<T,N,V,M> & v)
+  {
+    return Vc::any_of(v);
+  }
+
+  template<typename T, typename A>
+  bool all_true(const Vc::Mask<T,A> & v)
+  {
+    return Vc::all_of(v);
+  }
+
+  template<typename T, std::size_t N, typename V, std::size_t M>
+  bool all_true(const Vc::SimdMaskArray<T,N,V,M> & v)
+  {
+    return Vc::all_of(v);
+  }
+#endif // HAVE_VC
+
+} // end namespace Dune
+
+#endif // DUNE_COMMON_SIMD_HH
diff --git a/dune/common/typetraits.hh b/dune/common/typetraits.hh
index cbe30af9f945597860d83e8eafb827fa5c4130b3..10f19e8814a9aeacd3966e48cf0c4a3c595078f7 100644
--- a/dune/common/typetraits.hh
+++ b/dune/common/typetraits.hh
@@ -395,6 +395,25 @@ namespace Dune
 
 #endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
 
+  /**
+     typetrait to check that a class has begin() and end() members
+   */
+  // default version, gets picked if SFINAE fails
+  template<typename T, typename = void, typename = void>
+  struct is_range
+    : public std::false_type
+  {};
+
+#ifndef DOXYGEN
+  // version for types with begin() and end()
+  template<typename T>
+  struct is_range<T,
+                  decltype(std::declval<T>().begin()),
+                  decltype(std::declval<T>().end())>
+    : public std::true_type
+  {};
+#endif
+
   namespace detail
   {
     ///