diff --git a/examples/cahn_hilliard.cc b/examples/cahn_hilliard.cc
index a26e9ccf229ace431993e1284318162341a0eb57..fe37bdd7cfc013741b564b23efe12afe8e399df7 100644
--- a/examples/cahn_hilliard.cc
+++ b/examples/cahn_hilliard.cc
@@ -6,6 +6,8 @@
 #include <amdis/GridFunctions.hpp>
 #include <amdis/Marker.hpp>
 
+#include <dune/grid/albertagrid.hh>
+
 using namespace AMDiS;
 
 using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
diff --git a/examples/init/heat.dat.2d b/examples/init/heat.dat.2d
index 31836835ef599d98b3335ba67d7c6e9c64980fcc..e938b21c65fa0df47152df6fb850de5525c2a96c 100644
--- a/examples/init/heat.dat.2d
+++ b/examples/init/heat.dat.2d
@@ -1,9 +1,8 @@
 heatMesh->macro file name:    ./macro/macro.stand.2d
 heatMesh->global refinements: 4
 heatMesh->min corner: 0 0
-heatMesh->max corner: 1 1
+heatMesh->max corner: 2 2
 heatMesh->num cells: 2 2
-heatMesh->dimension: 2 2
 
 heat->mesh:  heatMesh
 heat->names: u
diff --git a/examples/init/stokes.dat.2d b/examples/init/stokes.dat.2d
index 54542825dba336eba2af96e3b3371f548ff8bad6..ded25d60812bc6e5f3eac56f709fb43b1fa9afe3 100644
--- a/examples/init/stokes.dat.2d
+++ b/examples/init/stokes.dat.2d
@@ -1,5 +1,5 @@
 stokesMesh->global refinements: 0
-stokesMesh->dimension: 1.0 1.0
+stokesMesh->max corner: 1.0 1.0
 stokesMesh->num cells: 4 4
 
 stokes->mesh: stokesMesh
diff --git a/src/amdis/BoundaryManager.hpp b/src/amdis/BoundaryManager.hpp
index 9e9191eb25e45f19a42b3c13910e905a68f90598..1b4358396b23021e0d7a6a5957a4e63fecb0d931 100644
--- a/src/amdis/BoundaryManager.hpp
+++ b/src/amdis/BoundaryManager.hpp
@@ -154,6 +154,13 @@ namespace AMDiS
       }
     }
 
+    template <class I>
+    void setBoundaryIds(std::vector<I> const& ids)
+    {
+      test_exit(ids.size() == boundaryIds_.size(), "Number of boundary IDs does not match!");
+      std::copy(ids.begin(), ids.end(), boundaryIds_.begin());
+    }
+
   private:
     std::shared_ptr<Grid> grid_;
     using Super::boundaryIds_;
