diff --git a/src/output/VTKWriter.hpp b/src/output/VTKWriter.hpp
index 57bd02166957fdea064e7c04bc3f8c11b431e553..d3b27c4aba234a000ce8a70c6bea83e2114629b6 100644
--- a/src/output/VTKWriter.hpp
+++ b/src/output/VTKWriter.hpp
@@ -14,11 +14,131 @@
 class VTKWriter
 {
  private:
+  template <typename DataType> struct VTKType {};
+
+  template <> struct VTKType<int8_t>
+  {
+    inline const static std::string name{"Int8"};
+  };
+
+  template <> struct VTKType<uint8_t>
+  {
+    inline const static std::string name{"UInt8"};
+  };
+
+  template <> struct VTKType<int16_t>
+  {
+    inline const static std::string name{"Int16"};
+  };
+
+  template <> struct VTKType<uint16_t>
+  {
+    inline const static std::string name{"UInt16"};
+  };
+
+  template <> struct VTKType<int32_t>
+  {
+    inline const static std::string name{"Int32"};
+  };
+
+  template <> struct VTKType<uint32_t>
+  {
+    inline const static std::string name{"UInt32"};
+  };
+
+  template <> struct VTKType<int64_t>
+  {
+    inline const static std::string name{"Int64"};
+  };
+
+  template <> struct VTKType<uint64_t>
+  {
+    inline const static std::string name{"UInt64"};
+  };
+
+  template <> struct VTKType<float>
+  {
+    inline const static std::string name{"Float32"};
+  };
+
+  template <> struct VTKType<double>
+  {
+    inline const static std::string name{"Float64"};
+  };
+
   const std::string m_base_filename;
   unsigned int m_file_number;
   double m_last_time;
   const double m_time_period;
 
+
+  template <typename DataType>
+  void _write_node_value(std::ofstream& os,
+                   const std::string& name,
+                   const NodeValue<const DataType>& item_value)
+  {
+    os << "<DataArray type=\"" << VTKType<DataType>::name
+       << "\" Name=\"" << name << "\">\n";
+    for (NodeId i=0; i<item_value.size(); ++i) {
+      os << item_value[i] << ' ';
+    }
+    os << "\n</DataArray>\n";
+  }
+
+  template <size_t N,
+            typename DataType>
+  void _write_node_value(std::ofstream& os,
+                         const std::string& name,
+                         const NodeValue<const TinyVector<N, DataType>>& item_value)
+  {
+    os << "<DataArray type=\"" << VTKType<DataType>::name
+       << "\" Name=\"" << name << "\" NumberOfComponents=\"" << N <<  "\">\n";
+    for (NodeId i=0; i<item_value.size(); ++i) {
+      for (size_t j=0; j<N; ++j) {
+        os << item_value[i][j] << ' ';
+      }
+    }
+    os << "\n</DataArray>\n";
+  }
+
+  template <typename DataType>
+  void _write_node_value(std::ofstream& os,
+                         const std::string& name,
+                         const CellValue<const DataType>& item_value) {}
+
+
+  template <typename DataType>
+  void _write_cell_value(std::ofstream& os,
+                   const std::string& name,
+                   const NodeValue<const DataType>& item_value) {}
+
+  template <typename DataType>
+  void _write_cell_value(std::ofstream& os,
+                         const std::string& name,
+                         const CellValue<const DataType>& item_value)
+  {
+    os << "<DataArray type=\"Float64\" Name=\"" << name << "\">\n";
+    for (CellId i=0; i<item_value.size(); ++i) {
+      os << item_value[i] << ' ';
+    }
+    os << "\n</DataArray>\n";
+  }
+
+  template <size_t N,
+            typename DataType>
+  void _write_cell_value(std::ofstream& os,
+                         const std::string& name,
+                         const CellValue<const TinyVector<N, DataType>>& item_value)
+  {
+    os << "<DataArray type=\"Float64\" Name=\"" << name << "\" NumberOfComponents=\"" << N <<  "\">\n";
+    for (CellId i=0; i<item_value.size(); ++i) {
+      for (size_t j=0; j<N; ++j) {
+        os << item_value[i][j] << ' ';
+      }
+    }
+    os << "\n</DataArray>\n";
+  }
+
  public:
   template <typename MeshType>
   void write(const MeshType& mesh,
@@ -40,7 +160,20 @@ class VTKWriter
     fout << "<UnstructuredGrid>\n";
     fout << "<Piece NumberOfPoints=\""<< mesh.numberOfNodes()
          << "\" NumberOfCells=\"" << mesh.numberOfCells() << "\">\n";
-
+    fout << "<CellData>\n";
+    for(const auto& [name, item_value_variant] : output_named_item_value_set) {
+      std::visit([&, name=name](auto&& item_value) {
+                   return this->_write_cell_value(fout, name, item_value);
+                 }, item_value_variant);
+    }
+    fout << "</CellData>\n";
+    fout << "<PointData>\n";
+    for(const auto& [name, item_value_variant] : output_named_item_value_set) {
+      std::visit([&, name=name](auto&& item_value) {
+                   return this->_write_node_value(fout, name, item_value);
+                 }, item_value_variant);
+    }
+    fout << "</PointData>\n";
     fout << "<Points>\n";
     fout << "<DataArray Name=\"Positions\" NumberOfComponents=\"3\" type=\"Float64\" format=\"ascii\">\n";
     using Rd = TinyVector<MeshType::dimension>;