Wildmeshing Toolkit
Loading...
Searching...
No Matches
HDF5Reader.cpp
Go to the documentation of this file.
1// gcc-13 complains about how we use an empty vector as a key.
2// Vector should do empty key deref for us - we hope
3#if defined(__GNUG__) && !defined(__clang__)
4#pragma GCC diagnostic push
5#pragma GCC diagnostic ignored "-Wnull-dereference"
6#endif
7#include <map>
8#if defined(__GNUG__) && !defined(__clang__)
9#pragma GCC diagnostic pop
10#endif
11
12#if defined(__GNUG__) && !defined(__clang__)
13#pragma GCC diagnostic push
14#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
15#endif
16#include <string>
17#if defined(__GNUG__) && !defined(__clang__)
18#pragma GCC diagnostic pop
19#endif
20
21#include "HDF5Reader.hpp"
22
23#include <wmtk/Mesh.hpp>
24
25#include <wmtk/EdgeMesh.hpp>
26#include <wmtk/PointMesh.hpp>
27#include <wmtk/TetMesh.hpp>
28#include <wmtk/TriMesh.hpp>
29
30#include <wmtk/utils/Logger.hpp>
32
34
35#include <h5pp/h5pp.h>
36
37#include <regex>
38
39
40namespace wmtk {
42
43
44std::shared_ptr<Mesh> HDF5Reader::read(const std::filesystem::path& filename)
45{
46 constexpr static int64_t TWO_TUPLE_SIZE = wmtk::multimesh::utils::TWO_TUPLE_SIZE;
47 constexpr static int64_t DEFAULT_TUPLES_VALUES = wmtk::multimesh::utils::DEFAULT_TUPLES_VALUES;
48
49 h5pp::File hdf5_file(filename, h5pp::FileAccess::READONLY);
50
51 auto root = read_mesh(hdf5_file, "WMTK");
52
53 if (hdf5_file.linkExists("WMTK/multimesh")) {
54 std::map<std::vector<int64_t>, std::shared_ptr<Mesh>> meshes;
55 meshes[{}] = root;
56
57 const auto dsets = hdf5_file.findGroups("mesh_", "WMTK/multimesh", -1, 1);
58 for (auto& s : dsets) {
59 const std::string dataset = "WMTK/multimesh/" + s;
60
61 auto absolute_id =
62 hdf5_file.readAttribute<std::vector<int64_t>>(dataset, "absolute_id");
63 meshes[absolute_id] = read_mesh(hdf5_file, dataset);
64 }
65
66
67 for (auto& p : meshes) {
68 if (p.first.empty()) continue;
69
70 const std::vector<int64_t>& child_id = p.first;
71 const auto child_index = child_id.back();
72
73 std::vector<int64_t> parent_id = child_id;
74 parent_id.pop_back();
75
76 auto parent_mesh = meshes.at(parent_id);
77 auto child_mesh = p.second;
78
79 const PrimitiveType child_primitive_type = child_mesh->top_simplex_type();
80
81
82 assert(parent_mesh->m_multi_mesh_manager.m_children.size() == child_index);
83
84 auto child_to_parent_handle =
85 child_mesh
86 ->get_attribute_handle<int64_t>(
88 child_primitive_type)
89 .as<int64_t>();
90
91 auto parent_to_child_handle =
92 parent_mesh
93 ->get_attribute_handle<int64_t>(
95 child_index),
96 child_primitive_type)
97 .as<int64_t>();
98
99 child_mesh->m_multi_mesh_manager.m_parent = parent_mesh.get();
100 child_mesh->m_multi_mesh_manager.m_child_id = child_index;
101 child_mesh->m_multi_mesh_manager.map_to_parent_handle = child_to_parent_handle;
102
103 parent_mesh->m_multi_mesh_manager.m_children.emplace_back();
104 parent_mesh->m_multi_mesh_manager.m_children.back().mesh = child_mesh;
105 parent_mesh->m_multi_mesh_manager.m_children.back().map_handle = parent_to_child_handle;
106 parent_mesh->m_multi_mesh_manager
107 .m_has_child_mesh_in_dimension[child_mesh->top_cell_dimension()] = true;
108 parent_mesh->assert_capacity_valid();
109 child_mesh->assert_capacity_valid();
110 }
111
112#if !defined(NDEBUG)
113 for (auto& p : meshes) {
114 assert(p.first == p.second->m_multi_mesh_manager.absolute_id());
115 }
116#endif
117 }
118
119
120 return root;
121}
122
123std::shared_ptr<Mesh> HDF5Reader::read_mesh(h5pp::File& hdf5_file, const std::string& root_dataset)
124{
125 PrimitiveType top_simplex_type =
126 hdf5_file.readAttribute<PrimitiveType>(root_dataset, "top_simplex_type");
127
128 std::shared_ptr<Mesh> mesh;
129
130 switch (top_simplex_type) {
131 case PrimitiveType::Vertex: mesh = std::make_shared<PointMesh>(); break;
132 case PrimitiveType::Edge: mesh = std::make_shared<EdgeMesh>(); break;
133 case PrimitiveType::Triangle: mesh = std::make_shared<TriMesh>(); break;
134 case PrimitiveType::Tetrahedron: mesh = std::make_shared<TetMesh>(); break;
135 default: break;
136 }
137
138 std::vector<int64_t> capacities =
139 hdf5_file.readAttribute<std::vector<int64_t>>(root_dataset, "capacities");
140
141
142 mesh->set_capacities(capacities);
143
144
145 const auto dsets = hdf5_file.findDatasets("", root_dataset, -1, 1);
146 for (auto& s : dsets) {
147 const std::string dataset = root_dataset + "/" + s;
148
149
150 const int64_t stride = hdf5_file.readAttribute<int64_t>(dataset, "stride");
151 const int64_t dimension = hdf5_file.readAttribute<int64_t>(dataset, "dimension");
152 const std::string type = hdf5_file.readAttribute<std::string>(dataset, "type");
153 const std::string name =
154 std::regex_replace(s, std::regex(std::to_string(dimension) + "/"), "");
155
156 auto pt = PrimitiveType(dimension);
157
158 if (type == "int64_t") {
159 auto v = hdf5_file.readDataset<std::vector<int64_t>>(dataset);
160 const auto default_val = hdf5_file.readAttribute<int64_t>(dataset, "default_value");
161
162 set_attribute<int64_t>(default_val, name, pt, stride, v, *mesh);
163 } else if (type == "char") {
164 auto tmp = hdf5_file.readDataset<std::vector<short>>(dataset);
165 const auto default_val = char(hdf5_file.readAttribute<short>(dataset, "default_value"));
166
167 std::vector<char> v;
168 v.reserve(tmp.size());
169 for (auto val : tmp) v.push_back(char(val));
170
171
172 set_attribute<char>(default_val, name, pt, stride, v, *mesh);
173 } else if (type == "double") {
174 auto v = hdf5_file.readDataset<std::vector<double>>(dataset);
175 const auto default_val = hdf5_file.readAttribute<double>(dataset, "default_value");
176
177
178 set_attribute<double>(default_val, name, pt, stride, v, *mesh);
179 } else if (type == "rational") {
180 const Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> tmp =
181 hdf5_file.readDataset<
182 Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(dataset);
183 const Eigen::Matrix<char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> tmp_char =
184 tmp.cast<char>();
185
186 const std::string data = hdf5_file.readAttribute<std::string>(dataset, "default_value");
187 Rational default_val;
188 default_val.init_from_binary(data);
189
190 std::vector<Rational> v;
191 v.reserve(tmp.rows());
192 for (size_t i = 0; i < tmp.rows(); ++i) {
193 v.emplace_back(tmp_char.row(i));
194 }
195
196 set_attribute<Rational>(default_val, name, pt, stride, v, *mesh);
197
198 } else {
199 logger().error("We currently do not support reading the type \"{}\"", type);
200 assert(false);
201 }
202 }
203
204 return mesh;
205}
206
207template <typename T>
209 const T& default_val,
210 const std::string& name,
211 PrimitiveType pt,
212 int64_t stride,
213 const std::vector<T>& v,
214 Mesh& mesh)
215{
217 mesh.has_attribute<T>(name, pt)
218 ? mesh.get_attribute_handle<T>(name, pt)
219 : mesh.register_attribute<T>(name, pt, stride, false, default_val);
220 const attribute::TypedAttributeHandle<T>& thandle = handle.as<T>();
221
222 int64_t handle_dimension = mesh.get_attribute_dimension(thandle);
223 if (stride != handle_dimension) {
225 "Attribute does not have the expected dimension:\n expected {}\n actual {}",
226 stride,
227 handle_dimension);
228 }
229
230 auto accessor = attribute::AccessorBase<T>(mesh, thandle);
231
232 accessor.set_attribute(v);
233}
234
235
236} // namespace wmtk
void set_attribute(const T &default_val, const std::string &name, PrimitiveType pt, int64_t stride, const std::vector< T > &v, Mesh &mesh)
std::shared_ptr< Mesh > read(const std::filesystem::path &filename)
std::shared_ptr< Mesh > read_mesh(h5pp::File &hdf5_file, const std::string &dataset)
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
attribute::MeshAttributeHandle get_attribute_handle(const std::string &name, const PrimitiveType ptype) const
Definition Mesh.hpp:903
int64_t get_attribute_dimension(const TypedAttributeHandle< T > &handle) const
Definition Mesh.hpp:929
bool has_attribute(const std::string &name, const PrimitiveType ptype) const
Definition Mesh.hpp:923
void init_from_binary(const std::string &v)
Definition Rational.cpp:346
auto as() const -> const held_handle_type< held_type_from_primitive< T >()> &
Handle that represents attributes for some mesh.
static std::string parent_to_child_map_attribute_name(int64_t index)
static std::string child_to_parent_map_attribute_name()
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:58