diff --git a/src/conversion/vtk/adaptor/foamVtkTools.H b/src/conversion/vtk/adaptor/foamVtkTools.H
index b246e3edf80f5fcfb2f2e59d839e02a961379d13..554f62af46b91096630209f33bbc8c77deb0dc67 100644
--- a/src/conversion/vtk/adaptor/foamVtkTools.H
+++ b/src/conversion/vtk/adaptor/foamVtkTools.H
@@ -197,6 +197,10 @@ public:
         //- Convert patch points/faces to vtkPolyData
         template<class PatchType>
         static vtkSmartPointer<vtkPolyData> mesh(const PatchType& p);
+
+        //- Convert patch face normals to vtkFloatArray
+        template<class PatchType>
+        static vtkSmartPointer<vtkFloatArray> faceNormals(const PatchType& p);
     };
 
 
diff --git a/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C b/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C
index ef9ff93c4dc937539d54b991eee66462bfad75c1..3a7b653869099e18df15ee5f0cd50de25d625e89 100644
--- a/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C
+++ b/src/conversion/vtk/adaptor/foamVtkToolsTemplates.C
@@ -109,6 +109,32 @@ Foam::vtk::Tools::Patch::mesh(const PatchType& p)
 }
 
 
+template<class PatchType>
+vtkSmartPointer<vtkFloatArray>
+Foam::vtk::Tools::Patch::faceNormals(const PatchType& p)
+{
+    auto array = vtkSmartPointer<vtkFloatArray>::New();
+
+    array->SetNumberOfComponents(3);
+    array->SetNumberOfTuples(p.size());
+
+    // Unit normals for patch faces.
+    // If not already cached, could be more memory efficient to loop over
+    // the individual faces instead.
+
+    const vectorField& norms = p.faceNormals();
+
+    vtkIdType faceId = 0;
+    for (const vector& n : norms)
+    {
+        array->SetTuple(faceId, n.v_);
+        ++faceId;
+    }
+
+    return array;
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 //
 // Low-Level conversions
diff --git a/src/fileFormats/vtk/core/foamVtkCore.C b/src/fileFormats/vtk/core/foamVtkCore.C
index 62612deb57a46b245c1bc909af23f752622bfaa4..6b8ab91b9306fc00b6e40967692fa9ebc0cb872b 100644
--- a/src/fileFormats/vtk/core/foamVtkCore.C
+++ b/src/fileFormats/vtk/core/foamVtkCore.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -46,6 +46,7 @@ Foam::vtk::fileTagNames
     { fileTag::POINT_DATA, "PointData" },
     { fileTag::POLY_DATA, "PolyData" },
     { fileTag::UNSTRUCTURED_GRID, "UnstructuredGrid" },
+    { fileTag::MULTI_BLOCK, "vtkMultiBlockDataSet" },
 };
 
 
diff --git a/src/fileFormats/vtk/core/foamVtkCore.H b/src/fileFormats/vtk/core/foamVtkCore.H
index d209d60c9315ac608c86e34d839dd7f495b23697..8584c9672ceebb8655b6c6403ffcb5ccb85b3d81 100644
--- a/src/fileFormats/vtk/core/foamVtkCore.H
+++ b/src/fileFormats/vtk/core/foamVtkCore.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -115,6 +115,7 @@ namespace vtk
         POINT_DATA,             //!< "PointData"
         POLY_DATA,              //!< "PolyData"
         UNSTRUCTURED_GRID,      //!< "UnstructuredGrid"
+        MULTI_BLOCK,            //!< "vtkMultiBlockDataSet"
     };
 
     //- Strings corresponding to the vtk xml tags
diff --git a/src/fileFormats/vtk/output/foamVtkOutput.C b/src/fileFormats/vtk/output/foamVtkOutput.C
index 5a54c2241ba43e8ea8d480b0f754b7c3e9993979..2ee7dbd7a57d95061cd1b267e7227d0caa6e4a39 100644
--- a/src/fileFormats/vtk/output/foamVtkOutput.C
+++ b/src/fileFormats/vtk/output/foamVtkOutput.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -33,6 +33,7 @@ License
 #include "foamVtkLegacyAsciiFormatter.H"
 #include "foamVtkLegacyRawFormatter.H"
 #include "typeInfo.H"
+#include "instant.H"
 
 // * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * * //
 
@@ -101,19 +102,52 @@ Foam::vtk::newFormatter
 }
 
 
+void Foam::vtk::writeSeries
+(
+    Ostream& os,
+    const word& prefix,
+    const word& suffix,
+    const UList<instant>& series
+)
+{
+    // Begin file-series (JSON)
+    os  << "{\n  \"file-series-version\" : \"1.0\",\n  \"files\" : [\n";
+
+    // Track how many entries are remaining
+    // - trailing commas on all but the final entry (JSON requirement)
+    label nremain = series.size();
+
+    // Each entry
+    //   { "name" : "<prefix>name<suffix>", "time" : value }
+
+    for (const instant& inst : series)
+    {
+        os  << "    { \"name\" : \""
+            << prefix << inst.name() << suffix
+            << "\", \"time\" : " << inst.value() << " }";
+
+        if (--nremain)
+        {
+            os  << ',';
+        }
+        os  << nl;
+    }
+
+    os  << "  ]\n}\n";
+}
+
+
 Foam::label Foam::vtk::writeVtmFile
 (
     std::ostream& os,
     const UList<fileName>& files
 )
 {
-    const word& content = "vtkMultiBlockDataSet";
-
     asciiFormatter vtmFile(os);
 
     vtmFile
         .xmlHeader()
-        .beginVTKFile(content, "1.0");
+        .beginVTKFile(fileTagNames[vtk::fileTag::MULTI_BLOCK], "1.0");
 
     forAll(files, i)
     {
@@ -124,7 +158,7 @@ Foam::label Foam::vtk::writeVtmFile
             .closeTag(true);
     }
 
-    vtmFile.endTag(content).endVTKFile();
+    vtmFile.endTag(fileTagNames[vtk::fileTag::MULTI_BLOCK]).endVTKFile();
 
     return files.size();
 }
diff --git a/src/fileFormats/vtk/output/foamVtkOutput.H b/src/fileFormats/vtk/output/foamVtkOutput.H
index 4a71b5208d310885e04cfcfc5a14e42cd1f99906..55f31cd91fca4baf85ed5a48a3ade1cc5e137f55 100644
--- a/src/fileFormats/vtk/output/foamVtkOutput.H
+++ b/src/fileFormats/vtk/output/foamVtkOutput.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -54,6 +54,9 @@ SourceFiles
 
 namespace Foam
 {
+// Forward declarations
+class instant;
+
 namespace vtk
 {
 
@@ -73,6 +76,19 @@ namespace vtk
     );
 
 
+    //- Write file series (JSON format) for specified time instances
+    //
+    //  \param prefix before the \c instant.name()
+    //  \param suffix after the \c instant.name()
+    //  \param series the list of name/value entries
+    void writeSeries
+    (
+        Ostream& os,
+        const word& prefix,
+        const word& suffix,
+        const UList<instant>& series
+    );
+
     //- Write vtm datasets for specified files
     label writeVtmFile(std::ostream& os, const UList<fileName>& files);