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.C
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 #include "IO/hdf5Reader.H"
30 #include "Mesh/meshBase.H"
31 #include <string.h>
32 #include <algorithm>
33 #include <iostream>
34 
35 /********************************************
36  hdfReader class implementation
37 *********************************************/
38 
39 std::string hdf5Reader::getFileName() { return h5FileName; }
40 
42  std::cout << "Opening HDF5 file " << h5FileName << std::endl;
43 
44  try {
45  // Open HDF5 file
46  H5std_string h5FileName_(h5FileName);
47  file.openFile(h5FileName_, H5F_ACC_RDWR);
48  } catch (FileIException error) {
49 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
50  error.printErrorStack();
51 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
52  error.printErrorStack();
53 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
54  error.printErrorStack();
55 #else
56  error.printError();
57 #endif
58  return -1;
59  }
60  return 0;
61 }
62 
64  std::cout << "Closing HDF5 file " << h5FileName << std::endl;
65 
66  try {
67  // Close HDF5 file
68  file.close();
69  } catch (FileIException error) {
70 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
71  error.printErrorStack();
72 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
73  error.printErrorStack();
74 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
75  error.printErrorStack();
76 #else
77  error.printError();
78 #endif
79  return -1;
80  }
81  return 0;
82 }
83 
84 // Read string data
85 int hdf5Reader::readTopDataSet(std::string dsetName, std::string &buffer) {
86  try {
87  // Open dataset
88  DataSet dset = file.openDataSet(dsetName);
89  // Read dataset
90  readDataSet(dset, buffer);
91  }
92  // catch failure caused by the H5File operations
93  catch (FileIException error) {
94 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
95  error.printErrorStack();
96 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
97  error.printErrorStack();
98 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
99  error.printErrorStack();
100 #else
101  error.printError();
102 #endif
103  return -1;
104  }
105  return 0;
106 }
107 
108 // Read string data
109 int hdf5Reader::readDataSet(DataSet dset, std::string &buffer) {
110  try {
111  // Get type of data
112  DataType dtype = dset.getDataType();
113  // Read data
114  dset.read(buffer, dtype);
115  // Close dataset
116  dset.close();
117  }
118  // catch failure caused by the H5File operations
119  catch (DataSetIException error) {
120 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
121  error.printErrorStack();
122 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
123  error.printErrorStack();
124 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
125  error.printErrorStack();
126 #else
127  error.printError();
128 #endif
129  return -1;
130  }
131  return 0;
132 }
133 
134 // Read existing HDF5 Group
135 int hdf5Reader::readGroup(std::string groupName, Group &group) {
136  try {
137  // Open group
138  group = Group(file.openGroup(groupName));
139  } catch (FileIException error) {
140 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE >= 20
141  error.printErrorStack();
142 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 2
143  error.printErrorStack();
144 #elif H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 11 && H5_VERS_RELEASE >= 0
145  error.printErrorStack();
146 #else
147  error.printError();
148 #endif
149  return -1;
150  }
151  return 0;
152 }
153 
154 void hdf5Reader::setNumberOfVertices(int _numVertices) {
155  numVertices = _numVertices;
156 }
157 
158 void hdf5Reader::setNumberOfElements(int _numElements) {
159  numElements = _numElements;
160 }
161 
162 void hdf5Reader::setNumberOfDimensions(int _numDimensions) {
163  numDimensions = _numDimensions;
164 }
165 
166 void hdf5Reader::setCoordinates(std::vector<double> _xCrd) { xCrd = _xCrd; }
167 
168 void hdf5Reader::setCoordinates(std::vector<double> _xCrd,
169  std::vector<double> _yCrd) {
170  xCrd = _xCrd;
171  yCrd = _yCrd;
172 }
173 
174 void hdf5Reader::setCoordinates(std::vector<double> _xCrd,
175  std::vector<double> _yCrd,
176  std::vector<double> _zCrd) {
177  xCrd = _xCrd;
178  yCrd = _yCrd;
179  zCrd = _zCrd;
180 }
181 
182 void hdf5Reader::setElementTypes(std::vector<int> _vtkElementTypes) {
183  vtkElementTypes = _vtkElementTypes;
184 }
185 
186 void hdf5Reader::setElementTypesList(std::vector<int> _vtkElementTypesList) {
187  vtkElementTypesList = _vtkElementTypesList;
188 }
189 
191  std::vector<std::map<int, std::vector<int>>> _elementConnectivity) {
192  elementConnectivity = _elementConnectivity;
193 }
194 
195 std::vector<int> hdf5Reader::getElementConnectivity(int elementId) {
196  int nVerts;
197  int connId = -1;
198 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
199  if (vtkElementTypes[elementId] == VTK_LAGRANGE_QUADRILATERAL) {
200  nVerts = 16;
201  auto itr = std::find(vtkElementTypesList.begin(), vtkElementTypesList.end(),
202  VTK_LAGRANGE_QUADRILATERAL);
203  if (itr != vtkElementTypesList.end()) {
204  connId = distance(vtkElementTypesList.begin(), itr);
205  }
206  } else if (vtkElementTypes[elementId] == VTK_QUAD)
207 #else
208  if (vtkElementTypes[elementId] == VTK_QUAD)
209 #endif
210  {
211  nVerts = 4;
212  auto itr = std::find(vtkElementTypesList.begin(), vtkElementTypesList.end(),
213  VTK_QUAD);
214  if (itr != vtkElementTypesList.end()) {
215  connId = distance(vtkElementTypesList.begin(), itr);
216  }
217  } else if (vtkElementTypes[elementId] == VTK_TRIANGLE) {
218  nVerts = 3;
219  auto itr = std::find(vtkElementTypesList.begin(), vtkElementTypesList.end(),
220  VTK_TRIANGLE);
221  if (itr != vtkElementTypesList.end()) {
222  connId = distance(vtkElementTypesList.begin(), itr);
223  }
224  } else {
225  std::cerr << "Element type not supported: " << vtkElementTypes[elementId]
226  << std::endl;
227  exit(-1);
228  }
229  if (connId != -1) {
230  std::vector<int> subConnectivity(
231  elementConnectivity[connId][elementId].begin(),
232  elementConnectivity[connId][elementId].begin() + nVerts);
233  return subConnectivity;
234  } else {
235  std::cerr << "Element type " << vtkElementTypes[elementId]
236  << " not found in connectivity table" << std::endl;
237  exit(-1);
238  }
239 }
240 
242  std::cout << "Exporting hdf5Reader object to VTK format..." << std::endl;
243 
244  if (!vtkMesh) {
245  // declare vtk dataset
246  auto dataSet_tmp = vtkSmartPointer<vtkUnstructuredGrid>::New();
247 
248  // points to be pushed into dataSet
250  // set double precision points
251  points->SetDataTypeToDouble();
252 
253  // allocate size for vtk point container
254  points->SetNumberOfPoints(numVertices);
255 
256  if (numDimensions == 2) {
257  for (int i = 0; i < numVertices; ++i) {
258  points->SetPoint(i, xCrd[i], yCrd[i], 0.0);
259  }
260  } else {
261  for (int i = 0; i < numVertices; ++i) {
262  points->SetPoint(i, xCrd[i], yCrd[i], zCrd[i]);
263  }
264  }
265  // add points to vtk mesh data structure
266  std::cout << " setting VTK point data..." << std::endl;
267  dataSet_tmp->SetPoints(points);
268  // allocate space for elements
269  std::cout << " allocating memory for elements..." << std::endl;
270  dataSet_tmp->Allocate(numElements);
271  // add the elements
272  std::cout << " adding VTK elements..." << std::endl;
273  for (int i = 0; i < numElements; ++i) {
274  auto vtkElmIds = vtkSmartPointer<vtkIdList>::New();
275  std::vector<int> elmIds(getElementConnectivity(i));
276  vtkElmIds->SetNumberOfIds(elmIds.size());
277  for (int j = 0; j < elmIds.size(); ++j) {
278  vtkElmIds->SetId(j, elmIds[j] - 0);
279  }
280  switch (vtkElementTypes[i]) {
281 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
282  case VTK_LAGRANGE_QUADRILATERAL:
283  dataSet_tmp->InsertNextCell(VTK_LAGRANGE_QUADRILATERAL, vtkElmIds);
284  break;
285 #endif
286  case VTK_QUAD:
287  dataSet_tmp->InsertNextCell(VTK_QUAD, vtkElmIds);
288  break;
289  case VTK_TRIANGLE:
290  dataSet_tmp->InsertNextCell(VTK_TRIANGLE, vtkElmIds);
291  break;
292  default:
293  std::cerr << "Unknown element type " << vtkElementTypes[i]
294  << std::endl;
295  break;
296  }
297  }
298  // build links - element incidences
299  dataSet_tmp->BuildLinks();
300  vtkMesh = dataSet_tmp;
301  }
302 }
303 
304 vtkSmartPointer<vtkDataSet> hdf5Reader::getVTKMesh() {
305  if (vtkMesh)
306  return vtkMesh;
307  else {
308  exportToVTKMesh();
309  return vtkMesh;
310  }
311 }
312 
314  std::cout << "Exporting hdf5Reader object to meshBase format..." << std::endl;
315  if (!vtkMesh) {
316  exportToVTKMesh();
317  }
319 }
320 
322 
324  std::vector<std::string> dataNames,
325  std::vector<std::vector<double>> data,
326  int pointOrCell) {
327  if (pointOrCell == 0) {
328  std::cout << "Setting hdf5Reader object point fields..." << std::endl;
329  } else if (pointOrCell == 1) {
330  std::cout << "Setting hdf5Reader object cell fields..." << std::endl;
331  }
332 
333  // Set element data
334  auto dataNameItr = dataNames.begin();
335  auto dataItr = data.begin();
336  while (dataNameItr != dataNames.end() || dataItr != data.end()) {
337  std::cout << " " << *dataNameItr << std::endl;
338 
339  if (pointOrCell == 0) {
340  myMeshBase->setPointDataArray((*dataNameItr).c_str(), *dataItr);
341  } else if (pointOrCell == 1) {
342  myMeshBase->setCellDataArray((*dataNameItr).c_str(), *dataItr);
343  }
344 
345  if (dataNameItr != dataNames.end()) {
346  dataNameItr++;
347  }
348  if (dataItr != data.end()) {
349  dataItr++;
350  }
351  }
352 }
353 
355  std::cout << "Writing hdf5Reader object to VTK file" << std::endl;
356  if (!myMeshBase) {
358  }
359  myMeshBase->write();
360 }
void setNumberOfVertices(int numVertices)
Set number of vertices in meshBase.
Definition: hdf5Reader.C:154
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
vtkSmartPointer< vtkDataSet > getVTKMesh()
Get VTK mesh object.
Definition: hdf5Reader.C:304
void setElementTypesList(std::vector< int > vtkElementTypesList)
Set list of each unique type of VTK element in mesh.
Definition: hdf5Reader.C:186
virtual void setPointDataArray(const std::string &name, const std::vector< std::vector< double >> &data)
register data to dataSet&#39;s point data
Definition: meshBase.H:319
void writeVTK()
Write mesh to VTK file.
Definition: hdf5Reader.C:354
std::vector< int > vtkElementTypesList
vector storing list of each unique VTK element type
Definition: hdf5Reader.H:389
void setElementTypes(std::vector< int > vtkElementTypes)
Set VTK element types for each element.
Definition: hdf5Reader.C:182
A brief description of meshBase.
Definition: meshBase.H:64
void exportToVTKMesh()
Export to VTK format.
Definition: hdf5Reader.C:241
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
virtual void setCellDataArray(const std::string &name, const std::vector< std::vector< double >> &data)
register data to dataSet&#39;s cell data
Definition: meshBase.H:334
std::vector< std::map< int, std::vector< int > > > elementConnectivity
element connectivity table
Definition: hdf5Reader.H:383
std::vector< double > yCrd
Definition: hdf5Reader.H:381
int closeFile()
Close HDF5 file.
Definition: hdf5Reader.C:63
meshBase * getMeshBase()
Get meshBase object.
Definition: hdf5Reader.C:321
static meshBase * Create(const std::string &fname)
Construct vtkMesh from filename.
Definition: meshBase.C:78
int readGroup(std::string groupName, Group &group)
Read existing HDF5 Group.
Definition: hdf5Reader.C:135
std::vector< double > xCrd
Definition: hdf5Reader.H:381
std::string getFileName()
Get HDF5 filename.
Definition: hdf5Reader.C:39
void setConnectivities(std::vector< std::map< int, std::vector< int >>> elementConnectivity)
Set meshBase element connectivity table.
Definition: hdf5Reader.C:190
vtkSmartPointer< vtkDataSet > vtkMesh
VTK DataSet object.
Definition: hdf5Reader.H:377
int numVertices
number of vertices in mesh
Definition: hdf5Reader.H:384
virtual void write() const
write the mesh to file named after the private var &#39;filename&#39;.
Definition: meshBase.H:598
int readTopDataSet(std::string dsetName, std::string &buffer)
Read string data from top level HDF5 DataSet.
Definition: hdf5Reader.C:85
void setFields(meshBase *myMeshBase, std::vector< std::string > dataNames, std::vector< std::vector< double >> data, int pointOrCell)
Set meshBase field data.
Definition: hdf5Reader.C:323
std::vector< vtkIdType > points
points given by id in .inp file
Definition: inpGeoMesh.C:133
int numDimensions
number of spatial dimensions
Definition: hdf5Reader.H:386
void exportToMeshBase()
Export HDF5 mesh to meshBase object.
Definition: hdf5Reader.C:313
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
std::vector< int > getElementConnectivity(int elementId)
Get element connectivity for global element ID.
Definition: hdf5Reader.C:195
void setNumberOfDimensions(int numDimensions)
Set number of spatial dimensions in meshBase.
Definition: hdf5Reader.C:162
int numElements
number of elements in mesh
Definition: hdf5Reader.H:385
std::string outputFname
VTK output filename.
Definition: hdf5Reader.H:374
void setCoordinates(std::vector< double > xCrd)
Set meshBase 1d coordinate data.
Definition: hdf5Reader.C:166
std::vector< int > vtkElementTypes
vector of VTK element type for each element
Definition: hdf5Reader.H:388
void setNumberOfElements(int numElements)
Set number of elements in meshBase.
Definition: hdf5Reader.C:158
int openFile()
Open HDF5 file.
Definition: hdf5Reader.C:41
int readDataSet(DataSet dset, std::string &buffer)
Read string data from generic HDF5 DataSet.
Definition: hdf5Reader.C:109