From d1234317cb82f354722c83344035f0e2a95fa534 Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Tue, 28 Aug 2018 15:04:43 +0200
Subject: [PATCH] added legacy vtkfunctions

---
 dune/vtk/defaultvtkfunction.hh              |  63 +++++
 dune/vtk/legacyvtkfunction.hh               |  45 ++++
 dune/vtk/vtkfunction.hh                     | 268 ++------------------
 dune/vtk/vtklocalfunction.hh                |  59 +++++
 dune/vtk/vtklocalfunctioninterface.hh       |  26 ++
 dune/vtk/writers/vtkwriterinterface.hh      |  33 +--
 dune/vtk/writers/vtkwriterinterface.impl.hh |   4 +-
 src/CMakeLists.txt                          |   4 +
 src/legacyvtkwriter.cc                      |  77 ++++++
 9 files changed, 317 insertions(+), 262 deletions(-)
 create mode 100644 dune/vtk/defaultvtkfunction.hh
 create mode 100644 dune/vtk/legacyvtkfunction.hh
 create mode 100644 dune/vtk/vtklocalfunction.hh
 create mode 100644 dune/vtk/vtklocalfunctioninterface.hh
 create mode 100644 src/legacyvtkwriter.cc

diff --git a/dune/vtk/defaultvtkfunction.hh b/dune/vtk/defaultvtkfunction.hh
new file mode 100644
index 0000000..078909b
--- /dev/null
+++ b/dune/vtk/defaultvtkfunction.hh
@@ -0,0 +1,63 @@
+#pragma once
+
+#include "vtklocalfunctioninterface.hh"
+
+namespace Dune { namespace experimental
+{
+  /// Type erasure for dune-functions LocalFunction interface
+  template <class GridView, class LocalFunction>
+  class LocalFunctionWrapper final
+      : public VtkLocalFunctionInterface<GridView>
+  {
+    using Self = LocalFunctionWrapper;
+    using Interface = VtkLocalFunctionInterface<GridView>;
+    using Entity = typename Interface::Entity;
+    using LocalCoordinate = typename Interface::LocalCoordinate;
+
+    template <class F, class D>
+    using Range = std::decay_t<decltype(std::declval<F>()(std::declval<D>()))>;
+
+    template <class F, class D>
+    using VectorValued = decltype(std::declval<Range<F,D>>()[0u]);
+
+  public:
+    template <class LocalFct, disableCopyMove<Self, LocalFct> = 0>
+    LocalFunctionWrapper (LocalFct&& localFct)
+      : localFct_(std::forward<LocalFct>(localFct))
+    {}
+
+    virtual void bind (Entity const& entity) override
+    {
+      localFct_.bind(entity);
+    }
+
+    virtual void unbind () override
+    {
+      localFct_.unbind();
+    }
+
+    virtual double evaluate (int comp, LocalCoordinate const& xi) const override
+    {
+      return evaluateImpl(comp, xi, Std::is_detected<VectorValued,LocalFunction,LocalCoordinate>{});
+    }
+
+  private:
+    // Evaluate a component of a vector valued data
+    double evaluateImpl (int comp, LocalCoordinate const& xi, std::true_type) const
+    {
+      auto y = localFct_(xi);
+      return comp < y.size() ? y[comp] : 0.0;
+    }
+
+    // Return the scalar values
+    double evaluateImpl (int comp, LocalCoordinate const& xi, std::false_type) const
+    {
+      assert(comp == 0);
+      return localFct_(xi);
+    }
+
+  private:
+    LocalFunction localFct_;
+  };
+
+}} // end namespace Dune::experimental
diff --git a/dune/vtk/legacyvtkfunction.hh b/dune/vtk/legacyvtkfunction.hh
new file mode 100644
index 0000000..2d3f797
--- /dev/null
+++ b/dune/vtk/legacyvtkfunction.hh
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <memory>
+
+#include <dune/grid/io/file/vtk/function.hh>
+
+#include "vtklocalfunctioninterface.hh"
+
+namespace Dune { namespace experimental
+{
+  /// Type erasure for Legacy VTKFunction
+  template <class GridView>
+  class VTKLocalFunctionWrapper final
+      : public VtkLocalFunctionInterface<GridView>
+  {
+    using Interface = VtkLocalFunctionInterface<GridView>;
+    using Entity = typename Interface::Entity;
+    using LocalCoordinate = typename Interface::LocalCoordinate;
+
+  public:
+    VTKLocalFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
+      : fct_(fct)
+    {}
+
+    virtual void bind (Entity const& entity) override
+    {
+      entity_ = &entity;
+    }
+
+    virtual void unbind () override
+    {
+      entity_ = nullptr;
+    }
+
+    virtual double evaluate (int comp, LocalCoordinate const& xi) const override
+    {
+      return fct_->evaluate(comp, *entity_, xi);
+    }
+
+  private:
+    std::shared_ptr<VTKFunction<GridView> const> fct_;
+    Entity const* entity_;
+  };
+
+}} // end namespace Dune::experimental
diff --git a/dune/vtk/vtkfunction.hh b/dune/vtk/vtkfunction.hh
index 1e71acb..08ea87c 100644
--- a/dune/vtk/vtkfunction.hh
+++ b/dune/vtk/vtkfunction.hh
@@ -4,227 +4,11 @@
 
 #include <dune/common/std/type_traits.hh>
 #include <dune/functions/common/signature.hh>
