diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4062ab1f070e2f5a69250f003d193f52b9c67081..3833858e87934e09b964edf05a7e5a0194bcdf62 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -49,6 +49,11 @@ dune_add_test(SOURCES harmonicmaptest.cc
               CMAKE_GUARD MPI_FOUND)
 endif()
 
+if (${DUNE_COMMON_VERSION} VERSION_GREATER_EQUAL 2.9)
+  dune_add_test(SOURCES cosseratcontinuumtest.cc
+              TIMEOUT 600)
+endif()
+
 dune_add_test(SOURCES geodesicfeassemblerwrappertest.cc
               MPI_RANKS 1 4
               TIMEOUT 600
diff --git a/test/cosseratcontinuumtest.cc b/test/cosseratcontinuumtest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0e9aade92703899c67dfc5587a17d02230a1f771
--- /dev/null
+++ b/test/cosseratcontinuumtest.cc
@@ -0,0 +1,255 @@
+#include <config.h>
+
+#include <array>
+
+// Includes for the ADOL-C automatic differentiation library
+// Need to come before (almost) all others.
+#include <adolc/adouble.h>
+#include <dune/fufem/utilities/adolcnamespaceinjections.hh>
+
+#include <dune/common/parametertree.hh>
+#include <dune/common/typetraits.hh>
+#include <dune/common/bitsetvector.hh>
+
+#include <dune/grid/uggrid.hh>
+#include <dune/grid/utility/structuredgridfactory.hh>
+
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+#include <dune/functions/functionspacebases/compositebasis.hh>
+#include <dune/functions/functionspacebases/powerbasis.hh>
+#include <dune/functions/functionspacebases/interpolate.hh>
+#include <dune/functions/functionspacebases/subspacebasis.hh>
+
+#include <dune/fufem/boundarypatch.hh>
+
+#include <dune/gfe/assemblers/cosseratenergystiffness.hh>
+#include <dune/gfe/assemblers/mixedlocalgfeadolcstiffness.hh>
+#include <dune/gfe/assemblers/mixedgfeassembler.hh>
+#include <dune/gfe/mixedriemanniantrsolver.hh>
+
+// grid dimension
+const int dim = 3;
+
+// Order of the approximation space for the displacement
+const int displacementOrder = 2;
+
+// Order of the approximation space for the microrotations
+const int rotationOrder = 1;
+
+using namespace Dune;
+
+int main (int argc, char *argv[])
+{
+
+  MPIHelper::instance(argc, argv);
+
+  using SolutionType = TupleVector<std::vector<RealTuple<double,dim> >, std::vector<Rotation<double,dim> > >;
+
+  // solver settings
+  const double tolerance                = 1e-6;
+  const int maxSolverSteps              = 1000;
+  const double initialTrustRegionRadius = 1;
+  const int multigridIterations         = 200;
+  const int baseIterations              = 100;
+  const double mgTolerance              = 1e-10;
+  const double baseTolerance            = 1e-8;
+
+  // ///////////////////////////////////////
+  //    Create the grid
+  // ///////////////////////////////////////
+  using GridType = UGGrid<dim>;
+
+  //Create a grid with 2 elements, one element will get refined to create different element types, the other one stays a cube 
+  std::shared_ptr<GridType> grid = StructuredGridFactory<GridType>::createCubeGrid({0,0,0}, {1,1,1}, {2,1,1});
+
+  // Refine once
+  for (auto&& e : elements(grid->leafGridView())){
+    bool refineThisElement = false;
+    for (int i = 0; i < e.geometry().corners(); i++) {
+        refineThisElement = refineThisElement || (e.geometry().corner(i)[0] > 0.99);
+    }
+    grid->mark(refineThisElement ? 1 : 0, e);
+  }
+  grid->adapt();
+  grid->loadBalance();
+
+  using GridView = GridType::LeafGridView;
+  GridView gridView = grid->leafGridView();
+
+  // ///////////////////////////////////////////
+  //  Construct all needed function space bases
+  // ///////////////////////////////////////////
+  using namespace TypeTree::Indices;
+  using namespace Functions::BasisFactory;
+
+  const int dimRotation = Rotation<double,dim>::embeddedDim;
+  auto compositeBasis = makeBasis(
+    gridView,
+    composite(
+      power<dim>(
+          lagrange<displacementOrder>()
+      ),
+      power<dimRotation>(
+          lagrange<rotationOrder>()
+      )
+  ));
+  using CompositeBasis = decltype(compositeBasis);
+
+  using DeformationFEBasis = Functions::LagrangeBasis<GridView,displacementOrder>;
+  using OrientationFEBasis = Functions::LagrangeBasis<GridView,rotationOrder>;
+
+  DeformationFEBasis deformationFEBasis(gridView);
+  OrientationFEBasis orientationFEBasis(gridView);
+
+  // ////////////////////////////////////////////
+  //  Determine Dirichlet dofs
+  // ////////////////////////////////////////////
+  // This identityBasis is only needed to interpolate the identity for both the displacement and the rotation
+  auto identityBasis = makeBasis(
+    gridView,
+    composite(
+      power<dim>(
+          lagrange<displacementOrder>()
+      ),
+      power<dim>(
+          lagrange<rotationOrder>()
+      )
+  ));
+  auto deformationPowerBasis = Functions::subspaceBasis(identityBasis, _0);
+  auto rotationPowerBasis = Functions::subspaceBasis(identityBasis, _1);
+
+  MultiTypeBlockVector<BlockVector<FieldVector<double,dim>>,BlockVector<FieldVector<double,dim>>> identity;
+  Functions::interpolate(deformationPowerBasis, identity, [&](FieldVector<double,dim> x){ return x;});
+  Functions::interpolate(rotationPowerBasis, identity, [&](FieldVector<double,dim> x){ return x;});
+
+  BitSetVector<dim> deformationDirichletDofs(deformationFEBasis.size(), false);
+  BitSetVector<dim> orientationDirichletDofs(orientationFEBasis.size(), false);
+
+  const GridView::IndexSet& indexSet = gridView.indexSet();
+
+  // Make predicate function that computes which vertices are on the Dirichlet boundary, based on the vertex positions.
+  auto isDirichlet = [](FieldVector<double,dim> coordinate)
+  {
+    return coordinate[0] < 0.01;
+  };
+
+  for (size_t i=0; i<deformationFEBasis.size(); i++) {
+      bool isDirichletDeformation = isDirichlet(identity[_0][i]);
+      for (size_t j=0; j<dim; j++)
+          deformationDirichletDofs[i][j] = isDirichletDeformation;
+  }
+  for (size_t i=0; i<orientationFEBasis.size(); i++) {
+      bool isDirichletOrientation = isDirichlet(identity[_1][i]);
+      for (size_t j=0; j<dim; j++)
+          orientationDirichletDofs[i][j] = isDirichletOrientation;
+  }
+
+  // /////////////////////////////////////////
+  //  Determine Neumann dofs and values
+  // /////////////////////////////////////////  
+
+  std::function<bool(FieldVector<double,dim>)> isNeumann = [](FieldVector<double,dim> coordinate) {
+    return coordinate[0] > 0.99;
+  };
+
+  BitSetVector<1> neumannVertices(gridView.size(dim), false);
+  
+  for (auto&& vertex : vertices(gridView))
+      neumannVertices[indexSet.index(vertex)] = isNeumann(vertex.geometry().corner(0));
+
+  auto neumannBoundary = std::make_shared<BoundaryPatch<GridType::LeafGridView>>(gridView, neumannVertices);
+
+  FieldVector<double,dim> values_ = {0,0,0};
+  auto neumannFunction = [&](FieldVector<double, dim>){
+    return values_;
+  };
+
+  // //////////////////////////
+  //  Initial iterate
+  // //////////////////////////
+
+  SolutionType x;
+
+  x[_0].resize(compositeBasis.size({0}));
+  x[_1].resize(compositeBasis.size({1}));
+
+  // ////////////////////////////
+  //  Parameters for the problem
+  // ////////////////////////////
+
+  ParameterTree parameters;
+  parameters["thickness"] = "0.1";
+  parameters["mu"] = "1";
+  parameters["lambda"] = "1";
+  parameters["mu_c"] = "1";
+  parameters["L_c"] = "0.1";
+  parameters["q"] = "2";
+  parameters["kappa"] = "1";
+  parameters["b1"] = "1";
+  parameters["b2"] = "1";
+  parameters["b3"] = "1";
+
+  // ////////////////////////////
+  //  Create an assembler
+  // ////////////////////////////
+
+  CosseratEnergyLocalStiffness<CompositeBasis, dim,adouble> localCosseratEnergy(parameters,
+                                                                              neumannBoundary.get(),
+                                                                              neumannFunction,
+                                                                              nullptr);
+
+  MixedLocalGFEADOLCStiffness<CompositeBasis,
+                      RealTuple<double,dim>,
+                      Rotation<double,dim> > localGFEADOLCStiffness(&localCosseratEnergy);
+  MixedGFEAssembler<CompositeBasis,
+            RealTuple<double,dim>,
+            Rotation<double,dim> > mixedAssembler(compositeBasis, &localGFEADOLCStiffness);
+  
+  MixedRiemannianTrustRegionSolver<GridType,
+                                 CompositeBasis,
+                                 DeformationFEBasis, RealTuple<double,dim>,
+                                 OrientationFEBasis, Rotation<double,dim> > solver;
+  solver.setup(*grid,
+           &mixedAssembler,
+           deformationFEBasis,
+           orientationFEBasis,
+           x,
+           deformationDirichletDofs,
+           orientationDirichletDofs,
+           tolerance,
+           maxSolverSteps,
+           initialTrustRegionRadius,
+           multigridIterations,
+           mgTolerance,
+           3, 3, 1,   // Multigrid V-cycle
+           baseIterations,
+           baseTolerance,
+           false);
+
+  solver.setInitialIterate(x);
+  solver.solve();
+
+  // //////////////////////////////////////////////
+  //  Check if solver returns the expected values
+  // //////////////////////////////////////////////
+
+  size_t expectedFinalIteration = 14;
+  double expectedEnergy = 0.67188585;
+
+  if (solver.getStatistics().finalIteration != expectedFinalIteration)
+  {
+      std::cerr << "Trust-region solver did " << solver.getStatistics().finalIteration+1
+                << " iterations, instead of the expected '" << expectedFinalIteration+1 << "'!" << std::endl;
+      return 1;
+  }
+
+  if ( std::abs(solver.getStatistics().finalEnergy - expectedEnergy) > 1e-7)
+  {
+      std::cerr << std::setprecision(9);
+      std::cerr << "Final energy is " << solver.getStatistics().finalEnergy
+                << " but '" << expectedEnergy << "' was expected!" << std::endl;
+      return 1;
+  }
+
+  return 0;
+}