diff --git a/dune/gfe/cosseratvtkwriter.hh b/dune/gfe/cosseratvtkwriter.hh
index 4fe9fffe1b0d05f7b1cf2b5f2e0290b86f747a0a..69eb2dfbac78c7a5f3d76d0be9fbcb85de243b0c 100644
--- a/dune/gfe/cosseratvtkwriter.hh
+++ b/dune/gfe/cosseratvtkwriter.hh
@@ -11,6 +11,7 @@
 #include <dune/functions/functionspacebases/lagrangebasis.hh>
 #include <dune/functions/functionspacebases/interpolate.hh>
 #include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
+#include <dune/functions/gridfunctions/composedgridfunction.hh>
 
 #include <dune/vtk/vtkwriter.hh>
 #include <dune/vtk/datacollectors/lagrangedatacollector.hh>
@@ -395,11 +396,10 @@ public:
    * \param directorBasis The basis that will be used to represent director fields
    * \param order The polynomial order that the data will have in the VTK file
    */
-  template <typename DisplacementFunction, typename DirectorBasis>
+  template <typename DisplacementFunction, typename OrientationFunction>
   static void write(const GridView& gridView,
                     const DisplacementFunction& displacement,
-                    const DirectorBasis& directorBasis,
-                    const std::vector<Rotation<double,3> >& orientationConfiguration,
+                    const OrientationFunction& orientation,
                     int order,
                     const std::string& filename)
   {
@@ -417,27 +417,26 @@ public:
     vtkWriter.addPointData(displacement, Dune::VTK::FieldInfo("displacement", Dune::VTK::FieldInfo::Type::vector, 3));
 
     // Attach the director fields
-    BlockVector<FieldVector<double,3> > director0(orientationConfiguration.size());
-    BlockVector<FieldVector<double,3> > director1(orientationConfiguration.size());
-    BlockVector<FieldVector<double,3> > director2(orientationConfiguration.size());
-
-    for (size_t i=0; i<orientationConfiguration.size(); i++)
-    {
-      FieldMatrix<double,3,3> rotationMatrix;
-      orientationConfiguration[i].matrix(rotationMatrix);
-
-      // Extract the directors, i.e., the columns of the matrix
-      for (size_t j=0; j<3; j++)
-      {
-        director0[i][j] = rotationMatrix[j][0];
-        director1[i][j] = rotationMatrix[j][1];
-        director2[i][j] = rotationMatrix[j][2];
-      }
-    }
-
-    auto director0Function = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(directorBasis, director0);
-    auto director1Function = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(directorBasis, director1);
-    auto director2Function = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(directorBasis, director2);
+    // This lambda takes a unit quaternion and extracts one column
+    // of the corresponding rotation matrix
+    auto directorExtractor = [](FieldVector<double,4> q,int columnNumber) -> FieldVector<double,3>
+                             {
+                               FieldMatrix<double,3,3> matrix;
+                               Rotation<double,3>(q).matrix(matrix);
+                               FieldVector<double,3> column;
+                               for (size_t i=0; i<3; ++i)
+                                 column[i] = matrix[i][columnNumber];
+                               return column;
+                             };
+
+    auto director0Function = Functions::makeComposedGridFunction(std::bind(directorExtractor,std::placeholders::_1,0),
+                                                                 orientation);
+
+    auto director1Function = Functions::makeComposedGridFunction(std::bind(directorExtractor,std::placeholders::_1,1),
+                                                                 orientation);
+
+    auto director2Function = Functions::makeComposedGridFunction(std::bind(directorExtractor,std::placeholders::_1,2),
+                                                                 orientation);
 
     vtkWriter.addPointData(director0Function, Dune::VTK::FieldInfo("director0", Dune::VTK::FieldInfo::Type::vector, 3));
     vtkWriter.addPointData(director1Function, Dune::VTK::FieldInfo("director1", Dune::VTK::FieldInfo::Type::vector, 3));
diff --git a/src/cosserat-continuum.cc b/src/cosserat-continuum.cc
index 856287f544a5c79dc634d4493b0345b870eb99c3..f656ae22e382ada3b830110d66e850be3571be60 100644
--- a/src/cosserat-continuum.cc
+++ b/src/cosserat-continuum.cc
@@ -287,13 +287,6 @@ int main (int argc, char *argv[]) try
       lagrange<displacementOrder>()
       ));
 
