From c0ef1fa83771f5e4acd0a88817c2d7cba63f7441 Mon Sep 17 00:00:00 2001
From: Tobias Meisel <tobias.meisel@ufz.de>
Date: Tue, 15 Dec 2020 13:07:39 +0100
Subject: [PATCH] [MeL/IO] Add class for combined writer of HDF5 and XDMF3

---
 MeshLib/IO/XDMF/XdmfHdfWriter.cpp | 65 +++++++++++++++++++++++++++++++
 MeshLib/IO/XDMF/XdmfHdfWriter.h   | 48 +++++++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 MeshLib/IO/XDMF/XdmfHdfWriter.cpp
 create mode 100644 MeshLib/IO/XDMF/XdmfHdfWriter.h

diff --git a/MeshLib/IO/XDMF/XdmfHdfWriter.cpp b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp
new file mode 100644
index 00000000000..60bb96bbfe7
--- /dev/null
+++ b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp
@@ -0,0 +1,65 @@
+
+#include "XdmfHdfWriter.h"
+
+#include <algorithm>
+
+#include "partition.h"
+#include "transformData.h"
+
+namespace MeshLib::IO
+{
+XdmfHdfWriter::XdmfHdfWriter(MeshLib::Mesh const& mesh,
+                             std::filesystem::path const& filepath,
+                             int const time_step)
+{
+    // transform Data into contiguous data and collect meta data
+    Geometry const& geometry = transformGeometry(mesh);
+    Topology const& topology = transformTopology(mesh, geometry.hdf.offsets[0]);
+    std::vector<AttributeMeta> const attributes = transformAttributes(mesh);
+
+    // HDF5
+    std::filesystem::path const hdf_filepath =
+        filepath.parent_path() / (filepath.stem().string() + ".h5");
+    std::vector<HdfData> hdf_data_attributes;
+    std::transform(attributes.begin(), attributes.end(),
+                   std::back_inserter(hdf_data_attributes),
+                   [](AttributeMeta att) -> HdfData { return att.hdf; });
+
+    // geometry hdf data refers to the local data geometry and topology vector.
+    // The hdf writer can write when data is out of scope.
+    _hdf_writer = std::make_unique<HdfWriter>(geometry.hdf, topology.hdf,
+                                              std::move(hdf_data_attributes),
+                                              time_step, hdf_filepath);
+    // XDMF
+    // The light data is only written by just one process
+    if (!isFileManager())
+    {
+        return;
+    }
+
+    std::filesystem::path const xdmf_filepath =
+        filepath.parent_path() / (filepath.stem().string() + ".xdmf");
+    std::vector<XdmfData> xdmf_data_attributes;
+    std::transform(attributes.begin(), attributes.end(),
+                   std::back_inserter(xdmf_data_attributes),
+                   [](AttributeMeta att) -> XdmfData { return att.xdmf; });
+
+    _xdmf_writer = std::make_unique<Xdmf3Writer>(
+        geometry.xdmf, topology.xdmf, std::move(xdmf_data_attributes),
+        xdmf_filepath, time_step);
+}
+
+void XdmfHdfWriter::writeStep(int const time_step, double const time) const
+{
+    _hdf_writer->writeStep(time_step);
+
+    // XDMF
+    // The light data is only written by just one process
+    if (!_xdmf_writer)
+    {
+        return;
+    }
+    _xdmf_writer->writeStep(time_step, time);
+}
+
+}  // namespace MeshLib::IO
\ No newline at end of file
diff --git a/MeshLib/IO/XDMF/XdmfHdfWriter.h b/MeshLib/IO/XDMF/XdmfHdfWriter.h
new file mode 100644
index 00000000000..ce88ad76ae4
--- /dev/null
+++ b/MeshLib/IO/XDMF/XdmfHdfWriter.h
@@ -0,0 +1,48 @@
+/**
+ * \file
+ * \author Tobias Meisel
+ * \date   2020-11-13
+ * \brief  XdmfWriter which create contiguous data for geometry and topology
+ * and writes this and all attributes to 1 xdmf + 1 hdf file
+ *
+ * \copyright
+ * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ */
+
+#pragma once
+
+#include <filesystem.h>
+
+#include "HdfWriter.h"
+#include "MeshLib/Mesh.h"
+#include "Xdmf3Writer.h"
+
+namespace MeshLib::IO
+{
+class XdmfHdfWriter final
+{
+public:
+    /**
+     * \brief Write xdmf and h5 file with geometry and topology data.
+     * @param mesh Mesh or NodePartitionedMesh to be written to file(s)
+     * @param filepath absolute or relative filepath to the hdf5 file
+     * @param time_step number of the step (temporal collection)
+     */
+    XdmfHdfWriter(MeshLib::Mesh const& mesh,
+                  std::filesystem::path const& filepath, int time_step);
+    /**
+     * \brief Write attribute data that has modified to previous time step or
+     * initial
+     * @param time_step number of the step (temporal collection)
+     * @param time time value of the current time_step
+     */
+    void writeStep(int time_step, double time) const;
+
+private:
+    std::unique_ptr<HdfWriter> _hdf_writer;
+    std::unique_ptr<Xdmf3Writer> _xdmf_writer;
+};
+}  // namespace MeshLib::IO
\ No newline at end of file
-- 
GitLab