diff --git a/src/rod3d.cc b/src/rod3d.cc
index 010167f53dcccaffa6f48163b6e2300490ae3581..db741d432d39c721a450273cd47283b566b66c25 100644
--- a/src/rod3d.cc
+++ b/src/rod3d.cc
@@ -5,6 +5,8 @@
 #include <adolc/drivers/drivers.h>
 #include <dune/fufem/utilities/adolcnamespaceinjections.hh>
 
+#include <optional>
+
 #include <dune/common/bitsetvector.hh>
 #include <dune/common/parametertree.hh>
 #include <dune/common/parametertreeparser.hh>
@@ -13,11 +15,20 @@
 
 #include <dune/istl/io.hh>
 
+#include <dune/functions/functionspacebases/interpolate.hh>
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+#include <dune/functions/functionspacebases/powerbasis.hh>
+#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
 
 #include <dune/solvers/solvers/iterativesolver.hh>
 #include <dune/solvers/norms/energynorm.hh>
 
+#if HAVE_DUNE_VTK
+#include <dune/vtk/vtkwriter.hh>
+#else
 #include <dune/gfe/cosseratvtkwriter.hh>
+#endif
+
 #include <dune/gfe/geodesicfeassembler.hh>
 #include <dune/gfe/localgeodesicfeadolcstiffness.hh>
 #include <dune/gfe/rigidbodymotion.hh>
@@ -185,7 +196,54 @@ int main (int argc, char *argv[]) try
     // //////////////////////////////
     //   Output result
     // //////////////////////////////
+#if HAVE_DUNE_VTK
+    VtkUnstructuredGridWriter<GridView> vtkWriter(gridView, Vtk::ASCII);
+
+    // Make basis for R^3-valued data
+    using namespace Functions::BasisFactory;
+
+    auto worldBasis = makeBasis(
+      gridView,
+      power<3>(lagrange<1>())
+    );
+
+    // The rod displacement field
+    BlockVector<FieldVector<double,3> > displacement(worldBasis.size());
+    for (std::size_t i=0; i<x.size(); i++)
+      displacement[i] = x[i].r;
+
+    std::vector<double> xEmbedding;
+    Functions::interpolate(feBasis, xEmbedding, [](FieldVector<double,1> x){ return x; });
+
+    BlockVector<FieldVector<double,3> > gridEmbedding(xEmbedding.size());
+    for (std::size_t i=0; i<gridEmbedding.size(); i++)
+      gridEmbedding[i] = {xEmbedding[i], 0, 0};
+
+    displacement -= gridEmbedding;
+
+    auto displacementFunction = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(worldBasis, displacement);
+    vtkWriter.addPointData(displacementFunction, "displacement", 3);
+
+    // The three director fields
+    using FunctionType = decltype(displacementFunction);
+    std::array<std::optional<FunctionType>, 3> directorFunction;
+
+    for (int i=0; i<3; i++)
+    {
+      BlockVector<FieldVector<double, 3> > director(worldBasis.size());
+      for (std::size_t j=0; j<x.size(); j++)
+        director[j] = x[j].q.director(i);
+
+      directorFunction[i] = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,3> >(worldBasis, std::move(director));
+      vtkWriter.addPointData(*directorFunction[i], "director " + std::to_string(i), 3);
+    }
+
+    vtkWriter.write(resultPath + "rod3d-result");
+#else
+    std::cout << "Falling back to legacy file writing.  Get dune-vtk for better results" << std::endl;
+    // Fall-back solution for users without dune-vtk
     CosseratVTKWriter<GridType>::write<FEBasis>(feBasis,x, resultPath + "rod3d-result");
+#endif
 
 } catch (Exception& e)
 {