-  // Vector-valued basis to represent directors
-  auto directorBasis = makeBasis(
-    gridView,
-    power<3>(
-      lagrange<rotationOrder>()
-      ));
-
   // Matrix-valued basis for treating the microrotation as a matrix field
   auto orientationMatrixBasis = makeBasis(
     gridView,
@@ -483,11 +476,19 @@ int main (int argc, char *argv[]) try
 
   auto displacementFunction = Dune::Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(deformationPowerBasis, displacement);
 
+#ifdef PROJECTED_INTERPOLATION
+  using RotationInterpolationRule = GFE::LocalProjectedFEFunction<dim, double, OrientationFEBasis::LocalView::Tree::FiniteElement, Rotation<double,3> >;
+#else
+  using RotationInterpolationRule = LocalGeodesicFEFunction<dim, double, OrientationFEBasis::LocalView::Tree::FiniteElement, Rotation<double,3> >;
+#endif
+
+  GFE::EmbeddedGlobalGFEFunction<OrientationFEBasis, RotationInterpolationRule,Rotation<double,3> > orientationFunction(orientationFEBasis,
+                                                                                                                        x[_1]);
+
   if (dim == dimworld) {
     CosseratVTKWriter<GridView>::write(gridView,
                                        displacementFunction,
-                                       directorBasis,
-                                       x[_1],
+                                       orientationFunction,
                                        std::max(LFE_ORDER, GFE_ORDER),
                                        resultPath + "cosserat_homotopy_0_l" + std::to_string(numLevels));
   } else if (dim == 2 && dimworld == 3) {
@@ -753,8 +754,7 @@ int main (int argc, char *argv[]) try
     if (dim == dimworld) {
       CosseratVTKWriter<GridView>::write(gridView,
                                          displacementFunction,
-                                         directorBasis,
-                                         x[_1],
+                                         orientationFunction,
                                          std::max(LFE_ORDER, GFE_ORDER),
                                          resultPath + "cosserat_homotopy_" + std::to_string(i+1) + "_l" + std::to_string(numLevels));
     } else if (dim == 2 && dimworld == 3) {
diff --git a/src/cosserat-rod.cc b/src/cosserat-rod.cc
index 6dcd7930c8c9fd86238e1e16b133cd20cde15fc3..c7f937da5bd087ab9c0aa3363a8f94298fb60778 100644
--- a/src/cosserat-rod.cc
+++ b/src/cosserat-rod.cc
@@ -31,6 +31,7 @@
 #include <dune/gfe/assemblers/geodesicfeassembler.hh>
 #include <dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh>
 #include <dune/gfe/cosseratvtkwriter.hh>
+#include <dune/gfe/embeddedglobalgfefunction.hh>
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/localprojectedfefunction.hh>
 #include <dune/gfe/riemanniantrsolver.hh>
@@ -288,13 +289,6 @@ int main (int argc, char *argv[]) try
     power<3>(lagrange<order>())
     );
 
-  // Vector-valued basis to represent directors
-  auto directorBasis = makeBasis(
-    gridView,
-    power<3>(
-      lagrange<order>()
-      ));
-
   // Compute the displacement from the deformation, because that's more easily visualized
   // in ParaView
   BlockVector<FieldVector<double,3> > displacement(worldBasis.size());
@@ -319,10 +313,14 @@ int main (int argc, char *argv[]) try
   for (size_t i=0; i<x.size(); ++i)
     orientationConfiguration[i] = x[i][_1];
 
+  using RotationInterpolationRule  = LocalGeodesicFEFunction<1, double, ScalarBasis::LocalView::Tree::FiniteElement, Rotation<double,3> >;
+
+  GFE::EmbeddedGlobalGFEFunction<ScalarBasis, RotationInterpolationRule,Rotation<double,3> > orientationFunction(scalarBasis,
+                                                                                                                 orientationConfiguration);
+
   CosseratVTKWriter<GridView>::write(gridView,
                                      displacementFunction,
-                                     directorBasis,
-                                     orientationConfiguration,
+                                     orientationFunction,
                                      order,
                                      resultPath + "cosserat-rod-result");
 
diff --git a/test/nonplanarcosseratenergytest.cc b/test/nonplanarcosseratenergytest.cc
index 350a544e0d59661814c5043a4b4435e7fd44a0e5..e44b1c24c8880c535065f4c1658b24b42c2b70d0 100644
--- a/test/nonplanarcosseratenergytest.cc
+++ b/test/nonplanarcosseratenergytest.cc
@@ -81,11 +81,11 @@ double calculateEnergy(const FlatGridView& flatGridView,
   // Turn matrix-valued function into quaternion-valued function
   auto orientationQuaternionFunction
     = [&orientationFunction](FieldVector<double,3> x) -> FieldVector<double,4>
-                                       {
-                                         Rotation<double,3> rotation;
-                                         rotation.set(orientationFunction(x));
-                                         return rotation;
-                                       };
+      {
+        Rotation<double,3> rotation;
+        rotation.set(orientationFunction(x));
+        return rotation;
+      };
 
   BlockVector<FieldVector<double,4> > orientationAsVector(flatFEBasis.size());
   Functions::interpolate(curvedGridQuaternionBasis, orientationAsVector, orientationQuaternionFunction);
@@ -96,17 +96,15 @@ double calculateEnergy(const FlatGridView& flatGridView,
   //  Write the configuration to a file (just for debugging)
   /////////////////////////////////////////////////////////////////////////
 
-  auto directorBasis = makeBasis(
-    flatGridView,
-    power<3>(
-      lagrange<2>()
-      ));
+  // The orientation function needs to become a GridViewFunction,
+  // otherwise the current CosseratVTKWriter will not accept it.
+  auto orientationQuaternionGridViewFunction = Functions::makeAnalyticGridViewFunction(orientationQuaternionFunction, flatGridView);
+
 
   // TODO: Write the curved grid, not the flat one
   CosseratVTKWriter<FlatGridView>::write(flatGridView,
                                          curvedGridGeometry,
-                                         directorBasis,
-                                         configuration[_1],
+                                         orientationQuaternionGridViewFunction,
                                          2, // VTK output element order
                                          "nonplanarcosseratenergytest-result.vtu");