diff --git a/src/amdis/CMakeLists.txt b/src/amdis/CMakeLists.txt
index ceaf0b69d0750e114d7f43c85b0d91e509c49f36..1237bbc906cd4a0c5806d782675d552daeb8afd2 100644
--- a/src/amdis/CMakeLists.txt
+++ b/src/amdis/CMakeLists.txt
@@ -50,7 +50,7 @@ install(FILES
     LocalOperators.hpp
     Marker.hpp
     Marker.inc.hpp
-    Mesh.hpp
+    MeshCreator.hpp
     Operations.hpp
     OperatorList.hpp
     Output.hpp
diff --git a/src/amdis/Mesh.hpp b/src/amdis/Mesh.hpp
deleted file mode 100644
index d4524bf3b98ca98eaea1e30d50f649c1cf134e77..0000000000000000000000000000000000000000
--- a/src/amdis/Mesh.hpp
+++ /dev/null
@@ -1,183 +0,0 @@
-#pragma once
-
-#include <array>
-#include <memory>
-#include <string>
-
-#include <dune/common/filledarray.hh>
-#include <dune/common/fvector.hh>
-
-#include <dune/grid/albertagrid.hh>
-#include <dune/grid/uggrid.hh>
-#include <dune/grid/yaspgrid.hh>
-
-#include <dune/grid/albertagrid/albertareader.hh>
-#include <dune/grid/io/file/gmshreader.hh>
-
-#include <amdis/Initfile.hpp>
-#include <amdis/Output.hpp>
-#include <amdis/common/Filesystem.hpp>
-
-namespace AMDiS
-{
-  namespace tag
-  {
-    struct albertagrid {};
-    struct uggrid {};
-    struct yaspgrid {};
-    struct unknowngrid {};
-
-  } // end namespace tag
-
-  namespace Impl
-  {
-    template <class Grid>
-    struct MeshTag
-    {
-      using type = tag::unknowngrid;
-    };
-
-    // specialization for some grid types from DUNE
-#if HAVE_ALBERTA
-    template <int dim, int dimworld>
-    struct MeshTag<Dune::AlbertaGrid<dim, dimworld>>
-    {
-      using type = tag::albertagrid;
-    };
-#endif
-
-#if HAVE_UG
-    template <int dim>
-    struct MeshTag<Dune::UGGrid<dim>>
-    {
-      using type = tag::uggrid;
-    };
-#endif
-
-    template <int dim, class Coordinates>
-    struct MeshTag<Dune::YaspGrid<dim, Coordinates>>
-    {
-      using type = tag::yaspgrid;
-    };
-
-  } // end namespace Impl
-
-  template <class Grid>
-  using MeshTag_t = typename Impl::MeshTag<Grid>::type;
-
-
-  /// A creator class for meshes. Each mesh needs different way of initialization
-  template <class Grid>
-  struct MeshCreator
-  {
-    static std::unique_ptr<Grid> create(std::string const& meshName)
-    {
-      error_exit("Creator not yet implemented for this mesh type.");
-      return {};
-    }
-  };
-
-#if HAVE_ALBERTA
-  template <int dim, int dimworld>
-  struct MeshCreator<Dune::AlbertaGrid<dim, dimworld>>
-  {
-    using Grid = Dune::AlbertaGrid<dim, dimworld>;
-
-    static std::unique_ptr<Grid> create(std::string const& meshName)
-    {
-      std::string macro_filename = "";
-      Parameters::get(meshName + "->macro file name", macro_filename);
-
-      // TODO: if filename_extension is ".2d" or ".3d" read it directly from file
-      // otherwise use a factory method
-
-      return std::make_unique<Grid>(macro_filename);
-    }
-  };
-#endif
-
-
-#if HAVE_UG
-  template <int dim>
-  struct MeshCreator<Dune::UGGrid<dim>>
-  {
-    using Grid = Dune::UGGrid<dim>;
-
-    static std::unique_ptr<Grid> create(std::string const& meshName)
-    {
-
-      std::string filename = "";
-      Parameters::get(meshName + "->macro file name", filename);
-
-      test_exit(!filename.empty(),
-        "Construction of UGGrid without filename not yet implemented!");
-
-      filesystem::path fn(filename);
-      auto ext = fn.extension();
-
-      if (ext == ".msh") {
-        Dune::GmshReader<Grid> reader;
-        return std::unique_ptr<Grid>{reader.read(filename)};
-      }
-// #if HAVE_ALBERTA
-//       else if (ext == ".1d" || ext == ".2d" || ext == ".3d") {
-//         Dune::Hybrid::ifElse(bool_t<ALBERTA_DIM == Grid::dimensionworld>{},
-//         [&](auto id) {
-//           Dune::GridFactory<Grid> factory;
-//           Dune::AlbertaReader<Grid> reader;
-//           id(reader).readGrid(filename, id(factory));
-//           return std::unique_ptr<Grid>{factory.createGrid()};
-//         });
-
-//         warning("WORLDDIM must be given in Alberta flags.");
-//       }
-// #endif
-
-      error_exit("No way to construct UG-Grid found");
-      return {};
-    }
-  };
-#endif
-
-  template <int dim, class T>
-  struct MeshCreator<Dune::YaspGrid<dim, Dune::EquidistantCoordinates<T,dim>>>
-  {
-    using Grid = Dune::YaspGrid<dim, Dune::EquidistantCoordinates<T,dim>>;
-
-    static std::unique_ptr<Grid> create(std::string const& meshName)
-    {
-      Dune::FieldVector<T, dim> L; L = 1.0;  // extension of the domain
-      Parameters::get(meshName + "->dimension", L);
-
-      auto s = Dune::filledArray<std::size_t(dim)>(1); // number of cells on coarse mesh in each direction
-      Parameters::get(meshName + "->num cells", s);
-
-      // TODO: add more parameters for yasp-grid (see constructor)
-
-      return std::make_unique<Grid>(L, s);
-    }
-  };
-
-
-  template <int dim, class T>
-  struct MeshCreator<Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<T, dim>>>
-  {
-    using Grid = Dune::YaspGrid<dim, Dune::EquidistantOffsetCoordinates<T, dim>>;
-
-    static std::unique_ptr<Grid> create(std::string const& meshName)
-    {
-      Dune::FieldVector<T, dim> lowerleft;  lowerleft = 0.0; // Lower left corner of the domain
-      Dune::FieldVector<T, dim> upperright; upperright = 1.0; // Upper right corner of the domain
-      Parameters::get(meshName + "->min corner", lowerleft);
-      Parameters::get(meshName + "->max corner", upperright);
-
-      auto s = Dune::filledArray<std::size_t(dim)>(1); // number of cells on coarse mesh in each direction
-      Parameters::get(meshName + "->num cells", s);
-
-      // TODO: add more parameters for yasp-grid (see constructor)
-
-      return std::make_unique<Grid>(lowerleft, upperright, s);
-    }
-  };
-
-} // end namespace AMDiS
diff --git a/src/amdis/MeshCreator.hpp b/src/amdis/MeshCreator.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dc00df3b33a6e4581ddf7419f7134cc739cc36a
--- /dev/null
+++ b/src/amdis/MeshCreator.hpp
@@ -0,0 +1,261 @@
+#pragma once
+
+#include <algorithm>
+#include <array>
+#include <memory>
+#include <string>
+
+#include <dune/common/filledarray.hh>
+#include <dune/common/fvector.hh>
+#include <dune/common/typeutilities.hh>
+
+#if HAVE_ALBERTA
+#include <dune/grid/albertagrid/albertareader.hh>
+#endif
+#include <dune/grid/io/file/gmshreader.hh>
+#include <dune/grid/utility/structuredgridfactory.hh>
+
+#include <amdis/Initfile.hpp>
+#include <amdis/Output.hpp>
+#include <amdis/common/Concepts.hpp>
+#include <amdis/common/Filesystem.hpp>
+#include <amdis/common/TypeTraits.hpp>
+#include <amdis/utility/MacroGridFactory.hpp>
+
+namespace AMDiS
+{
+  /// A creator class for dune grids.
+  template <class Grid>
+  struct MeshCreator
+  {
+    enum { dimension = Grid::dimension };
+    enum { dimworld = Grid::dimensionworld };
+
+    using ctype = typename Grid::ctype;
+
+    /// Construct a new MeshCreator
+    /**
+     * \param name  The name of the mesh used in the initifile
+     **/
+    MeshCreator(std::string const& name)
+      : name_(name)
+    {}
+
+    /// Create a new grid by inspecting the intifile parameter group `[meshName]`
+    /**
+     * Reads first the parameter `[meshName]->macro file name` and if set
+     * - reads the grid from file
+     *
+     * Otherwise reads the parameter `[meshName]->structured` and if set, creates:
+     * - cube: a structured cube grid
+     * - simplex: a structured simplex grid
+     *
+     * Otherwise tries to create a grid depending on the grid type.
+     **/
+    std::unique_ptr<Grid> create() const
+    {
+      auto filename = Parameters::get<std::string>(name_ + "->macro file name");
+      auto structured = Parameters::get<std::string>(name_ + "->structured");
+      if (filename) {
+        // read a macro file
+        return create_unstructured_grid(filename.value());
+      } else if (structured) {
+        // create structured grids
+        if (structured.value() == "cube") {
+          return create_cube_grid();
+        } else if (structured && structured.value() == "simplex") {
+          return create_simplex_grid();
+        } else {
+          error_exit("Unknown structured grid type. Must be either `cube` or `simplex` in parameter [meshName]->structured.");
+          return {};
+        }
+      } else {
+        // decide by inspecting the grid type how to create the grid
+        return create_by_gridtype<Grid>(Dune::PriorityTag<42>{});
+      }
+    }
+
+    /// Create a structured cube grid
+    std::unique_ptr<Grid> create_cube_grid() const
+    {
+      return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
+      {
+        return Dune::StructuredGridFactory<Grid>::createCubeGrid(lower, upper, numCells);
+      });
+    }
+
+    /// Create a structured simplex grid
+    std::unique_ptr<Grid> create_simplex_grid() const
+    {
+      return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
+      {
+        return MacroGridFactory<Grid>::createSimplexGrid(lower, upper, numCells);
+      });
+    }
+
+    /// Return the filled vector of boundary ids. NOTE: not all creators support reading this.
+    std::vector<int> const& boundaryIds() const
+    {
+      return boundaryIds_;
+    }
+
+    /// Return the filled vector of element ids. NOTE: not all creators support reading this.
+    std::vector<int> const& elementIds() const
+    {
+      return elementIds_;
+    }
+
+  private:
+    // use the structured grid factory to create the grid
+    template <class Factory>
+    std::unique_ptr<Grid> create_structured_grid(Factory factory) const
+    {
+      // Lower left corner of the domain
+      Dune::FieldVector<ctype,int(dimworld)> lower(0);
+      // Upper right corner of the domain
+      Dune::FieldVector<ctype,int(dimworld)> upper(1);
+      // number of blocks in each coordinate direction
+      auto numCells = Dune::filledArray<std::size_t(dimension),unsigned int>(1);
+
+      Parameters::get(name_ + "->min corner", lower);
+      Parameters::get(name_ + "->max corner", upper);
+      Parameters::get(name_ + "->num cells", numCells);
+      return factory(lower, upper, numCells);
+    }
+
+    // read a filename from `[meshName]->macro file name` and determine from the extension the fileformat
+    std::unique_ptr<Grid> create_unstructured_grid(std::string const& filename) const
+    {
+      filesystem::path fn(filename);
+      auto ext = fn.extension();
+
+      if (ext == ".msh") {
+        return read_gmsh_file<Grid>(filename, Dune::PriorityTag<42>{});
+      }
+      else if (ext == ".1d" || ext == ".2d" || ext == ".3d" || ext == ".amc") {
+        return read_alberta_file<Grid>(filename, Dune::PriorityTag<42>{});
+      }
+      else {
+        error_exit("Can not read grid file. Unknown file extension.");
+        return {};
+      }
+    }
+
+    template <class GridType>
+    using SupportsGmshReader = decltype(std::declval<Dune::GridFactory<GridType>>().insertBoundarySegment(
+      std::declval<std::vector<unsigned int>>(),
+      std::declval<std::shared_ptr<Dune::BoundarySegment<GridType::dimension, GridType::dimensionworld> >>()) );
+
+    // use GmshReader if GridFactory supports insertBoundarySegments
+    template <class GridType = Grid,
+      REQUIRES(Dune::Std::is_detected<SupportsGmshReader, GridType>::value)>
+    std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<2>) const
+    {
+      Dune::GmshReader<GridType> reader;
+      return std::unique_ptr<GridType>{reader.read(filename, boundaryIds_, elementIds_)};
+    }
+
+    // fallback if GmshReader cannot be used
+    template <class GridType = Grid>
+    std::unique_ptr<GridType> read_gmsh_file(std::string const& filename, Dune::PriorityTag<0>) const
+    {
+      error_exit("Gmsh reader not supported for this grid type!");
+      return {};
+    }
+
+    // read from Alberta file
+
+#if HAVE_ALBERTA
+    template <class GridType>
+    using IsAlbertaGrid = decltype(std::declval<GridType>().alberta2dune(0,0));
+
+    // construct the albertagrid directly from a filename
+    template <class GridType = Grid,
+      REQUIRES(GridType::dimensionworld == DIM_OF_WORLD),
+      REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)>
+    std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<3>) const
+    {
+      return std::make_unique<GridType>(filename);
+    }
+
+    // use a gridfactory and the generic AlbertaReader
+    template <class GridType = Grid,
+      REQUIRES(GridType::dimensionworld == DIM_OF_WORLD)>
+    std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<2>) const
+    {
+      Dune::GridFactory<GridType> factory;
+      Dune::AlbertaReader<GridType> reader;
+      reader.readGrid(filename, factory);
+      return std::unique_ptr<GridType>{factory.createGrid()};
+    }
+
+    // error if WORLDDIM not the same as Grid::dimensionworld
+    template <class GridType = Grid,
+      REQUIRES(GridType::dimensionworld != DIM_OF_WORLD)>
+    std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<1>) const
+    {
+      error_exit("Alberta (and AlbertaReader) require WORLDDIM == Grid::dimensionworld. Change the cmake parameters!");
+      return {};
+    }
+#else
+    // fallback if no Alberta is available
+    template <class GridType>
+    std::unique_ptr<GridType> read_alberta_file(std::string const& filename, Dune::PriorityTag<0>) const
+    {
+      error_exit("Alberta (and AlbertaReader) not available. Set AlbertaFlags to your executable in cmake!");
+      return {};
+    }
+#endif
+
+
+#if HAVE_ALBERTA
+    // albertagrid -> simplex
+    template <class GridType = Grid,
+      REQUIRES(Dune::Std::is_detected<IsAlbertaGrid, GridType>::value)>
+    std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<3>) const
+    {
+      return create_simplex_grid();
+    }
+#endif
+
+    // yasp grid -> cube
+    template <class GridType = Grid,
+      class = typename GridType::YGrid>
+    std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<2>) const
+    {
+      return create_cube_grid();
+    }
+
+#if HAVE_DUNE_SPGRID
+    // spgrid -> cube
+    template <class GridType = Grid,
+      class = typename GridType::ReferenceCube,
+      class = typename GridType::MultiIndex>
+    std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<1>) const
+    {
+      return create_structured_grid([](auto&& lower, auto&& upper, auto&& numCells)
+      {
+        std::array<int,dimworld> cells;
+        std::copy(std::begin(numCells), std::end(numCells), std::begin(cells));
+        typename GridType::MultiIndex multiIndex(cells);
+        return std::make_unique<GridType>(lower, upper, multiIndex);
+      });
+    }
+#endif
+
+    // final fallback
+    template <class GridType = Grid>
+    std::unique_ptr<GridType> create_by_gridtype(Dune::PriorityTag<0>) const
+    {
+      error_exit("Don't know how to create the grid.");
+      return {};
+    }
+
+  private:
+    std::string name_;
+    mutable std::vector<int> boundaryIds_;
+    mutable std::vector<int> elementIds_;
+  };
+
+
+} // end namespace AMDiS
diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp
index 005cf68eeb8afa62ed9e4213293fe8222d377395..faf6a34219f968efe7d481dfd0001d3695f97a1e 100644
--- a/src/amdis/ProblemStat.hpp
+++ b/src/amdis/ProblemStat.hpp
@@ -22,7 +22,7 @@
 #include <amdis/LinearAlgebra.hpp>
 #include <amdis/OperatorList.hpp>
 #include <amdis/Marker.hpp>
