diff --git a/dune.module b/dune.module
index 495e6222837193efa1875164c3bf9d45229b7912..6a17dcaf439041470959d85f65e703a9df591a9d 100644
--- a/dune.module
+++ b/dune.module
@@ -8,4 +8,4 @@ Version: svn
 Maintainer: oliver.sander@tu-dresden.de
 #depending on
 Depends: dune-common(>=2.7) dune-grid(>=2.7) dune-uggrid dune-istl dune-localfunctions dune-geometry (>=2.7) dune-functions (>=2.7) dune-solvers dune-fufem dune-elasticity (>=2.7)
-Suggests: dune-foamgrid dune-parmg dune-vtk dune-curvedgeometry
+Suggests: dune-foamgrid dune-parmg dune-vtk dune-curvedgrid
diff --git a/dune/gfe/cosseratvtkwriter.hh b/dune/gfe/cosseratvtkwriter.hh
index c7012e81064f0882911a74944fad7f4aabbb1311..1ccc013a350ed54bfa8685f342a1e22e2b6fbd96 100644
--- a/dune/gfe/cosseratvtkwriter.hh
+++ b/dune/gfe/cosseratvtkwriter.hh
@@ -109,6 +109,23 @@ class CosseratVTKWriter
     }
 
 public:
+    /** \brief Write a configuration given with respect to a scalar function space basis
+     */
+    template <typename Basis>
+    static void write(const Basis& basis,
+                      const Dune::TupleVector<std::vector<RealTuple<double,3> >,
+                                        std::vector<Rotation<double,3> > >& configuration,
+                      const std::string& filename)
+    {
+      using namespace Dune::TypeTree::Indices;
+      std::vector<RigidBodyMotion<double,3>> xRBM(basis.size());
+      for (int i = 0; i < basis.size(); i++) {
+        for (int j = 0; j < 3; j ++) // Displacement part
+          xRBM[i].r[j] = configuration[_0][i][j];
+        xRBM[i].q = configuration[_1][i];    // Rotation part
+      }
+      write(basis,xRBM,filename);
+    }
 
     /** \brief Write a configuration given with respect to a scalar function space basis
      */
