NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
hdf5Reader.H
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #ifndef NEMOSYS_HDF5READER_H_
30 #define NEMOSYS_HDF5READER_H_
31 
32 #include <stdio.h>
33 #include <iostream>
34 #include <iterator>
35 #include <map>
36 #include <string>
37 #include <typeinfo>
38 #include <utility>
39 #include <vector>
40 
41 // vtk
42 #include <vtkCellTypes.h>
43 #include <vtkDataSet.h>
44 #include <vtkIdList.h>
45 #include <vtkPoints2D.h>
46 #include <vtkSmartPointer.h>
47 #include <vtkUnstructuredGrid.h>
48 
49 // HDF5
50 #include <H5Cpp.h>
51 #include <H5Exception.h>
52 #ifndef H5_NO_NAMESPACE
53 using namespace H5;
54 #endif
55 
56 class meshBase;
57 
58 /** @brief Class for reading data from HDF5 files
59  **/
60 class hdf5Reader {
61  public:
62  /** @brief Construct HDF5 reader object
63  @param fname HDF5 filename
64  @param _outputFName Filename for VTK output file
65  @param _verb Boolean verbosity flag
66  **/
67  hdf5Reader(std::string fname, std::string _outputFname, int _verb = 0)
68  : // Initialization of class variables
69  h5FileName(fname),
70  outputFname(_outputFname),
71  verb(_verb),
72  vtkMesh(0) {
73  // Parse filename
74  std::size_t _loc = h5FileName.find_last_of(".");
75  baseH5FileName = h5FileName.substr(0, _loc);
76  };
77 
78  // Destructor
79  virtual ~hdf5Reader(){};
80 
81  // File I/O
82  /** @brief Open HDF5 file
83  @return Integer flag: 0 (failure) or 1 (success)
84  **/
85  int openFile();
86 
87  // File I/O
88  /** @brief Close HDF5 file
89  @return Integer flag: 0 (failure) or 1 (success)
90  **/
91  int closeFile();
92 
93  // Read data
94  // Reading string data
95  // File I/O
96  /** @brief Read string data from top level HDF5 DataSet
97  @param dsetName Dataset name
98  @param buffer Buffer into which string data is read
99  @return Integer flag: 0 (failure) or 1 (success)
100  **/
101  int readTopDataSet(std::string dsetName, std::string &buffer);
102  /** @brief Read string data from generic HDF5 DataSet
103  @param dset HDF5 dataset
104  @param buffer Buffer into which data is read
105  @return Integer flag: 0 (failure) or 1 (success)
106  **/
107  int readDataSet(DataSet dset, std::string &buffer);
108  // Reading numeric data
109  /** @brief Read numeric data from top level HDF5 DataSet
110  @param dsetName Dataset name
111  @param buffer Buffer into which numeric data is read
112  @return Integer flag: 0 (failure) or 1 (success)
113  **/
114  template <class T>
115  int readTopDataSet(std::string dsetName, std::vector<T> &buffer) {
116  try {
117  std::cout << "H5_VERS_MAJOR = " << H5_VERS_MAJOR << std::endl;
118  std::cout << "H5_VERS_MINOR = " << H5_VERS_MINOR << std::endl;
119  std::cout << "H5_VERS_RELEASE = " << H5_VERS_RELEASE << std::endl;
120  std::cout << "H5_VERS_SUBRELEASE = " << H5_VERS_SUBRELEASE << std::endl;
121  // Open dataset
122  DataSet dset = file.openDataSet(dsetName);
123  readDataSet(dset, buffer);
124  }
125  // catch failure caused by the H5File operations
126  catch (FileIException error) {
127 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
128  error.printErrorStack();
129 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
130  error.printErrorStack();
131 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
132  error.printErrorStack();
133 #else
134  error.printError();
135 #endif
136  return -1;
137  }
138 
139  return 0;
140  }
141 
142  // Reading numeric data
143  /** @brief Read numeric data from generic HDF5 DataSet
144  @param dset HDF5 dataset
145  @param buffer Buffer into which numeric data is read
146  @return Integer flag: 0 (failure) or 1 (success)
147  **/
148  template <class T> int readDataSet(DataSet dset, std::vector<T> &buffer) {
149  try {
150  // Get type of data
151  DataType dtype = dset.getDataType();
152  // Read data
153  dset.read(&buffer[0], dtype);
154  // Close dataset
155  dset.close();
156  }
157  // catch failure caused by the H5File operations
158  catch (DataSetIException error) {
159 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
160  error.printErrorStack();
161 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
162  error.printErrorStack();
163 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
164  error.printErrorStack();
165 #else
166  error.printError();
167 #endif
168  return -1;
169  }
170 
171  return 0;
172  }
173 
174  // Read groups
175  /** @brief Read existing HDF5 Group
176  @param groupName HDF5 group object name
177  @param group HDF5 group object
178  @return Integer flag: 0 (failure) or 1 (success)
179  **/
180  int readGroup(std::string groupName, Group &group);
181 
182  // Reading numeric data from group
183  /** @brief Read numeric data from HDF5 group
184  @param dsetName DataSet name
185  @param group HDF5 group object
186  @param buffer Buffer into which numeric data is read
187  @return Integer flag: 0 (failure) or 1 (success)
188  **/
189  template <class T>
190  int readGroupDataSet(std::string dsetName, Group &group,
191  std::vector<T> &buffer) {
192  try {
193  // Open dataset
194  DataSet dset = group.openDataSet(dsetName);
195  // Get type of data
196  DataType dtype = dset.getDataType();
197  // Read data
198  dset.read(&buffer[0], dtype);
199  // Close dataset
200  dset.close();
201  }
202  // catch failure caused by the H5File operations
203  catch (GroupIException error) {
204 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
205  error.printErrorStack();
206 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
207  error.printErrorStack();
208 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
209  error.printErrorStack();
210 #else
211  error.printError();
212 #endif
213  return -1;
214  } catch (DataSetIException error) {
215 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
216  error.printErrorStack();
217 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
218  error.printErrorStack();
219 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
220  error.printErrorStack();
221 #else
222  error.printError();
223 #endif
224  return -1;
225  }
226 
227  return 0;
228  }
229 
230  // Getter functions
231  /** @brief Get HDF5 filename
232  @return HDF5 filename
233  **/
234  std::string getFileName();
235 
236  /** @brief Flatten 2d data buffer
237  @param originalBuffer Original unflattened data
238  @param flatBuffer Output flattened data
239  **/
240  template <class T>
241  void flattenBuffer2d(std::vector<std::vector<T>> originalBuffer,
242  std::vector<T> &flatBuffer) {
243  // Populate flat buffer
244  for (auto bufItr1 = originalBuffer.begin(); bufItr1 != originalBuffer.end();
245  bufItr1++) {
246  for (auto bufItr2 = (*bufItr1).begin(); bufItr2 != (*bufItr1).end();
247  bufItr2++) {
248  flatBuffer.push_back(*bufItr2);
249  }
250  }
251  }
252 
253  /** @brief Unflatten 2d data buffer
254  @param flatBuffer Original flattened data
255  @param originalBuffer Output unflattened data
256  **/
257  template <class T>
258  void unflattenBuffer2d(std::vector<T> flatBuffer,
259  std::vector<std::vector<T>> &originalBuffer) {
260  // Populate original buffer
261  auto flatItr = flatBuffer.begin();
262  for (auto bufItr1 = originalBuffer.begin(); bufItr1 != originalBuffer.end();
263  bufItr1++) {
264  for (auto bufItr2 = (*bufItr1).begin(); bufItr2 != (*bufItr1).end();
265  bufItr2++) {
266  *bufItr2 = *flatItr;
267  flatItr++;
268  }
269  }
270  }
271 
272  // General implementation for flattening of arbitrary type and dimension
273  // vector
274  // template <template<typename...> class R=std::vector,
275  // typename Top,
276  // typename Sub = typename Top::value_type>
277  // R<typename Sub::value_type> flattenBuffer(Top const& all)
278  //{
279  // using std::begin;
280  // using std::end;
281  //
282  // R<typename Sub::value_type> accum;
283  //
284  // for(auto& sub : all)
285  // std::copy(begin(sub), end(sub), std::inserter(accum, end(accum)));
286  //
287  // return accum;
288  //}
289 
290  // export to vtk format without going through madlib/gmsh (needed for
291  // simmetrix interface)
292  /** @brief Export to VTK format
293  **/
294  void exportToVTKMesh();
295  /** @brief Get VTK mesh object
296  @return Pointer to vtkDataSet
297  **/
298  vtkSmartPointer<vtkDataSet> getVTKMesh();
299  /** @brief Export HDF5 mesh to meshBase object
300  **/
301  void exportToMeshBase();
302  /** @brief Get meshBase object
303  @return meshBase object
304  **/
305  meshBase *getMeshBase();
306  /** @brief Write mesh to VTK file
307  **/
308  void writeVTK();
309 
310  // Setting meshBase fields
311  /** @brief Set meshBase field data
312  @param myMeshBase meshBase object
313  @param dataNames Vector of names of data fields
314  @param data Vector storing data
315  @param pointOrCell Boolean indicating point or cell data
316  **/
317  void setFields(meshBase *myMeshBase, std::vector<std::string> dataNames,
318  std::vector<std::vector<double>> data, int pointOrCell);
319 
320  // Setter functions
321  // Setting meshBase fields
322  /** @brief Set number of vertices in meshBase
323  @param numVertices Number of vertices
324  **/
325  void setNumberOfVertices(int numVertices);
326  /** @brief Set number of elements in meshBase
327  @param numElements Number of elements
328  **/
329  void setNumberOfElements(int numElements);
330  /** @brief Set number of spatial dimensions in meshBase
331  @param numDimensions Number of spatial dimensions
332  **/
333  void setNumberOfDimensions(int numDimensions);
334  /** @brief Set meshBase 1d coordinate data
335  @param xCrd vector of x-coordinates
336  **/
337  void setCoordinates(std::vector<double> xCrd);
338  /** @brief Set meshBase 2d coordinate data
339  @param xCrd vector of x-coordinates
340  @param yCrd vector of y-coordinates
341  **/
342  void setCoordinates(std::vector<double> xCrd, std::vector<double> yCrd);
343  /** @brief Set meshBase 3d coordinate data
344  @param xCrd vector of x-coordinates
345  @param yCrd vector of y-coordinates
346  @param zCrd vector of z-coordinates
347  **/
348  void setCoordinates(std::vector<double> xCrd, std::vector<double> yCrd,
349  std::vector<double> zCrd);
350  /** @brief Set meshBase element connectivity table
351  @param elementConnectivity Element connectivity table
352  **/
353  void setConnectivities(
354  std::vector<std::map<int, std::vector<int>>> elementConnectivity);
355  /** @brief Set VTK element types for each element
356  @param vtkElementTypes Vector of VTK element types for each element
357  **/
358  void setElementTypes(std::vector<int> vtkElementTypes);
359  /** @brief Set list of each unique type of VTK element in mesh
360  @param vtkElementTypesList Vector of each unique VTK element type in mesh
361  **/
362  void setElementTypesList(std::vector<int> vtkElementTypesList);
363 
364  /** @brief Get element connectivity for global element ID
365  @param elementId Element ID
366  @return Element connectivity table
367  **/
368  std::vector<int> getElementConnectivity(int elementId);
369 
370  protected:
371  // class variables
372  std::string h5FileName; /**< HDF5 filename */
373  std::string baseH5FileName; /**< base of HDF5 filename */
374  std::string outputFname; /**< VTK output filename */
375  int verb; /**< verbosity flag */
376  H5File file; /**< HDF5 file object */
377  vtkSmartPointer<vtkDataSet> vtkMesh; /**< VTK DataSet object */
378  meshBase *myMeshBase; /**< meshBase object */
379 
380  // mesh data
381  std::vector<double> xCrd, yCrd, zCrd; /**< vector of coordinates */
382  std::vector<std::map<int, std::vector<int>>>
383  elementConnectivity; /**< element connectivity table */
384  int numVertices; /**< number of vertices in mesh */
385  int numElements; /**< number of elements in mesh */
386  int numDimensions; /**< number of spatial dimensions */
387  std::vector<int>
388  vtkElementTypes; /**< vector of VTK element type for each element */
389  std::vector<int> vtkElementTypesList; /**< vector storing list of each unique
390  VTK element type */
391 };
392 
393 #endif // NEMOSYS_HDF5READER_H_
data_type data
Edge/face with sorted point ids (a, b, c, ...) is located at some index i in data[b], with data[b][i].first == [a, c] (for edges, third point id treated as -1).
H5File file
HDF5 file object.
Definition: hdf5Reader.H:376
std::string baseH5FileName
base of HDF5 filename
Definition: hdf5Reader.H:373
virtual ~hdf5Reader()
Definition: hdf5Reader.H:79
void unflattenBuffer2d(std::vector< T > flatBuffer, std::vector< std::vector< T >> &originalBuffer)
Unflatten 2d data buffer.
Definition: hdf5Reader.H:258
std::vector< int > vtkElementTypesList
vector storing list of each unique VTK element type
Definition: hdf5Reader.H:389
A brief description of meshBase.
Definition: meshBase.H:64
std::vector< std::map< int, std::vector< int > > > elementConnectivity
element connectivity table
Definition: hdf5Reader.H:383
int readDataSet(DataSet dset, std::vector< T > &buffer)
Read numeric data from generic HDF5 DataSet.
Definition: hdf5Reader.H:148
vtkSmartPointer< vtkDataSet > vtkMesh
VTK DataSet object.
Definition: hdf5Reader.H:377
int numVertices
number of vertices in mesh
Definition: hdf5Reader.H:384
hdf5Reader(std::string fname, std::string _outputFname, int _verb=0)
Construct HDF5 reader object.
Definition: hdf5Reader.H:67
void flattenBuffer2d(std::vector< std::vector< T >> originalBuffer, std::vector< T > &flatBuffer)
Flatten 2d data buffer.
Definition: hdf5Reader.H:241
int numDimensions
number of spatial dimensions
Definition: hdf5Reader.H:386
meshBase * myMeshBase
meshBase object
Definition: hdf5Reader.H:378
std::vector< double > zCrd
vector of coordinates
Definition: hdf5Reader.H:381
std::string h5FileName
HDF5 filename.
Definition: hdf5Reader.H:372
int readTopDataSet(std::string dsetName, std::vector< T > &buffer)
Read numeric data from top level HDF5 DataSet.
Definition: hdf5Reader.H:115
int numElements
number of elements in mesh
Definition: hdf5Reader.H:385
int verb
verbosity flag
Definition: hdf5Reader.H:375
std::string outputFname
VTK output filename.
Definition: hdf5Reader.H:374
int readGroupDataSet(std::string dsetName, Group &group, std::vector< T > &buffer)
Read numeric data from HDF5 group.
Definition: hdf5Reader.H:190
std::vector< int > vtkElementTypes
vector of VTK element type for each element
Definition: hdf5Reader.H:388
Class for reading data from HDF5 files.
Definition: hdf5Reader.H:60