-#include <amdis/Mesh.hpp>
+#include <amdis/MeshCreator.hpp>
 #include <amdis/PeriodicBC.hpp>
 #include <amdis/ProblemStatBase.hpp>
 #include <amdis/ProblemStatTraits.hpp>
diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp
index 0a942639d2b8038814a3c898a271384b12087f2d..34d552a6fe77401f218dbcf0df33163d3f6a4666 100644
--- a/src/amdis/ProblemStat.inc.hpp
+++ b/src/amdis/ProblemStat.inc.hpp
@@ -126,8 +126,11 @@ template <class Traits>
 void ProblemStat<Traits>::createGrid()
 {
   Parameters::get(name_ + "->mesh", gridName_);
-  grid_ = MeshCreator<Grid>::create(gridName_);
+  MeshCreator<Grid> creator(gridName_);
+  grid_ = creator.create();
   boundaryManager_ = std::make_shared<BoundaryManager<Grid>>(grid_);
+  if (!creator.boundaryIds().empty())
+    boundaryManager_->setBoundaryIds(creator.boundaryIds());
 
   msg("Create grid:");
   msg("#elements = {}"   , grid_->size(0));
diff --git a/src/amdis/common/Concepts.hpp b/src/amdis/common/Concepts.hpp
index fc4aba7ad538be05eb359d8f4c6a73029e0bb8df..3a43c784c6badb7a470ff8b6b5a2577e4a4ad2e0 100644
--- a/src/amdis/common/Concepts.hpp
+++ b/src/amdis/common/Concepts.hpp
@@ -53,6 +53,17 @@ namespace AMDiS
     struct IsReferenceWrapper<std::reference_wrapper<T>>
       : std::true_type {};
 
+
+    template <class, class = void>
+    struct IsDefined
+      : std::false_type {};
+
+    template <class T>
+    struct IsDefined<T, std::enable_if_t<std::is_object<T>::value &&
+                                        !std::is_pointer<T>::value &&
+                                        (sizeof(T) > 0)> >
+      : std::true_type {};
+
   } // end namespace Traits
 
   namespace Concepts
