From 299c7129e98defba256f4be4bada8458664266eb Mon Sep 17 00:00:00 2001
From: Tobias Meisel <tobias.meisel@ufz.de>
Date: Tue, 4 May 2021 09:45:25 +0200
Subject: [PATCH] [MeL/IO] Xdmf: Use hyperslab selector for new hdf5 file
 structure

---
 MeshLib/IO/XDMF/Xdmf3Writer.cpp   | 41 +++++++++++++++++++++----------
 MeshLib/IO/XDMF/XdmfData.cpp      | 38 +++++++++++++++++++++++-----
 MeshLib/IO/XDMF/XdmfHdfWriter.cpp |  2 +-
 3 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/MeshLib/IO/XDMF/Xdmf3Writer.cpp b/MeshLib/IO/XDMF/Xdmf3Writer.cpp
index 43fc7eb9cd6..91556c378c9 100644
--- a/MeshLib/IO/XDMF/Xdmf3Writer.cpp
+++ b/MeshLib/IO/XDMF/Xdmf3Writer.cpp
@@ -44,19 +44,27 @@ boost::shared_ptr<const XdmfAttributeCenter> elemTypeOGS2XDMF(
     return mesh_item_type_ogs2xdmf.at(elem_type);
 }
 
-static std::string getTimeSection(int const step, std::string const& name)
+static std::string getDataSection(std::string const& name)
 {
-    return "t_"s + std::to_string(step) + "/"s + name;
+    return "data/"s + name;
+}
+
+static std::vector<XdmfDimType> prependDimension(
+    XdmfDimType const prepend_value, std::vector<XdmfDimType> const& dimensions)
+{
+    std::vector<XdmfDimType> dims = {prepend_value};
+    dims.insert(dims.end(), dimensions.begin(), dimensions.end());
+    return dims;
 }
 
 static boost::shared_ptr<XdmfGeometry> getLightGeometry(
-    std::string const& hdf5filename, int const step, XdmfData const& geometry)
+    std::string const& hdf5filename, XdmfData const& geometry)
 {
     auto xdmf_geometry = XdmfGeometry::New();
     xdmf_geometry->setType(XdmfGeometryType::XYZ());
     boost::shared_ptr<XdmfHDF5Controller> geometry_controller =
         XdmfHDF5Controller::New(hdf5filename,
-                                getTimeSection(step, "geometry"),
+                                getDataSection("geometry"),
                                 XdmfArrayType::Float64(),
                                 geometry.starts,
                                 geometry.strides,
@@ -67,13 +75,13 @@ static boost::shared_ptr<XdmfGeometry> getLightGeometry(
 }
 
 static boost::shared_ptr<XdmfTopology> getLightTopology(
-    std::string const& hdf5filename, int const step, XdmfData const& topology)
+    std::string const& hdf5filename, XdmfData const& topology)
 {
     auto xdmf_topology = XdmfTopology::New();
     xdmf_topology->setType(XdmfTopologyType::Mixed());
     auto topology_controller =
         XdmfHDF5Controller::New(hdf5filename,
-                                getTimeSection(step, "topology"),
+                                getDataSection("topology"),
                                 XdmfArrayType::Int32(),
                                 topology.starts,
                                 topology.strides,
@@ -86,14 +94,21 @@ static boost::shared_ptr<XdmfTopology> getLightTopology(
 static boost::shared_ptr<XdmfAttribute> getLightAttribute(
     std::string const& hdf5filename, int const step, XdmfData const& attribute)
 {
+    std::vector<XdmfDimType> starts = prependDimension(step, attribute.starts);
+    std::vector<XdmfDimType> strides = prependDimension(1, attribute.strides);
+    std::vector<XdmfDimType> global_block_dims =
+        prependDimension(1, attribute.global_block_dims);
+    std::vector<XdmfDimType> all_global_block_dims =
+        prependDimension(step + 1, attribute.global_block_dims);
+
     auto const attribute_controller =
         XdmfHDF5Controller::New(hdf5filename,
-                                getTimeSection(step, attribute.name),
+                                getDataSection(attribute.name),
                                 attribute.data_type,
-                                attribute.starts,
-                                attribute.strides,
-                                attribute.global_block_dims,
-                                attribute.global_block_dims);
+                                starts,
+                                strides,
+                                global_block_dims,
+                                all_global_block_dims);
 
     auto const xdmf_attribute = XdmfAttribute::New();
     auto const center = elemTypeOGS2XDMF(*(attribute.attribute_center));
@@ -113,8 +128,8 @@ Xdmf3Writer::Xdmf3Writer(XdmfData const& geometry, XdmfData const& topology,
     : _variable_attributes(std::move(variable_attributes)),
       _hdf5filename(filepath.stem().string() + ".h5")
 {
-    _initial_geometry = getLightGeometry(_hdf5filename, time_step, geometry);
-    _initial_topology = getLightTopology(_hdf5filename, time_step, topology);
+    _initial_geometry = getLightGeometry(_hdf5filename, geometry);
+    _initial_topology = getLightTopology(_hdf5filename, topology);
 
     std::transform(
         constant_attributes.begin(), constant_attributes.end(),
diff --git a/MeshLib/IO/XDMF/XdmfData.cpp b/MeshLib/IO/XDMF/XdmfData.cpp
index 5d734997321..a2e0462e48e 100644
--- a/MeshLib/IO/XDMF/XdmfData.cpp
+++ b/MeshLib/IO/XDMF/XdmfData.cpp
@@ -47,13 +47,31 @@ static boost::shared_ptr<XdmfArrayType const> MeshPropertyDataType2XdmfType(
     }
 }
 
-XdmfData::XdmfData(std::size_t size_partitioned_dim,
+XdmfData::XdmfData(std::size_t const size_partitioned_dim,
                    std::size_t const size_tuple,
                    MeshPropertyDataType const mesh_property_data_type,
                    std::string const& name,
                    std::optional<MeshLib::MeshItemType> const attribute_center)
-    : starts{0, 0, 0},
-      strides{1, 1, 1},
+    : starts([&size_tuple]() {
+          if (size_tuple > 1)
+          {
+              return std::vector<XdmfDimType>{0, 0};
+          }
+          else
+          {
+              return std::vector<XdmfDimType>{0};
+          }
+      }()),
+      strides([&size_tuple]() {
+          if (size_tuple > 1)
+          {
+              return std::vector<XdmfDimType>{1};
+          }
+          else
+          {
+              return std::vector<XdmfDimType>{1, 1};
+          }
+      }()),
       name(name),
       attribute_center(attribute_center)
 {
@@ -64,12 +82,20 @@ XdmfData::XdmfData(std::size_t size_partitioned_dim,
     auto const ui_global_components =
         static_cast<unsigned int>(partition_info.global_length);
     auto const ui_tuple_size = static_cast<unsigned int>(size_tuple);
-    global_block_dims = {ui_global_components, ui_tuple_size};
+
+    if (ui_tuple_size == 1)
+    {
+        global_block_dims = {ui_global_components};
+    }
+    else
+    {
+        global_block_dims = {ui_global_components, ui_tuple_size};
+    }
+
     data_type = MeshPropertyDataType2XdmfType(mesh_property_data_type);
     DBUG(
         "XDMF: dataset name: {:s}, offset: {:d} "
         "global_blocks: {:d}, tuples: {:d}",
-        name, partition_info.local_offset,
-        global_block_dims[0], ui_tuple_size);
+        name, partition_info.local_offset, global_block_dims[0], ui_tuple_size);
 }
 }  // namespace MeshLib::IO
\ No newline at end of file
diff --git a/MeshLib/IO/XDMF/XdmfHdfWriter.cpp b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp
index de17a426143..a33354b118f 100644
--- a/MeshLib/IO/XDMF/XdmfHdfWriter.cpp
+++ b/MeshLib/IO/XDMF/XdmfHdfWriter.cpp
@@ -21,7 +21,7 @@ XdmfHdfWriter::XdmfHdfWriter(MeshLib::Mesh const& mesh,
                              std::filesystem::path const& filepath,
                              int const time_step,
                              std::set<std::string>
-                             variable_output_names,
+                                 variable_output_names,
                              bool const use_compression)
 {
     // transform Data into contiguous data and collect meta data
-- 
GitLab