diff --git a/dune/stuff/la/container/dunedynamic.hh b/dune/stuff/la/container/dunedynamic.hh
index d851647e919db27506a9f220b8f9f80f3230ba53..9323475675f9fa2e2f1c4443bfe6e0b626afd6ee 100644
--- a/dune/stuff/la/container/dunedynamic.hh
+++ b/dune/stuff/la/container/dunedynamic.hh
@@ -14,6 +14,7 @@
 #include <dune/common/dynmatrix.hh>
 #include <dune/stuff/common/reenable_warnings.hh>
 #include <dune/common/float_cmp.hh>
+#include <dune/common/typetraits.hh>
 
 #include "interfaces.hh"
 
@@ -313,6 +314,7 @@ private:
       backend_ = std::make_shared<BackendType>(*backend_);
   } // ... ensure_uniqueness(...)
 
+  friend class DuneDynamicMatrix<ScalarType>;
   friend class Dune::Pymor::Operators::DuneDynamicInverse<ScalarType>;
   friend class Dune::Pymor::Operators::DuneDynamic<ScalarType>;
 
@@ -477,6 +479,17 @@ public:
     return backend_->cols();
   }
 
+  template <class SourceType, class RangeType>
+  inline void mv(const SourceType& /*xx*/, RangeType& /*yy*/) const
+  {
+    static_assert(Dune::AlwaysFalse<SourceType>::value, "Not available for this combination of xx and yy!");
+  }
+
+  inline void mv(const DuneDynamicVector<ScalarType>& xx, DuneDynamicVector<ScalarType>& yy) const
+  {
+    backend_->mv(*(xx.backend_), *(yy.backend_));
+  }
+
   void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
   {
     assert(ii < rows());
diff --git a/dune/stuff/la/container/eigen.hh b/dune/stuff/la/container/eigen.hh
index f70c52f2f2564617d703cbaea01de1ed95e3e9ff..7a17388315641548f9bb689b98176b07f56e58ad 100644
--- a/dune/stuff/la/container/eigen.hh
+++ b/dune/stuff/la/container/eigen.hh
@@ -14,6 +14,8 @@
 #include <Eigen/Core>
 #include <Eigen/SparseCore>
 
+#include <dune/common/typetraits.hh>
+
 #include <dune/stuff/aliases.hh>
 #include <dune/stuff/common/ranges.hh>
 #include <dune/stuff/common/exceptions.hh>
@@ -379,6 +381,8 @@ private:
       backend_ = std::make_shared<BackendType>(*backend_);
   } // ... ensure_uniqueness(...)
 
+  friend class EigenDenseMatrix<ScalarType>;
+  friend class EigenRowMajorSparseMatrix<ScalarType>;
   friend class Dune::Pymor::Operators::EigenRowMajorSparseInverse<ScalarType>;
   friend class Dune::Pymor::Operators::EigenRowMajorSparse<ScalarType>;
 
@@ -690,6 +694,8 @@ private:
     }
   } // ... ensure_uniqueness(...)
 
+  friend class EigenDenseMatrix<ScalarType>;
+  friend class EigenRowMajorSparseMatrix<ScalarType>;
   friend class Dune::Pymor::Operators::EigenRowMajorSparseInverse<ScalarType>;
   friend class Dune::Pymor::Operators::EigenRowMajorSparse<ScalarType>;
 
@@ -881,6 +887,32 @@ public:
     return backend_->cols();
   }
 
+  template <class SourceType, class RangeType>
+  inline void mv(const SourceType& /*xx*/, RangeType& /*yy*/) const
+  {
+    static_assert(Dune::AlwaysFalse<SourceType>::value, "Not available for this combination of xx and yy!");
+  }
+
+  inline void mv(const EigenDenseVector<ScalarType>& xx, EigenDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenDenseVector<ScalarType>& xx, EigenMappedDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenMappedDenseVector<ScalarType>& xx, EigenDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenMappedDenseVector<ScalarType>& xx, EigenMappedDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
   void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
   {
     assert(ii < rows());
@@ -1144,6 +1176,32 @@ public:
     return backend_->cols();
   }
 
+  template <class SourceType, class RangeType>
+  inline void mv(const SourceType& /*xx*/, RangeType& /*yy*/) const
+  {
+    static_assert(Dune::AlwaysFalse<SourceType>::value, "Not available for this combination of xx and yy!");
+  }
+
+  inline void mv(const EigenDenseVector<ScalarType>& xx, EigenDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenDenseVector<ScalarType>& xx, EigenMappedDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenMappedDenseVector<ScalarType>& xx, EigenDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
+  inline void mv(const EigenMappedDenseVector<ScalarType>& xx, EigenMappedDenseVector<ScalarType>& yy) const
+  {
+    yy.backend_->transpose() = backend_->operator*(*(xx.backend_));
+  }
+
   void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
   {
     assert(these_are_valid_indices(ii, jj));
diff --git a/dune/stuff/la/container/interfaces.hh b/dune/stuff/la/container/interfaces.hh
index fbbf3ffe2a0ba7a89be4f2a9d33fa2fcf430991d..997ca1405272514d67837d4bba4a71b6d9e9cc63 100644
--- a/dune/stuff/la/container/interfaces.hh
+++ b/dune/stuff/la/container/interfaces.hh
@@ -579,6 +579,12 @@ public:
     return this->as_imp(*this).cols();
   }
 
+  template <class SourceType, class RangeType>
+  inline void mv(const SourceType& xx, RangeType& yy) const
+  {
+    CHECK_AND_CALL_CRTP(this->as_imp(*this).mv(xx, yy));
+  }
+
   inline void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
   {
     CHECK_AND_CALL_CRTP(this->as_imp(*this).add_to_entry(ii, jj, value));
diff --git a/dune/stuff/la/container/istl.hh b/dune/stuff/la/container/istl.hh
index 02d34270b964427986bc372b1f61933af0070340..74b79f47174a6e9a40ad04603839cd574feb5142 100644
--- a/dune/stuff/la/container/istl.hh
+++ b/dune/stuff/la/container/istl.hh
@@ -12,6 +12,7 @@
 
 #include <dune/common/fvector.hh>
 #include <dune/common/fmatrix.hh>
+#include <dune/common/typetraits.hh>
 
 #include <dune/istl/bvector.hh>
 #include <dune/istl/bcrsmatrix.hh>
@@ -314,6 +315,7 @@ private:
       backend_ = std::make_shared<BackendType>(*backend_);
   } // ... ensure_uniqueness(...)
 
+  friend class IstlRowMajorSparseMatrix<ScalarType>;
   friend class BicgstabILUTSolver<IstlRowMajorSparseMatrix<ScalarType>, ThisType>;
   friend class AmgSolver<IstlRowMajorSparseMatrix<ScalarType>, ThisType>;
 
@@ -499,6 +501,17 @@ public:
     return backend_->M();
   }
 
+  template <class SourceType, class RangeType>
+  inline void mv(const SourceType& /*xx*/, RangeType& /*yy*/) const
+  {
+    static_assert(Dune::AlwaysFalse<SourceType>::value, "Not available for this combination of xx and yy!");
+  }
+
+  inline void mv(const IstlDenseVector<ScalarType>& xx, IstlDenseVector<ScalarType>& yy) const
+  {
+    backend_->mv(*(xx.backend_), *(yy.backend_));
+  }
+
   void add_to_entry(const size_t ii, const size_t jj, const ScalarType& value)
   {
     assert(these_are_valid_indices(ii, jj));