diff --git a/dune/gfe/geometries/moebiusstrip.hh b/dune/gfe/geometries/moebiusstrip.hh
new file mode 100644
index 0000000000000000000000000000000000000000..793c2283a3dc1cb2cf706a3a6c43327b3a0d9531
--- /dev/null
+++ b/dune/gfe/geometries/moebiusstrip.hh
@@ -0,0 +1,106 @@
+#ifndef DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH
+#define DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH
+
+#include <cmath>
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/fvector.hh>
+#include <dune/curvedgrid/gridfunctions/analyticgridfunction.hh>
+
+namespace Dune {
+
+/// \brief Functor representing a Möbius strip in 3D, where the base circle is the circle in the x-y-plane with radius_ around 0,0,0
+template <class T = double>
+class MoebiusStripProjection
+{
+  static const int dim = 3;
+  using Domain = FieldVector<T,dim>;
+  using Jacobian = FieldMatrix<T,dim,dim>;
+
+  T radius_;
+
+public:
+  MoebiusStripProjection (T radius)
+    : radius_(radius)
+  {}
+
+  /// \brief Project the coordinate to the MS using closest point projection
+  Domain operator() (const Domain& x) const
+  {
+    double nrm = std::sqrt(x[0]*x[0] + x[1]*x[1]);
+    //center for the point x - it lies on the circle around (0,0,0) with radius radius_ in the x-y-plane
+    Domain center{x[0] * radius_/nrm, x[1] * radius_/nrm, 0}; 
+    double cosu = x[0]/nrm;
+    double sinu = x[1]/nrm;
+    double cosuhalf = std::sqrt((1+cosu)/2);
+    cosuhalf *= (sinu < 0) ? (-1) : 1 ; // u goes from 0 to 2*pi, so cosuhalf is negative if sinu < 0, we multiply that here
+    double sinuhalf = std::sqrt((1-cosu)/2); //u goes from 0 to 2*pi, so sinuhalf is always >= 0 
+
+    // now calculate line from center to the new point
+    // the direction is (cosuhalf*cosu,cosuhalf*sinu,sinuhalf), as can be seen from the formula to construct the MS, we normalize this vector
+    Domain centerToPointOnMS{cosuhalf*cosu,cosuhalf*sinu,sinuhalf};
+    centerToPointOnMS /= centerToPointOnMS.two_norm();
+
+    Domain centerToX = center - x;
+    // We need the length, let theta be the angle between the vector centerToX and center to centerToPointOnMS
+    // then cos(theta) = centerToX*centerToPointOnMS/(len(centerToX)*len(centerToPointOnMS))
+    // We want to project the point to MS, s.t. the angle between the MS and the projection is 90deg
+    // Then, length = cos(theta) * len(centerToX) = centerToX*centerToPointOnMS/len(centerToPointOnMS) = centerToX*centerToPointOnMS
+    double length = - centerToX * centerToPointOnMS;
+    centerToPointOnMS *= length;
+    return center + centerToPointOnMS;
+  }
+
+
+  /// \brief derivative of the projection to the MS
+  friend auto derivative (const MoebiusStripProjection& moebiusStrip)
+  {
+    DUNE_THROW(NotImplemented,"The derivative of the projection to the Möbius strip is not implemented yet!");
+    return [radius = moebiusStrip.radius_](const Domain& x)
+    {
+      Jacobian out;
+      return out;
+    };
+  }
+
+  /// \brief Normal Vector of the MS
+  Domain normal (const Domain& x) const
+  {
+    using std::sqrt;
+    Domain nVec = {x[0],x[1],0};
+    double nrm = std::sqrt(x[0]*x[0] + x[1]*x[1]);
+    double cosu = x[0]/nrm;
+    double sinu = x[1]/nrm;
+    double cosuhalf = std::sqrt((1+cosu)/2);
+    cosuhalf *= (sinu < 0) ? (-1) : 1 ; // u goes from 0 to 2*pi, so cosuhalf is negative if sinu < 0, we multiply that here
+    double sinuhalf = std::sqrt((1-cosu)/2);
+    nVec[2] = (-1)*cosuhalf*(cosu*x[0]+sinu*x[1])/sinuhalf;
+    nVec /= nVec.two_norm();
+    return nVec;
+  }
+
+  /// \brief The mean curvature of the MS
+  T mean_curvature (const Domain& /*x*/) const
+  {
+    DUNE_THROW(NotImplemented,"The mean curvature of the Möbius strip is not implemented yet!");
+    return 1;
+  }
+
+  /// \brief The area of the MS
+  T area () const
+  {
+    DUNE_THROW(NotImplemented,"The area of the Möbius strip is not implemented yet!");
+    return 1;
+  }
+};
+
+/// \brief construct a grid function representing the parametrization of a MS
+template <class Grid, class T>
+auto moebiusStripGridFunction (T radius)
+{
+  return analyticGridFunction<Grid>(MoebiusStripProjection<T>{radius});
+}
+
+} // end namespace Dune
+
+#endif // DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH
diff --git a/dune/gfe/geometries/twistedstrip.hh b/dune/gfe/geometries/twistedstrip.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d7af48436d18dc99f9c8b787d8f94865448a5c6b
--- /dev/null
+++ b/dune/gfe/geometries/twistedstrip.hh
@@ -0,0 +1,104 @@
+#ifndef DUNE_GFE_TWISTEDSTRIP_GRIDFUNCTION_HH
+#define DUNE_GFE_TWISTEDSTRIP_GRIDFUNCTION_HH
+
+#include <cmath>
+
+#include <dune/common/fmatrix.hh>
+#include <dune/common/fvector.hh>
+#include <dune/curvedgrid/gridfunctions/analyticgridfunction.hh>
+
+namespace Dune {
+
+/// \brief Functor representing a twisted strip in 3D, with length length_ and nTwists twists
+template <class T = double>
+class TwistedStripProjection
+{
+  static const int dim = 3;
+  using Domain = FieldVector<T,dim>;
+  using Jacobian = FieldMatrix<T,dim,dim>;
+
+  T length_;
+  double nTwists_;
+
+public:
+  TwistedStripProjection (T length, double nTwists)
+    : length_(length),  
+      nTwists_(nTwists)
+  {}
+
+  /// \brief Project the coordinate to the twisted strip using closest point projection
+  Domain operator() (const Domain& x) const
+  {
+    // Angle for the x - position of the point
+    double alpha = std::acos(-1)*nTwists_*x[0]/length_;
+    double cosalpha = std::cos(alpha);
+    double sinalpha = std::sin(alpha);
+
+    // Add the line from middle to the new point - the direction is (0,cosalpha,sinalpha)
+    // We need the distance, calculated by (y^2 + z^2)^0.5
+    double dist = std::sqrt(x[1]*x[1] + x[2]*x[2]);
+    double y = std::abs(cosalpha*dist);
+    if (x[1] < 0 and std::abs(x[1]) > std::abs(x[2])) { // only trust the sign of x[1] if it is larger than x[2]
+      y *= (-1);
+    } else if (std::abs(x[1]) <= std::abs(x[2])) {
+      if (cosalpha * sinalpha >= 0 and x[2] < 0) // if cosalpha*sinalpha > 0, x[1] and x[2] must have the same sign
+        y *= (-1);
+      if (cosalpha * sinalpha <= 0 and x[2] > 0) // if cosalpha*sinalpha < 0, x[1] and x[2] must have opposite signs
+        y *= (-1);
+    }
+    double z = std::abs(sinalpha*dist);
+    if (x[2] < 0 and std::abs(x[2]) > std::abs(x[1])) {
+      z *= (-1);
+    } else if (std::abs(x[2]) <= std::abs(x[1])) {
+      if (cosalpha * sinalpha >= 0 and x[1] < 0)
+        z *= (-1);
+      if (cosalpha * sinalpha <= 0 and x[1] > 0)
+        z *= (-1);
+    }
+    return {x[0], y , z};
+  }
+
+  /// \brief derivative of the projection to the twistedstrip
+  friend auto derivative (const TwistedStripProjection& twistedStrip)
+  {
+    DUNE_THROW(NotImplemented,"The derivative of the projection to the twisted strip is not implemented yet!");
+    return [length = twistedStrip.length_, nTwists = twistedStrip.nTwists_](const Domain& x)
+    {
+      Jacobian out;
+      return out;
+    };
+  }
+
+  /// \brief Normal Vector of the twisted strip
+  Domain normal (const Domain& x) const
+  {
+    // Angle for the x - position of the point
+    double alpha = std::acos(-1)*nTwists_*x[0]/length_;
+    std::cout << "normal at " << x[0] << "is " << -std::sin(alpha) << ", " << std::cos(alpha) << std::endl; 
+    return {0,-std::sin(alpha), std::cos(alpha)};
+  }
+
+  /// \brief The mean curvature of the twisted strip
+  T mean_curvature (const Domain& /*x*/) const
+  {
+    DUNE_THROW(NotImplemented,"The mean curvature of the twisted strip is not implemented yet!");
+    return 1;
+  }
+
+  /// \brief The area of the twisted strip
+  T area (T width) const
+  {
+    return length_*width;
+  }
+};
+
+/// \brief construct a grid function representing the parametrization of a twisted strip
+template <class Grid, class T>
+auto twistedStripGridFunction (T length, double nTwists)
+{
+  return analyticGridFunction<Grid>(TwistedStripProjection<T>{length, nTwists});
+}
+
+} // end namespace Dune
+
+#endif // DUNE_GFE_TWISTEDSTRIP_GRIDFUNCTION_HH
diff --git a/dune/gfe/nonplanarcosseratshellenergy.hh b/dune/gfe/nonplanarcosseratshellenergy.hh
index 8fd0aceb4de0effe76dc7d854a990bf5cd7396d2..21a1f2a9e390bff5db91d6984bfcce7b03c56343 100644
--- a/dune/gfe/nonplanarcosseratshellenergy.hh
+++ b/dune/gfe/nonplanarcosseratshellenergy.hh
@@ -9,6 +9,8 @@
 
 #include <dune/fufem/boundarypatch.hh>
 
+#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
+
 #include <dune/gfe/localenergy.hh>
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/rigidbodymotion.hh>
@@ -21,7 +23,15 @@
 #include <dune/localfunctions/lagrange/lfecache.hh>
 #endif
 
