diff --git a/src/amdis/AdaptionInterface.hpp b/src/amdis/AdaptionInterface.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66a0baf6c7a370088d50d5a79333555c1dae9944
--- /dev/null
+++ b/src/amdis/AdaptionInterface.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <amdis/common/ConceptsBase.hpp>
+
+namespace AMDiS
+{
+  /**
+   * \addtogroup Concepts
+   * @{
+   **/
+
+  namespace Concepts
+  {
+    namespace Definition
+    {
+      struct InterpolateData
+      {
+        template <class Data>
+        auto requires_(Data const& data) -> decltype(
+            const_cast<Data&>(data).preAdapt(true),
+            const_cast<Data&>(data).postAdapt(true)
+          );
+      };
+
+      struct UpdateData
+      {
+        template <class Basis>
+        auto requires_(Basis const& basis) -> decltype(
+            const_cast<Basis&>(basis).update(basis.gridView())
+          );
+      };
+
+    } // end namespace Definition
+
+    template <class Data>
+    constexpr bool InterpolateData = models<Definition::InterpolateData(Data)>;
+
+    template <class Basis>
+    constexpr bool UpdateData = models<Definition::UpdateData(Basis)>;
+
+  } // end namespace Concepts
+
+  /// @}
+
+
+  /**
+   * \addtogroup Adaption
+   * @{
+   **/
+
+  /// \brief Interface for transfer between grid changes
+  class AdaptionInterface
+  {
+  public:
+    virtual ~AdaptionInterface() = default;
+
+    /// Prepare the grid and the data for the adaption
+    virtual bool preAdapt() = 0;
+
+    /// Do the grid adaption
+    virtual bool adapt() = 0;
+
+    // Perform data adaption to the new grid
+    virtual void postAdapt() = 0;
+  };
+
+  /// @}
+
+} // end namespace AMDiS
diff --git a/src/amdis/CMakeLists.txt b/src/amdis/CMakeLists.txt
index d13f729273157a36b29e8265059b81940b22935d..c21899d28f5d04dc8c23f965a5070db433dc66f0 100644
--- a/src/amdis/CMakeLists.txt
+++ b/src/amdis/CMakeLists.txt
@@ -17,6 +17,8 @@ install(FILES
     AdaptBase.hpp
     AdaptInfo.hpp
     AdaptInstationary.hpp
+    AdaptionInterface.hpp
+    AdaptiveGlobalBasis.hpp
     AdaptStationary.hpp
     AMDiS.hpp
     Assembler.hpp
diff --git a/src/amdis/GridTransfer.hpp b/src/amdis/GridTransfer.hpp
index c9166572bf80e7f8266a7bf4afead0ffb2ff85e5..3c61106ea698c0703dc03e62341106b89d2cadff 100644
--- a/src/amdis/GridTransfer.hpp
+++ b/src/amdis/GridTransfer.hpp
@@ -1,9 +1,10 @@
 #pragma once
 
+#include <functional>
 #include <list>
 
+#include <amdis/AdaptionInterface.hpp>
 #include <amdis/Output.hpp>
-#include <amdis/linearalgebra/DOFVectorInterface.hpp>
 
 namespace AMDiS
 {
@@ -12,35 +13,26 @@ namespace AMDiS
    * @{
    **/
 
-  /// \brief Interface for transfer between grid changes to be registered in a \ref GridTransferManager
-  class GridTransferInterface
-  {
-  public:
-    virtual ~GridTransferInterface() = default;
-
-    /// Attach a data container to the grid transfer, that gets interpolated during grid change
-    virtual void attach(DOFVectorInterface*) = 0;
-
-    /// Remove a data constainer from the grid transfer. Throws a warning if container not found.
-    virtual void detach(DOFVectorInterface*) = 0;
-
-    /// Prepare the grid and the data for the adaption
-    virtual bool preAdapt() = 0;
-
-    /// Do the grid adaption
-    virtual bool adapt() = 0;
-
-    // Perform data adaption to the new grid
-    virtual void postAdapt() = 0;
-  };
-
-
-  /// \brief Implementation of \ref GridTransferInterface for concrete Grid type.
+  /// \brief Implementation of \ref AdaptionInterface for concrete Grid type.
   template <class Grid>
   class GridTransfer
-      : public GridTransferInterface
+      : public AdaptionInterface
   {
     using Self = GridTransfer;
+    using Key = std::uintptr_t;
+
+    struct InterpolateCallback
+    {
+      std::function<void(bool)> preAdapt;
+      std::function<void(bool)> postAdapt;
+      int count = 0;
+    };
+
+    struct UpdateCallback
+    {
+      std::function<void(void)> update;
+      int count = 0;
+    };
 
   public:
     /// Bind a (mutable) grid to this GridTransfer. Must be called before any xxxAdapt() method.
@@ -63,20 +55,57 @@ namespace AMDiS
       return grid_ != nullptr;
     }
 
-    /// Implements \ref GridTransferInterface::attach
-    void attach(DOFVectorInterface* vec) override
+    /// Register data to GridTransfer.
+    /**
+     * This inserts a callback that is called in \ref preAdapt() and another that is
+     * called in \ref postAdapt() step.
+     *
+     * *Requirement:*
+     * - Data must be a model of \ref Concepts::InterpolateData
+     **/
+    template <class Data,
+      REQUIRES(Concepts::InterpolateData<Data>)>
+    void attach(Data& data)
     {
-      data_.push_back(vec);
+      auto it = interpolateCallbacks_.emplace(Key(&data), InterpolateCallback{
+        [&data](bool mightCoarsen) -> void { data.preAdapt(mightCoarsen); },
+        [&data](bool refined) -> void { data.postAdapt(refined); }});
+
+      it.first->second.count++;
     }
 
-    /// Implements \ref GridTransferInterface::detach
-    void detach(DOFVectorInterface* vec) override
+    /// Register data to GridTransfer.
+    /**
+     * This inserts a callback that is called after the \ref adapt() step.
+     * The callback calls `data.update(data.gridView())`.
+     *
+     * *Requirement:*
+     * - Data must be a model of \ref Concepts::UpdateData
+     **/
+    template <class Data,
+      REQUIRES(Concepts::UpdateData<Data>)>
+    void attach(Data& data)
     {
-      auto it = std::find(data_.begin(), data_.end(), vec);
-      if (it != data_.end())
-        data_.erase(it);
-      else
-        warning("DOFVector to detach not found");
+      auto it = updateCallbacks_.emplace(Key(&data), UpdateCallback{
+        [&data]() -> void { data.update(data.gridView()); }});
+
+      it.first->second.count++;
+    }
+
+    /// Unregister data from GridTransfer. Data is identified by its address.
+    template <class Data,
+      REQUIRES(Concepts::InterpolateData<Data>)>
+    void detach(Data& data)
+    {
+      eraseCallback(interpolateCallbacks_, Key(&data));
+    }
+
+    /// Unregister data from GridTransfer. Data is identified by its address.
+    template <class Data,
+      REQUIRES(Concepts::UpdateData<Data>)>
+    void detach(Data& data)
+    {
+      eraseCallback(updateCallbacks_, Key(&data));
     }
 
     /// Implements \ref GridTransferInterface::preAdapt
@@ -85,8 +114,8 @@ namespace AMDiS
     {
       assert(bound());
       mightCoarsen_ = grid_->preAdapt();
-      for (auto* vec : this->data_)
-        vec->preAdapt(mightCoarsen_);
+      for (auto&& data : interpolateCallbacks_)
+        data.second.preAdapt(mightCoarsen_);
       return mightCoarsen_;
     }
 
@@ -105,9 +134,12 @@ namespace AMDiS
     {
       assert(bound());
       if (mightCoarsen_ || refined_) {
-        for (auto* vec : this->data_)
-          vec->postAdapt(refined_);
+        for (auto&& data : updateCallbacks_)
+          data.second.update();
+        for (auto&& data : interpolateCallbacks_)
+          data.second.postAdapt(refined_);
       }
+
       grid_->postAdapt();
       changeIndex_++;
     }
@@ -118,12 +150,27 @@ namespace AMDiS
       return changeIndex_;
     }
 
+  private:
+    // remove entry from map if count <= 1, otherwise reduce count by 1
+    template <class Map>
+    void eraseCallback(Map& map, Key key)
+    {
+      auto it = map.find(key);
+      if (it == map.end())
+        warning("Data to detach not found");
+      else if (it->second.count > 1)
+        it->second.count--;
+      else
+        map.erase(it);
+    }
+
   private:
     /// A grid this GridTransfer is bound to in \ref bind()
     Grid* grid_ = nullptr;
 
     /// A list of data containers handled during grid adaption
-    std::list<DOFVectorInterface*> data_;
+    std::map<Key,InterpolateCallback> interpolateCallbacks_;
+    std::map<Key,UpdateCallback> updateCallbacks_;
 
     /// Flag set during \ref preAdapt(), indicating whether any element might be coarsened in \ref adapt()
     bool mightCoarsen_ = false;
diff --git a/src/amdis/GridTransferManager.hpp b/src/amdis/GridTransferManager.hpp
index 5721bf3ba9e176a7fad427c51390ae0cae3ff1ff..23f6a389c74b71fb1eee8e93b53f4828c925cb19 100644
--- a/src/amdis/GridTransferManager.hpp
+++ b/src/amdis/GridTransferManager.hpp
@@ -4,6 +4,7 @@
 #include <map>
 #include <memory>
 
+#include <amdis/AdaptionInterface.hpp>
 #include <amdis/GridTransfer.hpp>
 #include <amdis/common/ConcurrentCache.hpp>
 
@@ -17,12 +18,9 @@ namespace AMDiS
   /// Static administration class for automatic handling of DOFVectors during grid adaption
   class GridTransferManager
   {
-    template <class, class>
-    friend class DOFVectorBase;
-
     using Self = GridTransferManager;
     using Key = std::uintptr_t;
-    using Data = std::unique_ptr<GridTransferInterface>;
+    using Data = std::shared_ptr<AdaptionInterface>;
 
   private:
     // Constructors. Since this is a static class you cannot call any constructor.
@@ -41,56 +39,56 @@ namespace AMDiS
      * Takes a grid as argument. Marking of the grid needs to be performed prior to calling this.
      * Returns true if the grid changed during adaptation.
      **/
-    template <class Grid, class ...Bases>
-    static bool adapt(Grid& grid, Bases&... bases)
+    template <class Grid>
+    static bool adapt(Grid& grid)
     {
-      auto gridTransfer = GridTransferManager::gridTransfer(grid);
-      bool adapted = gridTransfer.preAdapt();
-      adapted |= gridTransfer.adapt();
-      // call basis.update(basis.gridView()) on all bases
-      (void)std::initializer_list<int>({0, (bases.update(bases.gridView()),0)...});
-      gridTransfer.postAdapt();
+      auto transfer = gridTransfer(grid);
+      bool adapted = transfer->preAdapt();
+      adapted |= transfer->adapt();
+      transfer->postAdapt();
       return adapted;
     }
 
-    /// Returns the GridTransfer corresponding to a Grid, to be used during the adaptation cycle
+    /// Returns the GridTransfer bound to a Grid, to be used during the adaptation cycle
     template <class Grid>
-    static GridTransfer<Grid>& gridTransfer(Grid& grid)
+    static std::shared_ptr<GridTransfer<Grid>> gridTransfer(Grid& grid)
     {
-      GridTransfer<Grid>* gridTransfer
-        = dynamic_cast<GridTransfer<Grid>*>(Self::gridTransferInterface(grid));
-      gridTransfer->bind(grid);
-      return *gridTransfer;
+      auto transfer = get(grid);
+      transfer->bind(grid);
+      return transfer;
     }
 
-  private:
-    // DOFVector registration methods. They are called automaticly by the DOFVectors.
-    template <class Vec>
-    static void attach(Vec& vec)
+  public:
+    template <class Grid, class Data>
+    static void attach(Grid const& grid, Data& data)
     {
-      auto const& grid = vec.basis().gridView().grid();
-      Self::gridTransferInterface(grid)->attach(&vec);
+      get(grid)->attach(data);
     }
 
-    template <class Vec>
-    static void detach(Vec& vec)
+    template <class Grid, class Data>
+    static void detach(Grid const& grid, Data& data)
     {
-      auto const& grid = vec.basis().gridView().grid();
-      Self::gridTransferInterface(grid)->detach(&vec);
+      get(grid)->detach(data);
     }
 
-    // Returns the GridTransferInterface class,
-    //   used for attaching and detaching DOFVectors to a GridTransfer
+
+  private:
+    /// \brief Returns the GridTransfer class, used for attaching and detaching Data
+    /**
+     * NOTE: The returned GridTransfer is not yet bound to a grid, since a
+     * mutable reference `Grid&` is needed for the binding.
+     **/
     template <class Grid>
-    static GridTransferInterface* gridTransferInterface(Grid const &grid)
+    static std::shared_ptr<GridTransfer<Grid>> get(Grid const& grid)
     {
       Key key = Key(&grid);
       GridTransferCache cache;
-      auto& gridTransferInterfaceUniquePtr = cache.get(key, [&](Key const&)
+      auto& gridTransferInterface = cache.get(key, [&](Key const&)
       {
         return std::make_unique<GridTransfer<Grid>>();
       });
-      return gridTransferInterfaceUniquePtr.get();
+
+      return std::dynamic_pointer_cast<GridTransfer<Grid>>(gridTransferInterface);
     }
 
   private:
diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp
index b4578993f8c93b557b0b8ac862bd0943c15da194..97046397ba315ccdddc8a42294718ec9ef0e5c4c 100644
--- a/src/amdis/ProblemStat.hpp
+++ b/src/amdis/ProblemStat.hpp
@@ -387,7 +387,7 @@ namespace AMDiS
     void adoptGlobalBasis(std::shared_ptr<GlobalBasis> const& globalBasis)
     {
       globalBasis_ = globalBasis;
-      initGlobalBasis(*globalBasis_);
+      initGlobalBasis();
     }
 
     void adoptGrid(std::shared_ptr<Grid> const& grid)
@@ -408,7 +408,7 @@ namespace AMDiS
     void createGlobalBasisImpl(std::true_type);
     void createGlobalBasisImpl(std::false_type);
 
-    void initGlobalBasis(GlobalBasis const& globalBasis);
+    void initGlobalBasis();
 
 
   public: // implementation of iteration interface methods
diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp
index 26f18a5ae91bacf8a97e1c12bb5e1a4d7c3e67b4..47c857fdd06ff07208a8b492adf0a9ba43deac13 100644
--- a/src/amdis/ProblemStat.inc.hpp
+++ b/src/amdis/ProblemStat.inc.hpp
@@ -50,7 +50,7 @@ void ProblemStat<Traits>::initialize(
     if (globalRefinements > 0) {
       grid_->globalRefine(globalRefinements);
       if (globalBasis_)
-        globalBasis_->update(gridView());
+        globalBasis_->update(globalBasis_->gridView());
     }
   }
 
@@ -143,7 +143,7 @@ template <class Traits>
 void ProblemStat<Traits>::createGlobalBasis()
 {
   createGlobalBasisImpl(Dune::Std::is_detected<HasCreate,Traits,GridView>{});
-  initGlobalBasis(*globalBasis_);
+  initGlobalBasis();
 }
 
 
@@ -164,7 +164,7 @@ void ProblemStat<Traits>::createGlobalBasisImpl(std::false_type)
 
 
 template <class Traits>
-void ProblemStat<Traits>::initGlobalBasis(GlobalBasis const& globalBasis)
+void ProblemStat<Traits>::initGlobalBasis()
 {
   dirichletBCs_.init(*globalBasis_, *globalBasis_);
   periodicBCs_.init(*globalBasis_, *globalBasis_);
@@ -367,7 +367,7 @@ globalCoarsen(int n)
     for (const auto& element : elements(grid_->leafGridView()))
       grid_->mark(-1, element);
 
-    adapted |= GridTransferManager::adapt(*grid_, *globalBasis_);
+    adapted |= GridTransferManager::adapt(*grid_);
   }
 
   msg("globalCoarsen needed {} seconds", t.elapsed());
@@ -389,7 +389,6 @@ globalRefine(int refCount)
   /*then*/ [&](auto id) {
     // TODO(FM): Add a way to pass a GridTransfer as ADH with *globalBasis_ argument
     id(grid_)->globalRefine(refCount, GridTransferManager::gridTransfer(*grid_));
-    globalBasis_->update(this->gridView());
   },
   /*else*/ [&](auto id) {
     for (int i = 0; i < refCount; ++i) {
@@ -397,7 +396,7 @@ globalRefine(int refCount)
       for (const auto& element : elements(grid_->leafGridView()))
         grid_->mark(1, element);
 
-      adapted |= GridTransferManager::adapt(*id(grid_), *id(globalBasis_));
+      adapted |= GridTransferManager::adapt(*id(grid_));
     }
   });
 
@@ -412,7 +411,7 @@ adaptGrid(AdaptInfo& adaptInfo)
 {
   Dune::Timer t;
 
-  bool adapted = GridTransferManager::adapt(*grid_, *globalBasis_);
+  bool adapted = GridTransferManager::adapt(*grid_);
 
   msg("adaptGrid needed {} seconds", t.elapsed());
   return adapted ? MESH_ADAPTED : Flag(0);
diff --git a/src/amdis/common/ConceptsBase.hpp b/src/amdis/common/ConceptsBase.hpp
index 86a2befda56702954f81fffd1c0ae465c7a5e623..aa8615011aee93b8adcd6cc6203fa9d5066a51b9 100644
--- a/src/amdis/common/ConceptsBase.hpp
+++ b/src/amdis/common/ConceptsBase.hpp
@@ -8,8 +8,8 @@
   #define REQUIRES_(...)
   #define CONCEPT constexpr
 #else
-  #define REQUIRES(...) std::enable_if_t<__VA_ARGS__ , int>* = nullptr
-  #define REQUIRES_(...) std::enable_if_t<__VA_ARGS__ , int>*
+  #define REQUIRES(...) std::enable_if_t<__VA_ARGS__ , int> = 0
+  #define REQUIRES_(...) std::enable_if_t<__VA_ARGS__ , int>
   #define CONCEPT constexpr
 #endif
 
diff --git a/src/amdis/linearalgebra/DOFVectorBase.hpp b/src/amdis/linearalgebra/DOFVectorBase.hpp
index 91e1c57dd0191329fc1b84f2629124293987484d..37feaab60fb8d0dc87e08a1eb26dd5b19e1e9125 100644
--- a/src/amdis/linearalgebra/DOFVectorBase.hpp
+++ b/src/amdis/linearalgebra/DOFVectorBase.hpp
@@ -57,12 +57,12 @@ namespace AMDiS
 
   public:
     /// Constructor. Constructs new BaseVector.
-    DOFVectorBase(GlobalBasis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+    DOFVectorBase(GlobalBasis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
       : basis_(&basis)
       , dataTransfer_(DataTransferFactory::create(op, basis))
     {
       compress();
-      GridTransferManager::attach(*this);
+      attachToGridTransfer();
       operators_.init(basis);
     }
 
@@ -74,7 +74,7 @@ namespace AMDiS
       , operators_(that.operators_)
       , dataTransfer_(that.dataTransfer_)
     {
-      GridTransferManager::attach(*this);
+      attachToGridTransfer();
     }
 
     /// Move constructor
@@ -85,24 +85,24 @@ namespace AMDiS
       , operators_(std::move(that.operators_))
       , dataTransfer_(std::move(that.dataTransfer_))
     {
-      GridTransferManager::attach(*this);
+      attachToGridTransfer();
     }
 
     /// Destructor
     ~DOFVectorBase() override
     {
-      GridTransferManager::detach(*this);
+      detachFromGridTransfer();
     }
 
     /// Copy assignment operator
     Self& operator=(Self const& that)
     {
-      GridTransferManager::detach(*this);
+      detachFromGridTransfer();
       basis_ = that.basis_;
       backend_.resize(that.size());
       backend_ = that.backend_;
       dataTransfer_ = that.dataTransfer_;
-      GridTransferManager::attach(*this);
+      attachToGridTransfer();
       return *this;
     }
 
@@ -225,9 +225,22 @@ namespace AMDiS
       dataTransfer_->postAdapt(*this, refined);
     }
 
+  private:
+    void attachToGridTransfer()
+    {
+      GridTransferManager::attach(basis_->gridView().grid(), *this);
+      GridTransferManager::attach(basis_->gridView().grid(), *basis_);
+    }
+
+    void detachFromGridTransfer()
+    {
+      GridTransferManager::detach(basis_->gridView().grid(), *basis_);
+      GridTransferManager::detach(basis_->gridView().grid(), *this);
+    }
+
   private:
     /// The finite element space / basis associated with the data vector
-    GlobalBasis const* basis_;
+    GlobalBasis* basis_;
 
     /// Data backend
     Backend backend_;
diff --git a/src/amdis/linearalgebra/eigen/DOFVector.hpp b/src/amdis/linearalgebra/eigen/DOFVector.hpp
index a2f71979522400d047d9172b810e3f1c75aa16fa..d961943fdd43453fdaa5e64ef70cadaf0aef5cdb 100644
--- a/src/amdis/linearalgebra/eigen/DOFVector.hpp
+++ b/src/amdis/linearalgebra/eigen/DOFVector.hpp
@@ -91,7 +91,7 @@ namespace AMDiS
     using Super = DOFVectorBase<BasisType, EigenVector<ValueType>>;
 
   public:
-    DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+    DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
       : Super(basis, op)
     {}
 
@@ -102,7 +102,7 @@ namespace AMDiS
   /// Constructor a dofvector from given basis and name
   template <class ValueType = double, class Basis>
   DOFVector<Basis, ValueType>
-  makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+  makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
   {
     return {basis, op};
   }
diff --git a/src/amdis/linearalgebra/istl/DOFVector.hpp b/src/amdis/linearalgebra/istl/DOFVector.hpp
index 5d54f7edc15ba75280cf9c9c6672cef652b23e86..b6a858033d41584cda7799ccba820e52dcb0711d 100644
--- a/src/amdis/linearalgebra/istl/DOFVector.hpp
+++ b/src/amdis/linearalgebra/istl/DOFVector.hpp
@@ -100,7 +100,7 @@ namespace AMDiS
     using Super = DOFVectorBase<BasisType, IstlVector<ValueType>>;
 
   public:
-    DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+    DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
       : Super(basis, op)
     {}
 
@@ -111,7 +111,7 @@ namespace AMDiS
   /// Constructor a dofvector from given basis and name
   template <class ValueType = double, class Basis>
   DOFVector<Basis, ValueType>
-  makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+  makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
   {
     return {basis, op};
   }
diff --git a/src/amdis/linearalgebra/mtl/DOFVector.hpp b/src/amdis/linearalgebra/mtl/DOFVector.hpp
index 35be3d71ec1d816fa5d35835ece04831036b0f25..f7c1a9e52fc8e9132cc507971376db7c188542ba 100644
--- a/src/amdis/linearalgebra/mtl/DOFVector.hpp
+++ b/src/amdis/linearalgebra/mtl/DOFVector.hpp
@@ -91,7 +91,7 @@ namespace AMDiS
     using Super = DOFVectorBase<BasisType, MtlVector<ValueType>>;
 
   public:
-    DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+    DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
       : Super(basis, op)
     {}
 
@@ -102,7 +102,7 @@ namespace AMDiS
   /// Constructor a dofvector from given basis and name
   template <class ValueType = double, class Basis>
   DOFVector<Basis, ValueType>
-  makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
+  makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE)
   {
     return {basis, op};
   }
diff --git a/test/DOFVectorTest.cpp b/test/DOFVectorTest.cpp
index 61721ef05a6c2e1fd3bf95b396b4c35090a5a5db..1d69bc4b53b1e96a2d3089c8124596d4d2e733fa 100644
--- a/test/DOFVectorTest.cpp
+++ b/test/DOFVectorTest.cpp
@@ -74,7 +74,7 @@ int main(int argc, char** argv)
     test_dofvector(basis, vec1);
     for (auto const& e : elements(gridView))
       grid.mark(1, e);
-    GridTransferManager::adapt(grid, basis);
+    GridTransferManager::adapt(grid);
     AMDIS_TEST_EQ(vec1.size(), basis.dimension());
   }
 
diff --git a/test/DataTransferTest.hpp b/test/DataTransferTest.hpp
index d2478feb52b31f002ac0c38816c6e5f641315821..e9c7c3d3e1f84d531a3be9ee076e9dbe1d05e7ba 100644
--- a/test/DataTransferTest.hpp
+++ b/test/DataTransferTest.hpp
@@ -60,29 +60,29 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts
   using Problem = ProblemStat<BasisCreator>;
 
   // make problem
-  Problem prob("test", grid);
-  prob.initialize(INIT_ALL);
+  auto prob = std::make_unique<Problem>("test", grid);
+  prob->initialize(INIT_ALL);
 
-  auto& globalBasis = *prob.globalBasis();
+  auto& globalBasis = *prob->globalBasis();
   auto localView = globalBasis.localView();
 
   // interpolate given function to initial grid
   int k = 0;
   for_each_leaf_node(localView.tree(), [&](auto const& node, auto tp)
   {
-    interpolate(globalBasis, tp, prob.solution(tp).coefficients(), funcs[k]);
+    interpolate(globalBasis, tp, prob->solution(tp).coefficients(), funcs[k]);
     k++;
   });
 
-  return prob;
+  return std::move(prob);
 }
 
 template <class Problem, class Fcts>
 double calcError(Problem const& prob, Fcts const& funcs)
 {
-  auto& globalBasis = *prob.globalBasis();
+  auto& globalBasis = *prob->globalBasis();
   auto localView = globalBasis.localView();
-  auto sol = prob.solution().coefficients();
+  auto const& sol = prob->solution().coefficients();
   std::vector<double> ref;
   ref.resize(globalBasis.size());
   double error = 0;
@@ -122,7 +122,7 @@ bool unchanged_test(Fcts<BasisCreator> const& funcs, bool simplex = true)
   auto e = *gridPtr->leafGridView().template begin<0>();
   gridPtr->mark(-1, e);
   AdaptInfo adaptInfo("adapt");
-  prob.adaptGrid(adaptInfo);
+  prob->adaptGrid(adaptInfo);
   auto error = calcError(prob, funcs);
 
   return error < AMDIS_TEST_TOL;
@@ -137,7 +137,7 @@ bool coarsen_test(Fcts<BasisCreator> const& funcs, bool simplex = true)
 
   auto gridPtr = makeGrid<BasisCreator>(simplex, (d > 2 ? 2 : 4));
   auto prob = makeProblem<BasisCreator, Fcts<BasisCreator>>(*gridPtr, funcs);
-  prob.globalCoarsen(1);
+  prob->globalCoarsen(1);
   auto error = calcError(prob, funcs);
 
   return error < AMDIS_TEST_TOL;
@@ -152,7 +152,7 @@ bool refine_test(Fcts<BasisCreator> const& funcs, bool simplex = true)
 
   auto gridPtr = makeGrid<BasisCreator>(simplex, (d > 2 ? 1 : 3));
   auto prob = makeProblem<BasisCreator, Fcts<BasisCreator>>(*gridPtr, funcs);
-  prob.globalRefine(1);
+  prob->globalRefine(1);
   auto error = calcError(prob, funcs);
 
   return error < AMDIS_TEST_TOL;