diff --git a/src/mesh/ItemValue.hpp b/src/mesh/ItemValue.hpp
index 23d92d53761c2e4c7d75270b6cf60d8eb7ddd2a0..9b4bf5cfc741f6132b1e5073ead769017b414476 100644
--- a/src/mesh/ItemValue.hpp
+++ b/src/mesh/ItemValue.hpp
@@ -34,7 +34,7 @@ class ItemValue
   }
 
   KOKKOS_INLINE_FUNCTION
-  size_t numberOfValues() const
+  size_t size() const
   {
     Assert(m_is_built);
     return m_values.size();
diff --git a/src/scheme/AcousticSolver.hpp b/src/scheme/AcousticSolver.hpp
index 0f3c2f384260428450a0c2a89d0f8b2a6ca4226e..a23f13d7eed39aac16cbef066acbecdd3710db65 100644
--- a/src/scheme/AcousticSolver.hpp
+++ b/src/scheme/AcousticSolver.hpp
@@ -1,9 +1,10 @@
 #ifndef ACOUSTIC_SOLVER_HPP
 #define ACOUSTIC_SOLVER_HPP
 
-#include <Kokkos_Core.hpp>
 #include <rang.hpp>
 
+#include <ArrayUtils.hpp>
+
 #include <BlockPerfectGas.hpp>
 #include <PastisAssert.hpp>
 
@@ -33,43 +34,6 @@ class AcousticSolver
   typedef TinyMatrix<dimension> Rdd;
 
  private:
-  struct ReduceMin
-  {
-   private:
-    const CellValue<const double> x_;
-
-   public:
-    typedef std::remove_const_t<CellValue<const double>::data_type> value_type;
-
-    ReduceMin(const CellValue<const double>& x) : x_ (x) {}
-
-#warning was: "typedef Kokkos::View<const double*>::size_type size_type;""
-    typedef size_t size_type;
-
-    KOKKOS_INLINE_FUNCTION
-    void operator() (const size_type i, value_type& update) const
-    {
-      if (x_[i] < update) {
-        update = x_[i];
-      }
-    }
-
-    KOKKOS_INLINE_FUNCTION
-    void join (volatile value_type& dst,
-               const volatile value_type& src) const
-    {
-      if (src < dst) {
-        dst = src;
-      }
-    }
-
-    KOKKOS_INLINE_FUNCTION void
-    init (value_type& dst) const
-    { // The identity under max is -Inf.
-      dst= Kokkos::reduction_identity<value_type>::min();
-    }
-  };
-
   KOKKOS_INLINE_FUNCTION
   const CellValue<const double>
   computeRhoCj(const CellValue<const double>& rhoj,
@@ -308,10 +272,7 @@ class AcousticSolver
         m_Vj_over_cj[j] = 2*Vj[j]/(S*cj[j]);
       });
 
-    double dt = std::numeric_limits<double>::max();
-    Kokkos::parallel_reduce(m_mesh.numberOfCells(), ReduceMin(m_Vj_over_cj), dt);
-
-    return dt;
+    return ReduceMin(m_Vj_over_cj);
   }
 
 
diff --git a/src/scheme/BlockPerfectGas.hpp b/src/scheme/BlockPerfectGas.hpp
index 97a0256efb672b9c680c9edbecd99d96f20ee3fc..0ec05d266f46fe80e38ea9bd4153f19996f4ab12 100644
--- a/src/scheme/BlockPerfectGas.hpp
+++ b/src/scheme/BlockPerfectGas.hpp
@@ -29,7 +29,7 @@ public:
 
   void updatePandCFromRhoE()
   {
-    const size_t nj = m_ej.numberOfValues();
+    const size_t nj = m_ej.size();
     const CellValue<const double> rho = m_rhoj;
     const CellValue<const double> e = m_ej;
     const CellValue<const double> gamma = m_gammaj;
@@ -43,7 +43,7 @@ public:
 
   void updateEandCFromRhoP()
   {
-    const size_t nj = m_ej.numberOfValues();
+    const size_t nj = m_ej.size();
     const CellValue<const double> rho = m_rhoj;
     const CellValue<const double> p = m_pj;
     const CellValue<const double> gamma = m_gammaj;
diff --git a/src/utils/ArrayUtils.hpp b/src/utils/ArrayUtils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7cb9915369d08b3e89243d48a8370a957a2c3541
--- /dev/null
+++ b/src/utils/ArrayUtils.hpp
@@ -0,0 +1,107 @@
+#ifndef ARRAY_UTILS_HPP
+#define ARRAY_UTILS_HPP
+
+#include <Kokkos_Core.hpp>
+
+template <typename ArrayType>
+class ReduceMin
+{
+ private:
+  const ArrayType& m_array;
+  using data_type = std::remove_const_t<typename ArrayType::data_type>;
+
+ public:
+  KOKKOS_INLINE_FUNCTION
+  operator data_type()
+  {
+    data_type reduced_value;
+    Kokkos::parallel_reduce(m_array.size(), *this, reduced_value);
+    return reduced_value;
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(const size_t& i, data_type& data) const
+  {
+    if (m_array[i] < data) {
+      data = m_array[i];
+    }
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  void join(volatile data_type& dst,
+            const volatile data_type& src) const
+  {
+    if (src < dst) {
+      dst = src;
+    }
+  }
+
+  KOKKOS_INLINE_FUNCTION void
+  init(data_type& value) const
+  {
+    value = std::numeric_limits<data_type>::max();
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  ReduceMin(const ArrayType& array)
+      : m_array(array)
+  {
+    ;
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  ~ReduceMin() = default;
+};
+
+
+template <typename ArrayType>
+class ReduceMax
+{
+ private:
+  const ArrayType& m_array;
+  using data_type = std::remove_const_t<typename ArrayType::data_type>;
+
+ public:
+  KOKKOS_INLINE_FUNCTION
+  operator data_type()
+  {
+    data_type reduced_value;
+    Kokkos::parallel_reduce(m_array.size(), *this, reduced_value);
+    return reduced_value;
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  void operator()(const size_t& i, data_type& data) const
+  {
+    if (m_array[i] > data) {
+      data = m_array[i];
+    }
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  void join(volatile data_type& dst,
+            const volatile data_type& src) const
+  {
+    if (src > dst) {
+      dst = src;
+    }
+  }
+
+  KOKKOS_INLINE_FUNCTION void
+  init(data_type& value) const
+  {
+    value = -std::numeric_limits<data_type>::max();
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  ReduceMax(const ArrayType& array)
+      : m_array(array)
+  {
+    ;
+  }
+
+  KOKKOS_INLINE_FUNCTION
+  ~ReduceMax() = default;
+};
+
+#endif //ARRAY_UTILS_HPP