-template<class Basis, int dim, class field_type=double>
+/** \brief Assembles the cosserat energy for a single element.
+ *
+ * \tparam Basis                       Type of the Basis used for assembling
+ * \tparam dim                         Dimension of the Targetspace, 3
+ * \tparam field_type                  The coordinate type of the TargetSpace
+ * \tparam StressFreeStateGridFunction Type of the GridFunction representing the Cosserat shell in a stress free state
+ */
+template<class Basis, int dim, class field_type=double, class StressFreeStateGridFunction = 
+  Dune::Functions::DiscreteGlobalBasisFunction<Basis,std::vector<Dune::FieldVector<double, Basis::GridView::dimensionworld>> > >
 class NonplanarCosseratShellEnergy
   : public Dune::GFE::LocalEnergy<Basis,RigidBodyMotion<field_type,dim> >
 {
@@ -40,13 +50,16 @@ class NonplanarCosseratShellEnergy
 public:
 
   /** \brief Constructor with a set of material parameters
-   * \param parameters The material parameters
+   * \param parameters                  The material parameters
+   * \param stressFreeStateGridFunction Pointer to a parametrization representing the Cosserat shell in a stress-free state
    */
   NonplanarCosseratShellEnergy(const Dune::ParameterTree& parameters,
+                               const StressFreeStateGridFunction* stressFreeStateGridFunction,
                                const BoundaryPatch<GridView>* neumannBoundary,
                                const std::function<Dune::FieldVector<double,3>(Dune::FieldVector<double,dimworld>)> neumannFunction,
                                const std::function<Dune::FieldVector<double,3>(Dune::FieldVector<double,dimworld>)> volumeLoad)
-  : neumannBoundary_(neumannBoundary),
+  : stressFreeStateGridFunction_(stressFreeStateGridFunction),
+    neumannBoundary_(neumannBoundary),
     neumannFunction_(neumannFunction),
     volumeLoad_(volumeLoad)
   {
@@ -111,6 +124,9 @@ public:
   /** \brief Curvature parameters */
   double b1_, b2_, b3_;
 
+  /** \brief The geometry used for assembling */
+  const StressFreeStateGridFunction* stressFreeStateGridFunction_;
+
   /** \brief The Neumann boundary */
   const BoundaryPatch<GridView>* neumannBoundary_;
 
@@ -121,15 +137,34 @@ public:
   const std::function<Dune::FieldVector<double,3>(Dune::FieldVector<double,dimworld>)> volumeLoad_;
 };
 
-template <class Basis, int dim, class field_type>
-typename NonplanarCosseratShellEnergy<Basis,dim,field_type>::RT
-NonplanarCosseratShellEnergy<Basis,dim,field_type>::
+template <class Basis, int dim, class field_type, class StressFreeStateGridFunction>
+typename NonplanarCosseratShellEnergy<Basis, dim, field_type, StressFreeStateGridFunction>::RT
+NonplanarCosseratShellEnergy<Basis,dim,field_type, StressFreeStateGridFunction>::
 energy(const typename Basis::LocalView& localView,
        const std::vector<RigidBodyMotion<field_type,dim> >& localSolution) const
 {
   // The element geometry
   auto element = localView.element();
+
+#if HAVE_DUNE_CURVEDGEOMETRY
+  // Construct a curved geometry of this element of the Cosserat shell in stress-free state
+  // When using element.geometry(), then the curvatures on the element are zero, when using a curved geometry, they are not
+  // If a parametrization representing the Cosserat shell in a stress-free state is given,
+  // this is used for the curved geometry approximation.
+  // The variable local holds the local coordinates in the reference element
+  // and localGeometry.global maps them to the world coordinates
+  Dune::CurvedGeometry<DT, gridDim, dimworld, Dune::CurvedGeometryTraits<DT, Dune::LagrangeLFECache<DT,DT,gridDim>>> geometry(referenceElement(element),
+    [this,element](const auto& local) {
+      if (not stressFreeStateGridFunction_) {
+        return element.geometry().global(local);
+      }
+      auto localGridFunction = localFunction(*stressFreeStateGridFunction_);
+      localGridFunction.bind(element);
+      return localGridFunction(local);
+    }, 2); /*order*/
+#else
   auto geometry = element.geometry();
+#endif
 
   // The set of shape functions on this element
   const auto& localFiniteElement = localView.tree().finiteElement();
@@ -215,17 +250,8 @@ energy(const typename Basis::LocalView& localView,
         c += aScalar * eps[alpha][beta] * Dune::GFE::dyadicProduct(aContravariant[alpha], aContravariant[beta]);
 
 #if HAVE_DUNE_CURVEDGEOMETRY
-    // Construct a curved geometry to evaluate the derivative of the normal field on each quadrature point
-    // The variable local holds the local coordinates in the reference element
-    // and localGeometry.global maps them to the world coordinates
-    // we want to take the derivative of the normal field on the element in world coordinates
-    Dune::CurvedGeometry<DT, gridDim, dimworld, Dune::CurvedGeometryTraits<DT, Dune::LagrangeLFECache<DT,DT,gridDim>>> curvedGeometry(referenceElement(element),
-      [localGeometry=element.geometry()](const auto& local) {
-        return localGeometry.global(local);
-      }, 1); //order = 1
-
-    // Second fundamental form: The derivative of the normal field
-    auto normalDerivative = curvedGeometry.normalGradient(quad[pt].position());
+    // Second fundamental form: The derivative of the normal field, on each quadrature point
+    auto normalDerivative = geometry.normalGradient(quad[pt].position());
 #else
     //In case dune-curvedgeometry is not installed, the normal derivative is set to zero.
     Dune::FieldMatrix<double,3,3> normalDerivative(0);
diff --git a/dune/gfe/riemannianpnsolver.cc b/dune/gfe/riemannianpnsolver.cc
index 8e0ca8bc5dd8478f53a1123463ae8353c2619d1b..bb7dc9c666d9d94e14b4a825ec0c99887dab3826 100644
--- a/dune/gfe/riemannianpnsolver.cc
+++ b/dune/gfe/riemannianpnsolver.cc
@@ -67,7 +67,7 @@ setup(const GridType& grid,
     // //////////////////////////////////////////////////////////////////////////////////////
 
     typedef DuneFunctionsBasis<Basis> FufemBasis;
-    FufemBasis basis(assembler_->basis_);
+    FufemBasis basis(assembler_->getBasis());
     OperatorAssembler<FufemBasis,FufemBasis> operatorAssembler(basis, basis);
 
     LaplaceAssembler<GridType, typename FufemBasis::LocalFiniteElement, typename FufemBasis::LocalFiniteElement> laplaceStiffness;
diff --git a/problems/cosserat-continuum-cantilever.parset b/problems/cosserat-continuum-cantilever.parset
index a697675dde85aed1bb666aa657d391ded7affca2..9440301af2c2e3a244b9799310e33768d16e1212 100644
--- a/problems/cosserat-continuum-cantilever.parset
+++ b/problems/cosserat-continuum-cantilever.parset
@@ -24,7 +24,7 @@ numHomotopySteps = 1
 tolerance = 1e-3
 
 # Max number of steps of the trust region solver
-maxTrustRegionSteps = 200
+maxSolverSteps = 200
 
 trustRegionScaling = 1 1 1 0.01 0.01 0.01
 
diff --git a/problems/cosserat-continuum-wriggers-l-shape.parset b/problems/cosserat-continuum-wriggers-l-shape.parset
index eb108bf0f5cbdf7474cd46f1234f78c263009278..12c715bd9e9618fa4ce069b8409584294f0f5660 100644
--- a/problems/cosserat-continuum-wriggers-l-shape.parset
+++ b/problems/cosserat-continuum-wriggers-l-shape.parset
@@ -20,7 +20,7 @@ numHomotopySteps = 1
 tolerance = 1e-8
 
 # Max number of steps of the trust region solver
-maxTrustRegionSteps = 1000
+maxSolverSteps = 1000
 
 trustRegionScaling = 1 1 1 0.01 0.01 0.01
 
diff --git a/problems/film-on-substrate.parset b/problems/film-on-substrate.parset
index 55b999fca1bb4703c13bd3126015711877869661..8ccce0d1c12ba5b5145e813910dade3ba1281cea 100644
--- a/problems/film-on-substrate.parset
+++ b/problems/film-on-substrate.parset
@@ -59,7 +59,7 @@ initialDeformation = "x"
 #############################################
 
 # Inner solver, cholmod or multigrid
-solvertype = multigrid
+solvertype = trustRegion
 
 # Number of homotopy steps for the Dirichlet boundary conditions
 numHomotopySteps = 1
diff --git a/src/cosserat-continuum.cc b/src/cosserat-continuum.cc
index fb68dbcd00eb541d27049b8843c6eafc6612b472..19fcf4135b2debf46457c937552555e858481b33 100644
--- a/src/cosserat-continuum.cc
+++ b/src/cosserat-continuum.cc
@@ -1,3 +1,5 @@
+#define MIXED_SPACE 0
+
 #include <config.h>
 
 #include <fenv.h>
@@ -37,7 +39,6 @@
 #include <dune/solvers/solvers/iterativesolver.hh>
 #include <dune/solvers/norms/energynorm.hh>
 
-#include <dune/gfe/rigidbodymotion.hh>
 #include <dune/gfe/localgeodesicfeadolcstiffness.hh>
 #include <dune/gfe/mixedlocalgfeadolcstiffness.hh>
 #include <dune/gfe/cosseratenergystiffness.hh>
@@ -45,10 +46,17 @@
 #include <dune/gfe/cosseratvtkwriter.hh>
 #include <dune/gfe/cosseratvtkreader.hh>
 #include <dune/gfe/geodesicfeassembler.hh>
-#include <dune/gfe/riemanniantrsolver.hh>
 #include <dune/gfe/embeddedglobalgfefunction.hh>
 #include <dune/gfe/mixedgfeassembler.hh>
+
+#if MIXED_SPACE
 #include <dune/gfe/mixedriemanniantrsolver.hh>
+#else
+#include <dune/gfe/geodesicfeassemblerwrapper.hh>
+#include <dune/gfe/riemannianpnsolver.hh>
+#include <dune/gfe/riemanniantrsolver.hh>
+#include <dune/gfe/rigidbodymotion.hh>
+#endif
 
 #if HAVE_DUNE_VTK
 #include <dune/vtk/vtkreader.hh>
@@ -59,22 +67,17 @@
 const int dim = 2;
 const int dimworld = 2;
 
-//#define MIXED_SPACE
-
 // Order of the approximation space for the displacement
 const int displacementOrder = 2;
 
 // Order of the approximation space for the microrotations
 const int rotationOrder = 2;
 
-#ifndef MIXED_SPACE
+#if !MIXED_SPACE
 static_assert(displacementOrder==rotationOrder, "displacement and rotation order do not match!");
 
 // Image space of the geodesic fe functions
-typedef RigidBodyMotion<double,3> TargetSpace;
-
-// Tangent vector of the image space
-const int blocksize = TargetSpace::TangentVector::dimension;
+using TargetSpace = RigidBodyMotion<double, 3>;
 #endif
 
 using namespace Dune;
@@ -84,6 +87,15 @@ int main (int argc, char *argv[]) try
     // initialize MPI, finalize is done automatically on exit
     Dune::MPIHelper& mpiHelper = MPIHelper::instance(argc, argv);
 
+    if (mpiHelper.rank()==0) {
+        std::cout << "DISPLACEMENTORDER = " << displacementOrder << ", ROTATIONORDER = " << rotationOrder << std::endl;
+        std::cout << "dim = " << dim << ", dimworld = " << dimworld << std::endl;
+    #if MIXED_SPACE
+        std::cout << "MIXED_SPACE = 1" << std::endl;
+    #else
+        std::cout << "MIXED_SPACE = 0" << std::endl;
+    #endif
+    }
     // Start Python interpreter
     Python::start();
     Python::Reference main = Python::import("__main__");
@@ -97,12 +109,8 @@ int main (int argc, char *argv[]) try
         << std::endl;
 
     using namespace TypeTree::Indices;
-#ifdef MIXED_SPACE
     using SolutionType = TupleVector<std::vector<RealTuple<double,3> >,
                                      std::vector<Rotation<double,3> > >;
-#else
-    typedef std::vector<TargetSpace> SolutionType;
-#endif
 
     // parse data file
     ParameterTree parameterSet;
@@ -117,7 +125,8 @@ int main (int argc, char *argv[]) try
     const int numLevels                   = parameterSet.get<int>("numLevels");
     int numHomotopySteps                  = parameterSet.get<int>("numHomotopySteps");
     const double tolerance                = parameterSet.get<double>("tolerance");
-    const int maxTrustRegionSteps         = parameterSet.get<int>("maxTrustRegionSteps");
+    const int maxSolverSteps              = parameterSet.get<int>("maxSolverSteps");
+    const double initialRegularization    = parameterSet.get<double>("initialRegularization", 1000);
     const double initialTrustRegionRadius = parameterSet.get<double>("initialTrustRegionRadius");
     const int multigridIterations         = parameterSet.get<int>("numIt");
     const int nu1                         = parameterSet.get<int>("nu1");
@@ -145,6 +154,8 @@ int main (int argc, char *argv[]) try
 
     std::string structuredGridType = parameterSet["structuredGrid"];
     if (structuredGridType == "cube") {
+        if (dim!=dimworld)
+            DUNE_THROW(GridError, "Please use FoamGrid and read in a grid for problems with dim != dimworld.");
 
         lower = parameterSet.get<FieldVector<double,dimworld> >("lower");
         upper = parameterSet.get<FieldVector<double,dimworld> >("upper");
@@ -183,7 +194,7 @@ int main (int argc, char *argv[]) try
     GridView gridView = grid->leafGridView();
 
     using namespace Dune::Functions::BasisFactory;
-#ifdef MIXED_SPACE
+
     const int dimRotation = Rotation<double,dim>::embeddedDim;
     auto compositeBasis = makeBasis(
       gridView,
@@ -195,6 +206,13 @@ int main (int argc, char *argv[]) try
             lagrange<rotationOrder>()
         )
     ));
+    using CompositeBasis = decltype(compositeBasis);
+
+    auto deformationPowerBasis = makeBasis(
+        gridView,
+        power<3>(
+            lagrange<displacementOrder>()
+    ));
 
     typedef Dune::Functions::LagrangeBasis<GridView,displacementOrder> DeformationFEBasis;
     typedef Dune::Functions::LagrangeBasis<GridView,rotationOrder> OrientationFEBasis;
@@ -202,10 +220,6 @@ int main (int argc, char *argv[]) try
     DeformationFEBasis deformationFEBasis(gridView);
     OrientationFEBasis orientationFEBasis(gridView);
 
-#else
-    typedef Dune::Functions::LagrangeBasis<typename GridType::LeafGridView, displacementOrder> FEBasis;
-    FEBasis feBasis(gridView);
-#endif
 
     // /////////////////////////////////////////
     //   Read Dirichlet values
@@ -237,10 +251,10 @@ int main (int argc, char *argv[]) try
     BoundaryPatch<GridView> dirichletBoundary(gridView, dirichletVertices);
     BoundaryPatch<GridView> neumannBoundary(gridView, neumannVertices);
 
-    if (mpiHelper.rank()==0)
-      std::cout << "Neumann boundary has " << neumannBoundary.numFaces() << " faces\n";
-
-#ifdef MIXED_SPACE
+    std::cout << "On rank " << mpiHelper.rank() << ": Dirichlet boundary has " << dirichletBoundary.numFaces()
+              << " faces and " << dirichletVertices.count() << " nodes.\n";
+    std::cout << "On rank " << mpiHelper.rank() << ": Neumann boundary has " << neumannBoundary.numFaces() << " faces.\n";
+  
     BitSetVector<1> deformationDirichletNodes(deformationFEBasis.size(), false);
     constructBoundaryDofs(dirichletBoundary,deformationFEBasis,deformationDirichletNodes);
 
@@ -261,43 +275,26 @@ int main (int argc, char *argv[]) try
       if (orientationDirichletNodes[i][0])
         for (int j=0; j<3; j++)
           orientationDirichletDofs[i][j] = true;
-#else
-    BitSetVector<1> dirichletNodes(feBasis.size(), false);
-    constructBoundaryDofs(dirichletBoundary,feBasis,dirichletNodes);
-
-    BitSetVector<1> neumannNodes(feBasis.size(), false);
-    constructBoundaryDofs(neumannBoundary,feBasis,neumannNodes);
-
-
-    BitSetVector<blocksize> dirichletDofs(feBasis.size(), false);
-    for (size_t i=0; i<feBasis.size(); i++)
-      if (dirichletNodes[i][0])
-        for (int j=0; j<5; j++)
-          dirichletDofs[i][j] = true;
-#endif
 
     // //////////////////////////
     //   Initial iterate
     // //////////////////////////
 
-#ifdef MIXED_SPACE
     SolutionType x;
 
-    x[_0].resize(deformationFEBasis.size());
+    x[_0].resize(compositeBasis.size({0}));
 
     lambda = std::string("lambda x: (") + parameterSet.get<std::string>("initialDeformation") + std::string(")");
     auto pythonInitialDeformation = Python::make_function<FieldVector<double,3> >(Python::evaluate(lambda));
 
     std::vector<FieldVector<double,3> > v;
-    Functions::interpolate(deformationFEBasis, v, pythonInitialDeformation);
+    Functions::interpolate(deformationPowerBasis, v, pythonInitialDeformation);
 
     for (size_t i=0; i<x[_0].size(); i++)
       x[_0][i] = v[i];
 
-    x[_1].resize(orientationFEBasis.size());
-#else
-    SolutionType x(feBasis.size());
-
+    x[_1].resize(compositeBasis.size({1}));
+#if !MIXED_SPACE
     if (parameterSet.hasKey("startFromFile"))
     {
       std::shared_ptr<GridType> initialIterateGrid;
@@ -314,35 +311,32 @@ int main (int argc, char *argv[]) try
         initialIterateGrid = std::shared_ptr<GridType>(GmshReader<GridType>::read(path + "/" + initialIterateGridFilename));
       }
 
-      SolutionType initialIterate;
+      std::vector<TargetSpace> initialIterate;
       GFE::CosseratVTKReader::read(initialIterate, parameterSet.get<std::string>("initialIterateFilename"));
 
       typedef Dune::Functions::LagrangeBasis<typename GridType::LeafGridView, 2> InitialBasis;
       InitialBasis initialBasis(initialIterateGrid->leafGridView());
 
 #ifdef PROJECTED_INTERPOLATION
-      using LocalInterpolationRule  = LocalProjectedFEFunction<dim, double, FEBasis::LocalView::Tree::FiniteElement, TargetSpace>;
+      using LocalInterpolationRule  = LocalProjectedFEFunction<dim, double, DeformationFEBasis::LocalView::Tree::FiniteElement, TargetSpace>;
 #else
-      using LocalInterpolationRule  = LocalGeodesicFEFunction<dim, double, FEBasis::LocalView::Tree::FiniteElement, TargetSpace>;
+      using LocalInterpolationRule  = LocalGeodesicFEFunction<dim, double, DeformationFEBasis::LocalView::Tree::FiniteElement, TargetSpace>;
 #endif
       GFE::EmbeddedGlobalGFEFunction<InitialBasis,LocalInterpolationRule,TargetSpace> initialFunction(initialBasis,initialIterate);
-
+      auto powerBasis = makeBasis(
+          gridView,
+          power<7>(
+              lagrange<displacementOrder>()
+      ));
       std::vector<FieldVector<double,7> > v;
-      Dune::Functions::interpolate(feBasis,v,initialFunction);
-      DUNE_THROW(NotImplemented, "Replace scalar basis by power basis!");
-
-      for (size_t i=0; i<x.size(); i++)
-        x[i] = TargetSpace(v[i]);
-
-    } else {
-    lambda = std::string("lambda x: (") + parameterSet.get<std::string>("initialDeformation") + std::string(")");
-      auto pythonInitialDeformation = Python::make_function<FieldVector<double,3> >(Python::evaluate(lambda));
+      //TODO: Interpolate does not work with an GFE:EmbeddedGlobalGFEFunction
+      //Dune::Functions::interpolate(powerBasis,v,initialFunction);
 
-    std::vector<FieldVector<double,3> > v;
-      Functions::interpolate(feBasis, v, pythonInitialDeformation);
-
-    for (size_t i=0; i<x.size(); i++)
-      x[i].r = v[i];
+      for (size_t i=0; i<x.size(); i++) {
+        auto vTargetSpace = TargetSpace(v[i]);
+        x[_0][i] = vTargetSpace.r;
+        x[_1][i] = vTargetSpace.q;
+      }
     }
 #endif
 
@@ -351,14 +345,30 @@ int main (int argc, char *argv[]) try
     ////////////////////////////////////////////////////////
 
     // Output initial iterate (of homotopy loop)
-#ifdef MIXED_SPACE
+    BlockVector<FieldVector<double,3> > identity(compositeBasis.size({0}));
+    Dune::Functions::interpolate(deformationPowerBasis, identity, [&](FieldVector<double,dimworld> x){ return x;});
+    BlockVector<FieldVector<double,3> > displacement(compositeBasis.size({0}));
+
+    if (dim == dimworld) {
     CosseratVTKWriter<GridType>::writeMixed<DeformationFEBasis,OrientationFEBasis>(deformationFEBasis,x[_0],
                                                                                    orientationFEBasis,x[_1],
                                                                                    resultPath + "mixed-cosserat_homotopy_0");
+    } else {
+#if MIXED_SPACE
+        for (int i = 0; i < displacement.size(); i++) {
+            for (int j = 0; j < 3; j++)
+                displacement[i][j] = x[_0][i][j];
+            displacement[i] -= identity[i];
+        }
+        auto displacementFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3>>(deformationPowerBasis, displacement);
+    
+        SubsamplingVTKWriter<GridView> vtkWriter(gridView, Dune::refinementLevels(0));
+        vtkWriter.addVertexData(displacementFunction, VTK::FieldInfo("displacement", VTK::FieldInfo::Type::scalar, dimworld));
+        vtkWriter.write(resultPath + "mixed-cosserat_homotopy_0");
 #else
-    CosseratVTKWriter<GridType>::write<FEBasis>(feBasis,x, resultPath + "cosserat_homotopy_0");
-#endif
-
+    CosseratVTKWriter<GridType>::write<DeformationFEBasis>(deformationFEBasis, x, resultPath + "cosserat_homotopy_0");
+#endif   
+    }
     for (int i=0; i<numHomotopySteps; i++) {
 
         double homotopyParameter = (i+1)*(1.0/numHomotopySteps);
@@ -375,7 +385,7 @@ int main (int argc, char *argv[]) try
     if (parameterSet.hasKey("neumannValues"))
         neumannValues = parameterSet.get<FieldVector<double,3> >("neumannValues");
 
-    auto neumannFunction = [&]( FieldVector<double,dim> ) {
+    auto neumannFunction = [&]( FieldVector<double,dimworld> ) {
       auto nV = neumannValues;
       nV *= homotopyParameter;
       return nV;
@@ -385,7 +395,7 @@ int main (int argc, char *argv[]) try
     if (parameterSet.hasKey("volumeLoad"))
         volumeLoadValues = parameterSet.get<FieldVector<double,3> >("volumeLoad");
 
-    auto volumeLoad = [&]( FieldVector<double,dim>) {
+    auto volumeLoad = [&]( FieldVector<double,dimworld>) {
       auto vL = volumeLoadValues;
       vL *= homotopyParameter;
       return vL;
@@ -396,82 +406,6 @@ int main (int argc, char *argv[]) try
         materialParameters.report();
     }
 
-    // Assembler using ADOL-C
-#ifdef MIXED_SPACE
-    CosseratEnergyLocalStiffness<decltype(compositeBasis),
-                        3,adouble> cosseratEnergyADOLCLocalStiffness(materialParameters,
-                                                                     &neumannBoundary,
-                                                                     neumannFunction,
-                                                                     volumeLoad);
-
-    MixedLocalGFEADOLCStiffness<decltype(compositeBasis),
-                                RealTuple<double,3>,
-                                Rotation<double,3> > localGFEADOLCStiffness(&cosseratEnergyADOLCLocalStiffness);
-
-    MixedGFEAssembler<decltype(compositeBasis),
-                      RealTuple<double,3>,
-                      Rotation<double,3> > assembler(compositeBasis, &localGFEADOLCStiffness);
-#else
-    std::shared_ptr<GFE::LocalEnergy<FEBasis,RigidBodyMotion<adouble,3> > > localCosseratEnergy;
-
-    if (dim==dimworld)
-    {
-      localCosseratEnergy = std::make_shared<CosseratEnergyLocalStiffness<FEBasis,3,adouble> >(materialParameters,
-                                                                                               &neumannBoundary,
-                                                                                               neumannFunction,
-                                                                                               volumeLoad);
-    }
-    else
-    {
-      localCosseratEnergy = std::make_shared<NonplanarCosseratShellEnergy<FEBasis,3,adouble> >(materialParameters,
-                                                                                               &neumannBoundary,
-                                                                                               neumannFunction,
-                                                                                               volumeLoad);
-    }
-
-    LocalGeodesicFEADOLCStiffness<FEBasis,
-                                  TargetSpace> localGFEADOLCStiffness(localCosseratEnergy.get());
-
-    GeodesicFEAssembler<FEBasis,TargetSpace> assembler(gridView, localGFEADOLCStiffness);
-#endif
-
-    // /////////////////////////////////////////////////
-    //   Create a Riemannian trust-region solver
-    // /////////////////////////////////////////////////
-
-#ifdef MIXED_SPACE
-    MixedRiemannianTrustRegionSolver<GridType,
-                                     decltype(compositeBasis),
-                                     DeformationFEBasis, RealTuple<double,3>,
-                                     OrientationFEBasis, Rotation<double,3> > solver;
-#else
-    RiemannianTrustRegionSolver<FEBasis,TargetSpace> solver;
-#endif
-    solver.setup(*grid,
-                 &assembler,
-#ifdef MIXED_SPACE
-                 deformationFEBasis,
-                 orientationFEBasis,
-#endif
-                 x,
-#ifdef MIXED_SPACE
-                 deformationDirichletDofs,
-                 orientationDirichletDofs,
-#else
-                 dirichletDofs,
-#endif
-                 tolerance,
-                 maxTrustRegionSteps,
-                 initialTrustRegionRadius,
-                 multigridIterations,
-                 mgTolerance,
-                 mu, nu1, nu2,
-                 baseIterations,
-                 baseTolerance,
-                 instrumented);
-
-        solver.setScaling(parameterSet.get<FieldVector<double,6> >("trustRegionScaling"));
-
         ////////////////////////////////////////////////////////
         //   Set Dirichlet values
         ////////////////////////////////////////////////////////
@@ -484,85 +418,227 @@ int main (int argc, char *argv[]) try
         Python::Reference dirichletValuesPythonObject = C(homotopyParameter);
 
         // Extract object member functions as Dune functions
-        auto deformationDirichletValues = Python::make_function<FieldVector<double,3> >(dirichletValuesPythonObject.get("deformation"));
-        auto orientationDirichletValues = Python::make_function<FieldMatrix<double,3,3> >(dirichletValuesPythonObject.get("orientation"));
-
-        std::vector<FieldVector<double,3> > ddV;
-        std::vector<FieldMatrix<double,3,3> > dOV;
-
-#ifdef MIXED_SPACE
-        Functions::interpolate(deformationFEBasis, ddV, deformationDirichletValues, deformationDirichletDofs);
-        Functions::interpolate(orientationFEBasis, dOV, orientationDirichletValues, orientationDirichletDofs);
-
-        for (size_t j=0; j<x[_0].size(); j++)
-          if (deformationDirichletNodes[j][0])
-            x[_0][j] = ddV[j];
-
-        for (size_t j=0; j<x[_1].size(); j++)
-          if (orientationDirichletNodes[j][0])
-            x[_1][j].set(dOV[j]);
+        auto deformationDirichletValues = Python::make_function<FieldVector<double,3> >   (dirichletValuesPythonObject.get("deformation"));
+        auto orientationDirichletValues = Python::make_function<FieldMatrix<double,3,3> > (dirichletValuesPythonObject.get("orientation"));
+    
+        BlockVector<FieldVector<double,3> > ddV;
+        Dune::Functions::interpolate(deformationPowerBasis, ddV, deformationDirichletValues, deformationDirichletDofs);
+    
+        BlockVector<FieldMatrix<double,3,3> > dOV;
+        Dune::Functions::interpolate(orientationFEBasis, dOV, orientationDirichletValues, orientationDirichletDofs);
+    
+        for (int i = 0; i < compositeBasis.size({0}); i++) {
+          if (deformationDirichletDofs[i][0])
+            x[_0][i] = ddV[i];
+        }
+        for (int i = 0; i < compositeBasis.size({1}); i++)
+          if (orientationDirichletDofs[i][0])
+            x[_1][i].set(dOV[i]);
+
+        if (dim==dimworld) {
+            CosseratEnergyLocalStiffness<CompositeBasis, 3,adouble> localCosseratEnergy(materialParameters,
+                                                                                            &neumannBoundary,
+                                                                                            neumannFunction,
+                                                                                            volumeLoad);
+            MixedLocalGFEADOLCStiffness<CompositeBasis,
+                                RealTuple<double,3>,
+                                Rotation<double,3> > localGFEADOLCStiffness(&localCosseratEnergy);
+            MixedGFEAssembler<CompositeBasis,
+                      RealTuple<double,3>,
+                      Rotation<double,3> > mixedAssembler(compositeBasis, &localGFEADOLCStiffness);
+#if MIXED_SPACE
+            MixedRiemannianTrustRegionSolver<GridType,
+                                         CompositeBasis,
+                                         DeformationFEBasis, RealTuple<double,3>,
+                                         OrientationFEBasis, Rotation<double,3> > solver;
+            solver.setup(*grid,
+                     &mixedAssembler,
+                     deformationFEBasis,
+                     orientationFEBasis,
+                     x,
+                     deformationDirichletDofs,
+                     orientationDirichletDofs, tolerance,
+                     maxSolverSteps,
+                     initialTrustRegionRadius,
+                     multigridIterations,
+                     mgTolerance,
+                     mu, nu1, nu2,
+                     baseIterations,
+                     baseTolerance,
+                     instrumented);
+
+            solver.setScaling(parameterSet.get<FieldVector<double,6> >("trustRegionScaling"));
+
+            solver.setInitialIterate(x);
+            solver.solve();
+            x = solver.getSol();
 #else
-        Functions::interpolate(feBasis, ddV, deformationDirichletValues, dirichletDofs);
-        Functions::interpolate(feBasis, dOV, orientationDirichletValues, dirichletDofs);
-
-        for (size_t j=0; j<x.size(); j++)
-          if (dirichletNodes[j][0])
-          {
-            x[j].r = ddV[j];
-            x[j].q.set(dOV[j]);
-          }
+            //The MixedRiemannianTrustRegionSolver can treat the Displacement and Orientation Space as separate ones
+            //The RiemannianTrustRegionSolver can only treat the Displacement and Rotation together in a RigidBodyMotion
+            //Therefore, x and the dirichletDofs are converted to a RigidBodyMotion structure, as well as the Hessian and Gradient that are returned by the assembler
+            std::vector<TargetSpace> xTargetSpace(compositeBasis.size({0}));
+            BitSetVector<TargetSpace::TangentVector::dimension> dirichletDofsTargetSpace(compositeBasis.size({0}), false);
+            for (int i = 0; i < compositeBasis.size({0}); i++) {
+              for (int j = 0; j < 3; j ++) { // Displacement part
+                xTargetSpace[i].r[j] = x[_0][i][j];
+                dirichletDofsTargetSpace[i][j] = deformationDirichletDofs[i][j];
+              }
+              xTargetSpace[i].q = x[_1][i]; // Rotation part
+              for (int j = 3; j < TargetSpace::TangentVector::dimension; j ++)
+                dirichletDofsTargetSpace[i][j] = orientationDirichletDofs[i][j-3];
+            }
+
+            using GFEAssemblerWrapper = Dune::GFE::GeodesicFEAssemblerWrapper<CompositeBasis, DeformationFEBasis, TargetSpace, RealTuple<double, 3>, Rotation<double,3>>;
+            GFEAssemblerWrapper assembler(&mixedAssembler, deformationFEBasis);
+            RiemannianTrustRegionSolver<DeformationFEBasis, TargetSpace, GFEAssemblerWrapper> solver;
+            solver.setup(*grid,
+                     &assembler,
+                     xTargetSpace,
+                     dirichletDofsTargetSpace,
+                     tolerance,
+                     maxSolverSteps,
+                     initialTrustRegionRadius,
+                     multigridIterations,
+                     mgTolerance,
+                     mu, nu1, nu2,
+                     baseIterations,
+                     baseTolerance,
+                     instrumented);
+
+            solver.setScaling(parameterSet.get<FieldVector<double,6> >("trustRegionScaling"));
+            solver.setInitialIterate(xTargetSpace);
+            solver.solve();
+            xTargetSpace = solver.getSol();
+            for (int i = 0; i < xTargetSpace.size(); i++) {
+              x[_0][i] = xTargetSpace[i].r;
+              x[_1][i] = xTargetSpace[i].q;
+            }
 #endif
+        } else {
+#if MIXED_SPACE
+            DUNE_THROW(Exception, "Problems with dim != dimworld do not work for MIXED_SPACE = 1!");
+#else
+            std::shared_ptr<LocalGeodesicFEADOLCStiffness<DeformationFEBasis, TargetSpace>> localGFEADOLCStiffness;
+
+            NonplanarCosseratShellEnergy<DeformationFEBasis, 3, adouble> localCosseratEnergyPlanar(materialParameters,
+                                                                                                    nullptr,
+                                                                                                    &neumannBoundary,
+                                                                                                    neumannFunction,
+                                                                                                    volumeLoad);
+              localGFEADOLCStiffness = std::make_shared<LocalGeodesicFEADOLCStiffness<DeformationFEBasis, TargetSpace>>(&localCosseratEnergyPlanar);
+
+            GeodesicFEAssembler<DeformationFEBasis,TargetSpace> assembler(gridView, *localGFEADOLCStiffness);
+            //The MixedRiemannianTrustRegionSolver can treat the Displacement and Orientation Space as separate ones
+            //The RiemannianTrustRegionSolver can only treat the Displacement and Rotation together in a RigidBodyMotion
+            //Therefore, x and the dirichletDofs are converted to a RigidBodyMotion structure, as well as the Hessian and Gradient that are returned by the assembler
+            std::vector<TargetSpace> xTargetSpace(compositeBasis.size({0}));
+            BitSetVector<TargetSpace::TangentVector::dimension> dirichletDofsTargetSpace(compositeBasis.size({0}), false);
+            for (int i = 0; i < compositeBasis.size({0}); i++) {
+              for (int j = 0; j < 3; j ++) { // Displacement part
+                xTargetSpace[i].r[j] = x[_0][i][j];
+                dirichletDofsTargetSpace[i][j] = deformationDirichletDofs[i][j];
+              }
+              xTargetSpace[i].q = x[_1][i]; // Rotation part
+              for (int j = 3; j < TargetSpace::TangentVector::dimension; j ++)
+                dirichletDofsTargetSpace[i][j] = orientationDirichletDofs[i][j-3];
+            }
+            if (parameterSet.get<std::string>("solvertype", "trustRegion") == "trustRegion") {
+
+                RiemannianTrustRegionSolver<DeformationFEBasis, TargetSpace> solver;
+                solver.setup(*grid,
+                         &assembler,
+                         xTargetSpace,
+                         dirichletDofsTargetSpace,
+                         tolerance,
+                         maxSolverSteps,
+                         initialTrustRegionRadius,
+                         multigridIterations,
+                         mgTolerance,
+                         mu, nu1, nu2,
+                         baseIterations,
+                         baseTolerance,
+                         instrumented);
+
+                solver.setScaling(parameterSet.get<FieldVector<double,6> >("trustRegionScaling"));
+                solver.setInitialIterate(xTargetSpace);
+                solver.solve();
+                xTargetSpace = solver.getSol();
+            } else { //parameterSet.get<std::string>("solvertype") == "proximalNewton"
+#if DUNE_VERSION_LT(DUNE_COMMON, 2, 8)
+                DUNE_THROW(Exception, "Please install dune-solvers >= 2.8 to use the Proximal Newton Solver with Cholmod!");
+#else
+                RiemannianProximalNewtonSolver<DeformationFEBasis, TargetSpace> solver;
+                solver.setup(*grid,
+                             &assembler,
+                             xTargetSpace,
+                             dirichletDofsTargetSpace,
+                             tolerance,
+                             maxSolverSteps,
+                             initialRegularization,
+                             instrumented);
+                solver.setInitialIterate(xTargetSpace);
+                solver.solve();
+                xTargetSpace = solver.getSol();
+#endif
+            }
 
-        // /////////////////////////////////////////////////////
-        //   Solve!
-        // /////////////////////////////////////////////////////
-
-        solver.setInitialIterate(x);
-        solver.solve();
-
-        x = solver.getSol();
-
+            for (int i = 0; i < xTargetSpace.size(); i++) {
+              x[_0][i] = xTargetSpace[i].r;
+              x[_1][i] = xTargetSpace[i].q;
+            }
+#endif
+        }
         // Output result of each homotopy step
         std::stringstream iAsAscii;
         iAsAscii << i+1;
-#ifdef MIXED_SPACE
+        if (dim == dimworld) {
         CosseratVTKWriter<GridType>::writeMixed<DeformationFEBasis,OrientationFEBasis>(deformationFEBasis,x[_0],
                                                                                        orientationFEBasis,x[_1],
                                                                                        resultPath + "mixed-cosserat_homotopy_" + iAsAscii.str());
-#else
-        CosseratVTKWriter<GridType>::write<FEBasis>(feBasis,x, resultPath + "cosserat_homotopy_" + iAsAscii.str());
+        } else {
+#if MIXED_SPACE
+            for (int i = 0; i < displacement.size(); i++) {
+               for (int j = 0; j  < 3; j++) {
+                displacement[i][j] = x[_0][i][j];
+              }
+              displacement[i] -= identity[i];
+            }
+            auto displacementFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3>>(deformationPowerBasis, displacement);
+    
+            //  We need to subsample, because VTK cannot natively display real second-order functions
+            SubsamplingVTKWriter<GridView> vtkWriter(gridView, Dune::refinementLevels(displacementOrder-1));
+            vtkWriter.addVertexData(displacementFunction, VTK::FieldInfo("displacement", VTK::FieldInfo::Type::scalar, 3));
+            vtkWriter.write(resultPath + "cosserat_homotopy_" + std::to_string(i+1));
+#else 
+        CosseratVTKWriter<GridType>::write<DeformationFEBasis>(deformationFEBasis, x, resultPath + "cosserat_homotopy_" + std::to_string(i+1));
 #endif
-
+        }
     }
 
     // //////////////////////////////
     //   Output result
     // //////////////////////////////
 
-#ifndef MIXED_SPACE
+#if !MIXED_SPACE
     // Write the corresponding coefficient vector: verbatim in binary, to be completely lossless
     // This data may be used by other applications measuring the discretization error
-    BlockVector<TargetSpace::CoordinateType> xEmbedded(x.size());
-    for (size_t i=0; i<x.size(); i++)
-      xEmbedded[i] = x[i].globalCoordinates();
+    BlockVector<TargetSpace::CoordinateType> xEmbedded(compositeBasis.size({0}));
+    for (size_t i=0; i<compositeBasis.size({0}); i++)
+        for (size_t j=0; j<TargetSpace::TangentVector::dimension; j++)
+            xEmbedded[i][j] = j < 3 ? x[_0][i][j] : x[_1][i].globalCoordinates()[j-3];
 
     std::ofstream outFile("cosserat-continuum-result-" + std::to_string(numLevels) + ".data", std::ios_base::binary);
     MatrixVector::Generic::writeBinary(outFile, xEmbedded);
     outFile.close();
 #endif
 
+    if (parameterSet.get<bool>("computeAverageNeumannDeflection", false) and parameterSet.hasKey("neumannValues")) {
     // finally: compute the average deformation of the Neumann boundary
     // That is what we need for the locking tests
     FieldVector<double,3> averageDef(0);
-#ifdef MIXED_SPACE
     for (size_t i=0; i<x[_0].size(); i++)
         if (neumannNodes[i][0])
             averageDef += x[_0][i].globalCoordinates();
-#else
-    for (size_t i=0; i<x.size(); i++)
-        if (neumannNodes[i][0])
-            averageDef += x[i].r;
-#endif
     averageDef /= neumannNodes.count();
 
     if (mpiHelper.rank()==0 and parameterSet.hasKey("neumannValues"))
@@ -570,6 +646,7 @@ int main (int argc, char *argv[]) try
       std::cout << "Neumann values = " << parameterSet.get<FieldVector<double, 3> >("neumannValues") << "  "
                 << ",  average deflection: " << averageDef << std::endl;
     }
+    }
 
 } catch (Exception& e)
 {
diff --git a/src/film-on-substrate.cc b/src/film-on-substrate.cc
index 5f5134fe7d641f802b120830cb58d9892fd5f731..e52201554d6630a4c50dde4f5283c60bd5d9d592 100644
--- a/src/film-on-substrate.cc
+++ b/src/film-on-substrate.cc
@@ -554,7 +554,7 @@ int main (int argc, char *argv[]) try
     //   Create the chosen solver and solve!
     ///////////////////////////////////////////////////
 
-    if (parameterSet.get<std::string>("solvertype") == "multigrid") {
+    if (parameterSet.get<std::string>("solvertype", "trustRegion") == "trustRegion") {
 #if MIXED_SPACE
       MixedRiemannianTrustRegionSolver<GridType, CompositeBasis, DeformationFEBasis, RealTuple<double,dim>, OrientationFEBasis, Rotation<double,dim>> solver;
       solver.setup(*grid,
@@ -603,7 +603,7 @@ int main (int argc, char *argv[]) try
         x[_1][i] = xRBM[i].q;
       }
 #endif
-    } else { //parameterSet.get<std::string>("solvertype") == "cholmod"
+    } else { //parameterSet.get<std::string>("solvertype") == "proximalNewton"
 
 #if MIXED_SPACE
     DUNE_THROW(Exception, "Error: There is no MixedRiemannianProximalNewtonSolver!");