OGS
XdmfHdfWriter.cpp
Go to the documentation of this file.
1
10#include "XdmfHdfWriter.h"
11
12#include <algorithm>
13#include <functional>
14#include <range/v3/algorithm/contains.hpp>
15
16#include "BaseLib/Algorithm.h"
17#include "InfoLib/GitInfo.h"
18#include "partition.h"
19#include "transformData.h"
20#include "writeXdmf.h"
21
22using namespace std::literals;
23
24namespace MeshLib::IO
25{
27{
28 std::vector<double> flattened_geometry_values;
29 std::vector<int> flattened_topology_values;
30};
31struct XdmfHdfMesh final
32{
35 std::vector<XdmfHdfData> attributes;
36 std::string name;
37 // TransformedMeshData may be large, ensure it is never copied
38 std::unique_ptr<TransformedMeshData> transformed_data;
39};
40
41template <typename Data>
42std::function<bool(Data)> isVariableAttribute(
43 std::set<std::string> const& variable_output_names)
44{
45 if (variable_output_names.empty())
46 {
47 return [](Data const& data) -> bool
48 {
49 constexpr std::array constant_output_names{
50 "MaterialIDs"sv,
51 "topology"sv,
52 "geometry"sv,
53 "OGS_VERSION"sv,
58 return !ranges::contains(constant_output_names, data.name);
59 };
60 }
61 return [&variable_output_names](Data const& data) -> bool
62 { return variable_output_names.contains(data.name); };
63}
64
66 std::vector<std::reference_wrapper<const MeshLib::Mesh>> const& meshes,
67 std::filesystem::path const& filepath, unsigned long long const time_step,
68 double const initial_time,
69 std::set<std::string> const& variable_output_names,
70 bool const use_compression, unsigned int const n_files,
71 unsigned int const chunk_size_bytes)
72{
73 // ogs meshes to vector of Xdmf/HDF meshes (we keep Xdmf and HDF together
74 // because XDMF depends on HDF) to meta
75
76 // if no output name is specified, all data will be assumened to be
77 // variable over the timesteps. The xdmfhdfwriter is an alternative to
78 // other writers, that do not consider the constantness of data Callers
79 // of xdmfwriter (e.g. ogs tools) do not provide these information yet
80 // and indicate with empty list
81
82 // Transform the data to be written into a format conforming with the rules
83 // of xdmf topology and geometry
84 auto const transform_ogs_mesh_data_to_xdmf_conforming_data =
85 [&n_files, &chunk_size_bytes](auto const& mesh)
86 {
87 auto flattened_geometry_values = transformToXDMFGeometry(mesh);
88 // actually this line is only needed to calculate the offset
89 XdmfHdfData const& geometry = transformGeometry(
90 mesh, flattened_geometry_values.data(), n_files, chunk_size_bytes);
91 auto const flattened_topology_values =
92 transformToXDMFTopology(mesh, geometry.hdf.offsets[0]);
93 return std::make_unique<TransformedMeshData>(
94 TransformedMeshData{std::move(flattened_geometry_values),
95 std::move(flattened_topology_values)});
96 };
97
98 // create metadata for transformed data and original ogs mesh data
99 auto const transform_to_meta_data =
100 [&transform_ogs_mesh_data_to_xdmf_conforming_data, &n_files,
101 &chunk_size_bytes](auto const& mesh)
102 {
103 // important: transformed data must survive and be unique, raw pointer
104 // to its memory!
105 std::unique_ptr<TransformedMeshData> xdmf_conforming_data =
106 transform_ogs_mesh_data_to_xdmf_conforming_data(mesh);
107 auto const geometry = transformGeometry(
108 mesh, xdmf_conforming_data->flattened_geometry_values.data(),
109 n_files, chunk_size_bytes);
110 auto const topology =
111 transformTopology(xdmf_conforming_data->flattened_topology_values,
112 n_files, chunk_size_bytes);
113 auto const attributes =
114 transformAttributes(mesh, n_files, chunk_size_bytes);
115 return XdmfHdfMesh{std::move(geometry), std::move(topology),
116 std::move(attributes), mesh.get().getName(),
117 std::move(xdmf_conforming_data)};
118 };
119 auto isVariableHdfAttribute =
120 isVariableAttribute<HdfData>(variable_output_names);
121
122 // extract meta data relevant for HDFWriter
123 auto const transform_metamesh_to_hdf =
124 [&isVariableHdfAttribute](auto const& metamesh)
125 {
126 // topology and geometry can be treated as any other attribute
127 std::vector<HdfData> hdf_data_attributes = {metamesh.geometry.hdf,
128 metamesh.topology.hdf};
129
130 hdf_data_attributes.reserve(hdf_data_attributes.size() +
131 metamesh.attributes.size());
132 std::transform(metamesh.attributes.begin(), metamesh.attributes.end(),
133 std::back_inserter(hdf_data_attributes),
134 [](XdmfHdfData att) -> HdfData { return att.hdf; });
135
136 HDFAttributes constant_attributes;
137 std::copy_if(hdf_data_attributes.begin(), hdf_data_attributes.end(),
138 back_inserter(constant_attributes),
139 std::not_fn(isVariableHdfAttribute));
140 HDFAttributes variable_attributes;
141 std::copy_if(hdf_data_attributes.begin(), hdf_data_attributes.end(),
142 back_inserter(variable_attributes),
143 isVariableHdfAttribute);
144
145 return MeshHdfData{
146 .constant_attributes = std::move(constant_attributes),
147 .variable_attributes = std::move(variable_attributes),
148 .name = std::move(metamesh.name)};
149 };
150
151 // --------------- XDMF + HDF ---------------------
152 std::vector<XdmfHdfMesh> xdmf_hdf_meshes;
153 xdmf_hdf_meshes.reserve(meshes.size());
154 std::transform(meshes.begin(), meshes.end(),
155 std::back_inserter(xdmf_hdf_meshes), transform_to_meta_data);
156
157 std::vector<MeshHdfData> hdf_meshes;
158 hdf_meshes.reserve(xdmf_hdf_meshes.size());
159 std::transform(xdmf_hdf_meshes.begin(), xdmf_hdf_meshes.end(),
160 std::back_inserter(hdf_meshes), transform_metamesh_to_hdf);
161
162 // --------------- HDF ---------------------
163 std::filesystem::path const hdf_filepath =
164 filepath.parent_path() / (filepath.stem().string() + ".h5");
165
166 auto const is_file_manager = isFileManager();
167 _hdf_writer = std::make_unique<HdfWriter>(std::move(hdf_meshes), time_step,
168 hdf_filepath, use_compression,
169 is_file_manager, n_files);
170
171 // --------------- XDMF ---------------------
172 // The light data is only written by just one process
173 if (!is_file_manager)
174 {
175 return;
176 }
177
178 auto isVariableXdmfAttribute =
179 isVariableAttribute<XdmfData>(variable_output_names);
180 // xdmf section
181 // extract meta data relevant for XDMFWriter
182 auto const transform_metamesh_to_xdmf =
183 [&isVariableXdmfAttribute, &filepath, &hdf_filepath,
184 &initial_time](XdmfHdfMesh& metamesh)
185 {
186 std::string const xdmf_name = metamesh.name;
187 std::filesystem::path const xdmf_filepath =
188 filepath.parent_path() /
189 (filepath.stem().string() + "_" + xdmf_name + ".xdmf");
190
191 std::vector<XdmfData> xdmf_attributes;
192 std::transform(metamesh.attributes.begin(), metamesh.attributes.end(),
193 std::back_inserter(xdmf_attributes),
194 [](XdmfHdfData const& att) -> XdmfData
195 { return att.xdmf; });
196
197 for (std::size_t i = 0; i < metamesh.attributes.size(); ++i)
198 {
199 // index 1 time, index 2 geo, index 3 topology, attributes start at
200 // index 4
201 xdmf_attributes[i].index = i + 4;
202 }
203
204 std::vector<XdmfData> xdmf_variable_attributes;
205 std::copy_if(xdmf_attributes.begin(), xdmf_attributes.end(),
206 back_inserter(xdmf_variable_attributes),
207 isVariableXdmfAttribute);
208 std::vector<XdmfData> xdmf_constant_attributes;
209 std::copy_if(xdmf_attributes.begin(), xdmf_attributes.end(),
210 back_inserter(xdmf_constant_attributes),
211 std::not_fn(isVariableXdmfAttribute));
212
213 auto const xdmf_writer_fn =
214 write_xdmf(metamesh.geometry.xdmf, metamesh.topology.xdmf,
215 xdmf_constant_attributes, xdmf_variable_attributes,
216 hdf_filepath.filename().string(),
218 auto xdmf_writer = std::make_unique<XdmfWriter>(xdmf_filepath.string(),
219 xdmf_writer_fn);
220 xdmf_writer->addTimeStep(initial_time);
221 return xdmf_writer;
222 };
223
224 std::transform(xdmf_hdf_meshes.begin(), xdmf_hdf_meshes.end(),
225 std::back_inserter(_xdmf_writer),
226 transform_metamesh_to_xdmf);
227}
228
229void XdmfHdfWriter::writeStep(double const time)
230{
231 // ToDo (tm) time_step will be used for simulation continuation (restart)
232 _hdf_writer->writeStep(time);
233 // The light data is only written by just one process
234 if (isFileManager())
235 {
236 for (auto const& xdmf_writer : _xdmf_writer)
237 {
238 xdmf_writer->addTimeStep(time);
239 }
240 }
241}
242
243} // namespace MeshLib::IO
Git information.
XdmfWriter which create contiguous data for geometry and topology and writes this and all attributes ...
XdmfHdfWriter(std::vector< std::reference_wrapper< const MeshLib::Mesh > > const &meshes, std::filesystem::path const &filepath, unsigned long long time_step, double initial_time, std::set< std::string > const &variable_output_names, bool use_compression, unsigned int n_files, unsigned int chunk_size_bytes)
Write xdmf and h5 file with geometry and topology data.
std::unique_ptr< HdfWriter > _hdf_writer
std::vector< std::unique_ptr< XdmfWriter > > _xdmf_writer
void writeStep(double time)
Adds data for either lazy (xdmf) or eager (hdf) writing algorithm.
GITINFOLIB_EXPORT const std::string ogs_version
std::vector< int > transformToXDMFTopology(MeshLib::Mesh const &mesh, std::size_t const offset)
Copies all cells into a new vector. Contiguous data used for writing. The topology is specific to xdm...
std::vector< HdfData > HDFAttributes
Definition HdfWriter.h:25
std::vector< double > transformToXDMFGeometry(MeshLib::Mesh const &mesh)
Copies all node points into a new vector. Contiguous data used for writing. Conform with XDMF standar...
std::function< std::string(std::vector< double >)> write_xdmf(XdmfData const &geometry, XdmfData const &topology, std::vector< XdmfData > const &constant_attributes, std::vector< XdmfData > const &variable_attributes, std::string const &h5filename, std::string const &ogs_version, std::string const &mesh_name)
Generator function that creates a function capturing the spatial data of a mesh Temporal data can lat...
XdmfHdfData transformGeometry(MeshLib::Mesh const &mesh, double const *data_ptr, unsigned int const n_files, unsigned int const chunk_size_bytes)
Create meta data for geometry used for hdf5 and xdmf.
std::function< bool(Data)> isVariableAttribute(std::set< std::string > const &variable_output_names)
std::vector< XdmfHdfData > transformAttributes(MeshLib::Mesh const &mesh, unsigned int const n_files, unsigned int const chunk_size_bytes)
Create meta data for attributes used for hdf5 and xdmf.
XdmfHdfData transformTopology(std::vector< int > const &values, unsigned int const n_files, unsigned int const chunk_size_bytes)
Create meta data for topology used for HDF5 and XDMF.
bool isFileManager()
Definition partition.cpp:26
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)
Definition Properties.h:188
Dispatches functions specific to execution platform (w/o MPI)
std::vector< Hdf5DimType > offsets
Definition HdfData.h:34
HDFAttributes constant_attributes
Definition HdfWriter.h:28
std::vector< int > flattened_topology_values
std::vector< double > flattened_geometry_values
std::vector< XdmfHdfData > attributes
std::unique_ptr< TransformedMeshData > transformed_data
Transforms OGS Mesh into vectorized data.
write_xdmf generates a function based on spatial mesh data. The generated function finally generates ...