-#include <dune/grid/io/file/vtk/function.hh>
+
+#include "vtklocalfunction.hh"
 
 namespace Dune { namespace experimental
 {
-  /// An abstract base class for LocalFunctions
-  template <class GridView>
-  class VtkLocalFunctionInterface
-  {
-  public:
-    using Entity = typename GridView::template Codim<0>::Entity;
-    using LocalCoordinate = typename Entity::Geometry::LocalCoordinate;
-
-    /// Bind the function to the grid entity
-    virtual void bind (Entity const& entity) = 0;
-
-    /// Unbind from the currently bound entity
-    virtual void unbind () = 0;
-
-    /// Evaluate single component comp in the entity at local coordinates xi
-    virtual double evaluate (int comp, LocalCoordinate const& xi) const = 0;
-
-    /// Virtual destructor
-    virtual ~VtkLocalFunctionInterface () = default;
-  };
-
-
-  /// Type erasure for dune-functions LocalFunction interface
-  template <class GridView, class LocalFunction>
-  class LocalFunctionWrapper
-      : public VtkLocalFunctionInterface<GridView>
-  {
-    using Self = LocalFunctionWrapper;
-    using Interface = VtkLocalFunctionInterface<GridView>;
-    using Entity = typename Interface::Entity;
-    using LocalCoordinate = typename Interface::LocalCoordinate;
-
-    template <class F, class D>
-    using Range = std::decay_t<decltype(std::declval<F>()(std::declval<D>()))>;
-
-    template <class F, class D>
-    using VectorValued = decltype(std::declval<Range<F,D>>()[0u]);
-
-  public:
-    template <class LocalFct, disableCopyMove<Self, LocalFct> = 0>
-    LocalFunctionWrapper (LocalFct&& localFct)
-      : localFct_(std::forward<LocalFct>(localFct))
-    {}
-
-    virtual void bind (Entity const& entity) override
-    {
-      localFct_.bind(entity);
-    }
-
-    virtual void unbind () override
-    {
-      localFct_.unbind();
-    }
-
-    virtual double evaluate (int comp, LocalCoordinate const& xi) const override
-    {
-      return evaluateImpl(comp, xi, Std::is_detected<VectorValued,LocalFunction,LocalCoordinate>{});
-    }
-
-  private:
-    // Evaluate a component of a vector valued data
-    double evaluateImpl (int comp, LocalCoordinate const& xi, std::true_type) const
-    {
-      auto y = localFct_(xi);
-      return comp < y.size() ? y[comp] : 0.0;
-    }
-
-    // Return the scalar values
-    double evaluateImpl (int comp, LocalCoordinate const& xi, std::false_type) const
-    {
-      assert(comp == 0);
-      return localFct_(xi);
-    }
-
-  private:
-    LocalFunction localFct_;
-  };
-
-
-  /// Type erasure for Legacy VTKFunction
-  template <class GridView>
-  class VTKLocalFunctionWrapper
-      : public VtkLocalFunctionInterface<GridView>
-  {
-    using Interface = VtkLocalFunctionInterface<GridView>;
-    using Entity = typename Interface::Entity;
-    using LocalCoordinate = typename Interface::LocalCoordinate;
-
-  public:
-    VTKLocalFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
-      : fct_(fct)
-    {}
-
-    virtual void bind (Entity const& entity) override
-    {
-      entity_ = &entity;
-    }
-
-    virtual void unbind () override
-    {
-      entity_ = nullptr;
-    }
-
-    virtual double evaluate (int comp, LocalCoordinate const& xi) const override
-    {
-      return fct_->evaluate(comp, *entity_, xi);
-    }
-
-  private:
-    std::shared_ptr<VTKFunction<GridView> const> fct_;
-    Entity const* entity_;
-  };
-
-
-  template <class GridView>
-  class VtkLocalFunction
-  {
-    using Self = VtkLocalFunction;
-    using Entity = typename GridView::template Codim<0>::Entity;
-    using LocalCoordinate = typename Entity::Geometry::LocalCoordinate;
-
-    template <class LF, class E>
-    using HasBind = decltype(std::declval<LF>().bind(std::declval<E>()));
-
-  public:
-    // Store wrapper around dune-function LocalFunction
-    template <class LocalFct, disableCopyMove<Self, LocalFct> = 0,
-      std::enable_if_t<Std::is_detected<HasBind, LocalFct, Entity>::value,int> = 0>
-    VtkLocalFunction (LocalFct&& lf)
-      : localFct_(std::make_unique<LocalFunctionWrapper<GridView, std::decay_t<LocalFct>>>(std::forward<LocalFct>(lf)))
-    {}
-
-    // store wrapper around legacy VTKFunction
-    VtkLocalFunction (std::shared_ptr<VTKFunction<GridView> const> const& lf)
-      : localFct_(std::make_unique<VTKLocalFunctionWrapper<GridView>>(lf))
-    {}
-
-    VtkLocalFunction () = default;
-
-    /// Bind the function to the grid entity
-    void bind (Entity const& entity)
-    {
-      localFct_->bind(entity);
-    }
-
-    /// Unbind from the currently bound entity
-    void unbind ()
-    {
-      localFct_->unbind();
-    }
-
-    /// Evaluate the `comp` component of the Range value at local coordinate `xi`
-    double evaluate (int comp, LocalCoordinate const& xi) const
-    {
-      return localFct_->evaluate(comp, xi);
-    }
-
-  private:
-    std::shared_ptr<VtkLocalFunctionInterface<GridView>> localFct_;
-  };
-
-  // ---------------------------------------------------------------------------
-
-  /// An abstract base class for GlobalFunctions
-  template <class GridView>
-  class VtkFunctionInterface
-  {
-  public:
-    /// Create a local function
-    virtual VtkLocalFunction<GridView> makeLocalFunction () const = 0;
-
-    /// Virtual destructor
-    virtual ~VtkFunctionInterface () = default;
-  };
-
-
-  template <class GridView, class GridViewFunction>
-  class GridViewFunctionWrapper
-      : public VtkFunctionInterface<GridView>
-  {
-    using Self = GridViewFunctionWrapper;
-
-  public:
-    template <class GVFct, disableCopyMove<Self, GVFct> = 0>
-    GridViewFunctionWrapper (GVFct&& gvFct)
-      : gvFct_(std::forward<GVFct>(gvFct))
-    {}
-
-    virtual VtkLocalFunction<GridView> makeLocalFunction () const override
-    {
-      return VtkLocalFunction<GridView>{localFunction(gvFct_)};
-    }
-
-  private:
-    GridViewFunction gvFct_;
-  };
-
-
-  template <class GridView>
-  class VTKFunctionWrapper
-      : public VtkFunctionInterface<GridView>
-  {
-  public:
-    VTKFunctionWrapper (std::shared_ptr<VTKFunction<GridView> const> const& fct)
-      : fct_(fct)
-    {}
-
-    virtual VtkLocalFunction<GridView> makeLocalFunction () const override
-    {
-      return VtkLocalFunction<GridView>{fct_};
-    }
-
-  private:
-    std::shared_ptr<VTKFunction<GridView> const> fct_;
-  };
-
-
   template <class GridView>
   class VtkFunction
   {
@@ -232,37 +16,39 @@ namespace Dune { namespace experimental
     using HasLocalFunction = decltype(localFunction(std::declval<F>()));
 
     template <class F>
-    using Signature = typename std::decay_t<F>::Signature;
+    using Domain = typename std::decay_t<F>::EntitySet::GlobalCoordinate;
+
+    template <class F>
+    using Range = std::decay_t<decltype(std::declval<F>()(std::declval<Domain<F>>()))>;
 
   public:
-    template <class F,
-      std::enable_if_t<Std::is_detected<HasLocalFunction,F>::value, int> = 0,
-      class Range = typename Functions::SignatureTraits<Signature<F>>::Range>
-    VtkFunction (F&& f, std::string name, int ncomps = 1,
-                 Vtk::DataTypes type = Vtk::Map::type<Range>)
-      : fct_(std::make_unique<GridViewFunctionWrapper<GridView,std::decay_t<F>>>(std::forward<F>(f)))
-      , name_(std::move(name))
-      , ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
-      , type_(type)
+    /// Constructor VtkFunction from legacy VTKFunction
+    VtkFunction (std::shared_ptr<VTKFunction<GridView> const> const& fct)
+      : localFct_(fct)
+      , name_(fct->name())
+      , ncomps_(fct->ncomps())
+      , type_(Vtk::FLOAT64)
     {}
 
+    /// Construct VtkFunction from dune-functions GridFunction with Signature
     template <class F,
       std::enable_if_t<Std::is_detected<HasLocalFunction,F>::value, int> = 0,
-      std::enable_if_t<not Std::is_detected<Signature,F>::value,int> = 0>
-    VtkFunction (F&& f, std::string name, int ncomps = 1,
-                 Vtk::DataTypes type = Vtk::FLOAT32)
-      : fct_(std::make_unique<GridViewFunctionWrapper<GridView,std::decay_t<F>>>(std::forward<F>(f)))
+      std::enable_if_t<Std::is_detected<Range,F>::value,int> = 0>
+    VtkFunction (F&& fct, std::string name, int ncomps = 1, Vtk::DataTypes type = Vtk::Map::type<Range<F>>)
+      : localFct_(localFunction(std::forward<F>(fct)))
       , name_(std::move(name))
-      , ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
+      , ncomps_(ncomps)
       , type_(type)
     {}
 
-    VtkFunction (std::shared_ptr<VTKFunction<GridView> const> const& fct,
-                 std::string name, int ncomps = 1,
-                 Vtk::DataTypes type = Vtk::FLOAT32)
-      : fct_(std::make_unique<VTKFunctionWrapper<GridView>>(fct))
+    /// Construct VtkFunction from dune-functions GridFunction without Signature
+    template <class F,
+      std::enable_if_t<Std::is_detected<HasLocalFunction,F>::value, int> = 0,
+      std::enable_if_t<not Std::is_detected<Range,F>::value,int> = 0>
+    VtkFunction (F const& fct, std::string name, int ncomps = 1, Vtk::DataTypes type = Vtk::FLOAT32)
+      : localFct_(localFunction(std::forward<F>(fct)))
       , name_(std::move(name))
-      , ncomps_(ncomps > 3 ? 9 : ncomps > 1 ? 3 : 1) // tensor, vector, or scalar
+      , ncomps_(ncomps)
       , type_(type)
     {}
 
@@ -271,7 +57,7 @@ namespace Dune { namespace experimental
     /// Create a LocalFunction
     friend VtkLocalFunction<GridView> localFunction (VtkFunction const& self)
     {
-      return self.fct_->makeLocalFunction();
+      return self.localFct_;
     }
 
     /// Return a name associated with the function
@@ -293,10 +79,10 @@ namespace Dune { namespace experimental
     }
 
   private:
-    std::shared_ptr<VtkFunctionInterface<GridView>> fct_;
+    VtkLocalFunction<GridView> localFct_;
     std::string name_;
     int ncomps_ = 1;
-    Vtk::DataTypes type_;
+    Vtk::DataTypes type_ = Vtk::FLOAT32;
   };
 
 }} // end namespace Dune::experimental
diff --git a/dune/vtk/vtklocalfunction.hh b/dune/vtk/vtklocalfunction.hh
new file mode 100644
index 0000000..9b5dc85
--- /dev/null
+++ b/dune/vtk/vtklocalfunction.hh
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <memory>
+#include <type_traits>
+
+#include <dune/common/std/type_traits.hh>
+
+#include "vtklocalfunctioninterface.hh"
+#include "legacyvtkfunction.hh"
+#include "defaultvtkfunction.hh"
+
+namespace Dune { namespace experimental
+{
+  template <class GridView>
+  class VtkLocalFunction
+  {
+    using Self = VtkLocalFunction;
+    using Entity = typename GridView::template Codim<0>::Entity;
+    using LocalCoordinate = typename Entity::Geometry::LocalCoordinate;
+
+    template <class LF, class E>
+    using HasBind = decltype(std::declval<LF>().bind(std::declval<E>()));
+
+  public:
+    template <class LF, disableCopyMove<Self, LF> = 0,
+      std::enable_if_t<Std::is_detected<HasBind,LF,Entity>::value, int> = 0>
+    VtkLocalFunction (LF&& lf)
+      : localFct_(std::make_shared<LocalFunctionWrapper<GridView,LF>>(std::forward<LF>(lf)))
+    {}
+
+    VtkLocalFunction (std::shared_ptr<VTKFunction<GridView> const> const& lf)
+      : localFct_(std::make_shared<VTKLocalFunctionWrapper<GridView>>(lf))
+    {}
+
+    VtkLocalFunction () = default;
+
+    /// Bind the function to the grid entity
+    void bind (Entity const& entity)
+    {
+      localFct_->bind(entity);
+    }
+
+    /// Unbind from the currently bound entity
+    void unbind ()
+    {
+      localFct_->unbind();
+    }
+
+    /// Evaluate the `comp` component of the Range value at local coordinate `xi`
+    double evaluate (int comp, LocalCoordinate const& xi) const
+    {
+      return localFct_->evaluate(comp, xi);
+    }
+
+  private:
+    std::shared_ptr<VtkLocalFunctionInterface<GridView>> localFct_;
+  };
+
+}} // end namespace Dune::experimental
diff --git a/dune/vtk/vtklocalfunctioninterface.hh b/dune/vtk/vtklocalfunctioninterface.hh
new file mode 100644
index 0000000..221dbc1
--- /dev/null
+++ b/dune/vtk/vtklocalfunctioninterface.hh
@@ -0,0 +1,26 @@
+#pragma once
+
+namespace Dune { namespace experimental
+{
+  /// An abstract base class for LocalFunctions
+  template <class GridView>
+  class VtkLocalFunctionInterface
+  {
+  public:
+    using Entity = typename GridView::template Codim<0>::Entity;
+    using LocalCoordinate = typename Entity::Geometry::LocalCoordinate;
+
+    /// Bind the function to the grid entity
+    virtual void bind (Entity const& entity) = 0;
+
+    /// Unbind from the currently bound entity
+    virtual void unbind () = 0;
+
+    /// Evaluate single component comp in the entity at local coordinates xi
+    virtual double evaluate (int comp, LocalCoordinate const& xi) const = 0;
+
+    /// Virtual destructor
+    virtual ~VtkLocalFunctionInterface () = default;
+  };
+
+}} // end namespace Dune::experimental
diff --git a/dune/vtk/writers/vtkwriterinterface.hh b/dune/vtk/writers/vtkwriterinterface.hh
index c86609e..26e9202 100644
--- a/dune/vtk/writers/vtkwriterinterface.hh
+++ b/dune/vtk/writers/vtkwriterinterface.hh
@@ -21,8 +21,7 @@ namespace Dune { namespace experimental
   protected:
     static constexpr int dimension = GridView::dimension;
 
-    using GlobalFunction = VtkFunction<GridView>;
-    using LocalFunction = VtkLocalFunction<GridView>;
+    using VtkFunction = Dune::experimental::VtkFunction<GridView>;
     using pos_type = typename std::ostream::pos_type;
 
     enum PositionTypes {
@@ -47,23 +46,19 @@ namespace Dune { namespace experimental
                 Vtk::FormatTypes format,
                 Vtk::DataTypes datatype = Vtk::FLOAT32);
 
-    /// Attach point data to the writer
-    template <class GridViewFunction>
-    VtkWriterInterface& addPointData (GridViewFunction const& gridViewFct,
-                                      std::string const& name = {},
-                                      int ncomps = 1)
+    /// Attach point data to the writer, \see VtkFunction for possible arguments
+    template <class Function, class... Args>
+    VtkWriterInterface& addPointData (Function const& fct, Args&&... args)
     {
-      pointData_.emplace_back(gridViewFct, name, ncomps);
+      pointData_.emplace_back(fct, std::forward<Args>(args)...);
       return *this;
     }
 
-    /// Attach cell data to the writer
-    template <class GridViewFunction>
-    VtkWriterInterface& addCellData (GridViewFunction const& gridViewFct,
-                                     std::string const& name = {},
-                                     int ncomps = 1)
+    /// Attach cell data to the writer, \see VtkFunction for possible arguments
+    template <class Function, class... Args>
+    VtkWriterInterface& addCellData (Function const& fct, Args&&... args)
     {
-      cellData_.emplace_back(gridViewFct, name, ncomps);
+      cellData_.emplace_back(fct, std::forward<Args>(args)...);
       return *this;
     }
 
@@ -84,14 +79,14 @@ namespace Dune { namespace experimental
     // attributes "offset" in the vector `offsets`.
     void writeData (std::ofstream& out,
                     std::vector<pos_type>& offsets,
-                    GlobalFunction const& fct,
+                    VtkFunction const& fct,
                     PositionTypes type) const;
 
     // Collect point or cell data (depending on \ref PositionTypes) and pass
     // the resulting vector to \ref writeAppended.
     template <class T>
     std::uint64_t writeDataAppended (std::ofstream& out,
-                                     GlobalFunction const& fct,
+                                     VtkFunction const& fct,
                                      PositionTypes type) const;
 
     // Write the coordinates of the vertices to the output stream `out`. In case
@@ -110,7 +105,7 @@ namespace Dune { namespace experimental
     std::uint64_t writeAppended (std::ofstream& out, std::vector<T> const& values) const;
 
     /// Return PointData/CellData attributes for the name of the first scalar/vector/tensor DataArray
-    std::string getNames (std::vector<GlobalFunction> const& data) const
+    std::string getNames (std::vector<VtkFunction> const& data) const
     {
       auto scalar = std::find_if(data.begin(), data.end(), [](auto const& v) { return v.ncomps() == 1; });
       auto vector = std::find_if(data.begin(), data.end(), [](auto const& v) { return v.ncomps() == 3; });
@@ -135,8 +130,8 @@ namespace Dune { namespace experimental
     Vtk::DataTypes datatype_;
 
     // attached data
-    std::vector<GlobalFunction> pointData_;
-    std::vector<GlobalFunction> cellData_;
+    std::vector<VtkFunction> pointData_;
+    std::vector<VtkFunction> cellData_;
 
     std::size_t const block_size = 1024*32;
     int compression_level = -1; // in [0,9], -1 ... use default value
diff --git a/dune/vtk/writers/vtkwriterinterface.impl.hh b/dune/vtk/writers/vtkwriterinterface.impl.hh
index 5b39fb2..353fb08 100644
--- a/dune/vtk/writers/vtkwriterinterface.impl.hh
+++ b/dune/vtk/writers/vtkwriterinterface.impl.hh
@@ -65,7 +65,7 @@ void VtkWriterInterface<GV,DC>
 template <class GV, class DC>
 void VtkWriterInterface<GV,DC>
   ::writeData (std::ofstream& out, std::vector<pos_type>& offsets,
-               GlobalFunction const& fct, PositionTypes type) const
+               VtkFunction const& fct, PositionTypes type) const
 {
   out << "<DataArray Name=\"" << fct.name() << "\" type=\"" << to_string(fct.type()) << "\""
       << " NumberOfComponents=\"" << fct.ncomps() << "\" format=\"" << (format_ == Vtk::ASCII ? "ascii\">\n" : "appended\"");
@@ -116,7 +116,7 @@ void VtkWriterInterface<GV,DC>
 template <class GV, class DC>
   template <class T>
 std::uint64_t VtkWriterInterface<GV,DC>
-  ::writeDataAppended (std::ofstream& out, GlobalFunction const& fct, PositionTypes type) const
+  ::writeDataAppended (std::ofstream& out, VtkFunction const& fct, PositionTypes type) const
 {
   assert(is_a(format_, Vtk::APPENDED) && "Function should by called only in appended mode!\n");
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 23038f9..96f90d2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,6 +22,10 @@ add_executable("structuredgridwriter" structuredgridwriter.cc)
 target_link_dune_default_libraries("structuredgridwriter")
 target_link_libraries("structuredgridwriter" dunevtk)
 
+add_executable("legacyvtkwriter" legacyvtkwriter.cc)
+target_link_dune_default_libraries("legacyvtkwriter")
+target_link_libraries("legacyvtkwriter" dunevtk)
+
 if (dune-polygongrid_FOUND)
   add_executable("polygongrid" polygongrid.cc)
   target_link_dune_default_libraries("polygongrid")
diff --git a/src/legacyvtkwriter.cc b/src/legacyvtkwriter.cc
new file mode 100644
index 0000000..8631e0e
--- /dev/null
+++ b/src/legacyvtkwriter.cc
@@ -0,0 +1,77 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <iostream>
+#include <vector>
+
+#include <dune/common/parallel/mpihelper.hh> // An initializer of MPI
+#include <dune/common/exceptions.hh> // We use exceptions
+#include <dune/common/filledarray.hh>
+
+#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+#include <dune/functions/functionspacebases/interpolate.hh>
+#include <dune/functions/gridfunctions/analyticgridviewfunction.hh>
+#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh>
+#include <dune/grid/uggrid.hh>
+#include <dune/grid/yaspgrid.hh>
+
+#include <dune/vtk/writers/vtkunstructuredgridwriter.hh>
+#include <dune/vtk/legacyvtkfunction.hh>
+
+using namespace Dune;
+using namespace Dune::experimental;
+using namespace Dune::Functions;
+
+#define GRID_TYPE 1
+
+int main(int argc, char** argv)
+{
+  Dune::MPIHelper::instance(argc, argv);
+
+  const int dim = 3;
+
+#if GRID_TYPE == 1
+  using GridType = YaspGrid<dim>;
+  FieldVector<double,dim> upperRight; upperRight = 1.0;
+  auto numElements = filledArray<dim,int>(8);
+  GridType grid(upperRight,numElements);
+#elif GRID_TYPE == 2
+  using GridType = UGGrid<dim>;
+  FieldVector<double,dim> lowerLeft; lowerLeft = 0.0;
+  FieldVector<double,dim> upperRight; upperRight = 1.0;
+  auto numElements = filledArray<dim,unsigned int>(4);
+  auto gridPtr = StructuredGridFactory<GridType>::createSimplexGrid(lowerLeft, upperRight, numElements);
+  auto& grid = *gridPtr;
+#endif
+
+  using GridView = typename GridType::LeafGridView;
+  GridView gridView = grid.leafGridView();
+
+  using namespace BasisFactory;
+  auto basis = makeBasis(gridView, lagrange<1>());
+
+  std::vector<double> p1function(basis.dimension());
+
+  interpolate(basis, p1function, [](auto const& x) {
+    return 100*x[0] + 10*x[1] + 1*x[2];
+  });
+
+  using P1Function = P1VTKFunction<GridView,std::vector<double>>;
+  std::shared_ptr<VTKFunction<GridView> const> p1FctWrapped(new P1Function(gridView, p1function, "p1"));
+
+  using Writer = VtkUnstructuredGridWriter<GridView>;
+  Writer vtkWriter(gridView);
+  vtkWriter.addPointData(p1FctWrapped);
+
+  vtkWriter.write("test_ascii_float32.vtu", Vtk::ASCII);
+  vtkWriter.write("test_binary_float32.vtu", Vtk::BINARY);
+  vtkWriter.write("test_compressed_float32.vtu", Vtk::COMPRESSED);
+  vtkWriter.write("test_ascii_float64.vtu", Vtk::ASCII, Vtk::FLOAT64);
+  vtkWriter.write("test_binary_float64.vtu", Vtk::BINARY, Vtk::FLOAT64);
+  vtkWriter.write("test_compressed_float64.vtu", Vtk::COMPRESSED, Vtk::FLOAT64);
+}
-- 
GitLab