@@ -117,6 +128,9 @@ namespace AMDiS
     template <class MI>
     constexpr bool MultiIndex = models<Definition::MultiIndex(MI)>;
 
+    template <class T>
+    constexpr bool Defined = Traits::IsDefined<T>::value;
+
     /** @} **/
 
   } // end namespace Concepts
diff --git a/src/amdis/utility/CMakeLists.txt b/src/amdis/utility/CMakeLists.txt
index f9300e39e6bb22f3525dfc4a04c93363f0e6e03c..870230af8d6cc5e42061d2bffb6e135918017f11 100644
--- a/src/amdis/utility/CMakeLists.txt
+++ b/src/amdis/utility/CMakeLists.txt
@@ -2,5 +2,6 @@ install(FILES
     AssembleOperators.hpp
     LocalBasisCache.hpp
     LocalToGlobalAdapter.hpp
+    MacroGridFactory.hpp
     QuadratureFactory.hpp
 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/utility)
diff --git a/src/amdis/utility/MacroGridFactory.hpp b/src/amdis/utility/MacroGridFactory.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..26b0eae6acb09391bd5cf01564d04417f10e98b1
--- /dev/null
+++ b/src/amdis/utility/MacroGridFactory.hpp
@@ -0,0 +1,150 @@
+#pragma once
+
+#include <dune/common/typeutilities.hh>
+#include <dune/common/version.hh>
+#include <dune/grid/utility/structuredgridfactory.hh>
+
+#if ! DUNE_VERSION_GT(DUNE_GRID,2,6)
+  #include <dune/grid/yaspgrid.hh>
+#endif
+
+namespace Dune
+{
+  template <class GridType>
+  struct CubedWrapper : public GridType {};
+
+
+  template <class GridType>
+  class GridFactory<CubedWrapper<GridType>>
+      : public GridFactoryInterface<GridType>
+  {
+    using Self = GridFactory;
+    using ctype = typename GridType::ctype;
+
+    enum { dim = GridType::dimension };
+    enum { dimworld = GridType::dimensionworld };
+
+  public:
+    template <class... Args, disableCopyMove<Self, Args...> = 0>
+    GridFactory (Args&&... args)
+      : factory_(std::make_shared<GridFactory<GridType>>(std::forward<Args>(args)...))
+    {}
+
+    GridFactory (GridFactory<GridType>& factory)
+      : factory_(stackobject_to_shared_ptr(factory))
+    {}
+
+    /// \brief Insert a vertex into the coarse grid
+    void insertVertex (const FieldVector<ctype,dimworld>& pos) override
+    {
+      factory_->insertVertex(pos);
+    }
+
+    /// \brief Insert simplex elements into the coarse grid
+    /**
+     * Creates a simplex subdividion of the cube element.
+     *
+     * \param type      The GeometryType of the box grid
+     * \param vertices  Indices of the cube corners
+     **/
+    void insertElement (const GeometryType& type,
+                        const std::vector<unsigned int>& vertices) override
+    {
+      // triangulation of reference cube
+      static const auto reference_cubes = std::make_tuple(
+        std::array<std::array<int,2>, 1>{std::array<int,2>{0,1}},
+        std::array<std::array<int,3>, 2>{std::array<int,3>{3,0,1}, std::array<int,3>{0,3,2}},
+        std::array<std::array<int,4>, 6>{std::array<int,4>{0,7,3,1}, std::array<int,4>{0,7,5,1},
+                                         std::array<int,4>{0,7,5,4}, std::array<int,4>{0,7,3,2},
+                                         std::array<int,4>{0,7,6,2}, std::array<int,4>{0,7,6,4}} );
+
+      assert(type == GeometryTypes::cube(dim));
+
+      auto const& simplices = std::get<dim-1>(reference_cubes);
+      thread_local std::vector<unsigned int> corners(dim+1);
+      for (auto const& simplex : simplices) {
+        for (std::size_t i = 0; i < simplex.size(); ++i)
+          corners[i] = vertices[simplex[i]];
+
+        factory_->insertElement(GeometryTypes::simplex(dim), corners);
+      }
+    }
+
+    /// \brief insert a boundary segment
+    // TODO: maybe split boundary segment in simplices
+    void insertBoundarySegment (const std::vector<unsigned int>& vertices) override
+    {
+      factory_->insertBoundarySegment(vertices);
+    }
+
+    /// \brief Finalize grid creation and hand over the grid
+#if DUNE_VERSION_GT(DUNE_GRID,2,6)
+    ToUniquePtr<GridType> createGrid () override
+#else
+    GridType* createGrid () override
+#endif
+    {
+      return factory_->createGrid();
+    }
+
+  private:
+    std::shared_ptr<GridFactory<GridType>> factory_;
+  };
+
+} // end namespace Dune
+
+
+namespace AMDiS
+{
+  template <class GridType>
+  class MacroGridFactory
+  {
+    using ctype = typename GridType::ctype;
+
+    enum { dim = GridType::dimension };
+    enum { dimworld = GridType::dimensionworld };
+
+  public:
+#if DUNE_VERSION_GT(DUNE_GRID,2,6)
+    /// \brief insert structured simplex grid into grid factory
+    static std::unique_ptr<GridType> createSimplexGrid (Dune::GridFactory<GridType>& originalFactory,
+                                                        const Dune::FieldVector<ctype,dimworld>& lowerLeft,
+                                                        const Dune::FieldVector<ctype,dimworld>& upperRight,
+                                                        const std::array<unsigned int,dim>& numElements)
+    {
+      Dune::GridFactory<Dune::CubedWrapper<GridType>> factory(originalFactory);
+      Dune::StructuredGridFactory<Dune::CubedWrapper<GridType>>::createCubeGrid(factory, lowerLeft, upperRight, numElements);
+      return std::unique_ptr<GridType>(factory.createGrid());
+    }
+#endif
+
+    /// \brief Create a structured simplex grid
+    static std::unique_ptr<GridType> createSimplexGrid (const Dune::FieldVector<ctype,dimworld>& lowerLeft,
+                                                        const Dune::FieldVector<ctype,dimworld>& upperRight,
+                                                        const std::array<unsigned int,dim>& numElements)
+    {
+      Dune::GridFactory<Dune::CubedWrapper<GridType>> factory;
+#if DUNE_VERSION_GT(DUNE_GRID,2,6)
+      Dune::StructuredGridFactory<Dune::CubedWrapper<GridType>>::createCubeGrid(factory, lowerLeft, upperRight, numElements);
+#else
+      // fallback implementation using temporary YaspGrid
+      using TempGrid = Dune::YaspGrid<dim,Dune::EquidistantOffsetCoordinates<double,dim>>;
+      auto grid = Dune::StructuredGridFactory<TempGrid>::createCubeGrid(lowerLeft, upperRight, numElements);
+      for (auto const& v : vertices(grid->leafGridView()))
+        factory.insertVertex(v.geometry().corner(0));
+
+      auto const& indexSet = grid->leafIndexSet();
+      for (auto const& e : elements(grid->leafGridView()))
+      {
+        thread_local std::vector<unsigned int> vertices;
+        vertices.resize(e.subEntities(dim));
+        for (unsigned int i = 0; i < e.subEntities(dim); ++i)
+          vertices[i] = indexSet.subIndex(e,i,dim);
+        factory.insertElement(Dune::GeometryTypes::cube(dim), vertices);
+      }
+#endif
+      return std::unique_ptr<GridType>(factory.createGrid());
+    }
+  };
+
+} // end namespace AMDiS
diff --git a/test/MarkerTest.cpp b/test/MarkerTest.cpp
index a120ce9a6cae6719a2e91321d3656b1cd4f5a825..6ae27b0def0ca4b167c257ce9bcf5428ebca2811 100644
--- a/test/MarkerTest.cpp
+++ b/test/MarkerTest.cpp
@@ -1,6 +1,8 @@
 #include <amdis/AMDiS.hpp>
 #include <amdis/ProblemStat.hpp>
 
+#include <dune/grid/uggrid.hh>
+
 #include "Tests.hpp"
 
 using namespace AMDiS;