OOFEM 3.0
Loading...
Searching...
No Matches
vtkhdf5reader.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "vtkhdf5reader.h"
37#include "elementgeometrytype.h"
38#include "floatarray.h"
39#include "element.h"
40#include "timestep.h"
41
42#ifdef __HDF_MODULE
43#include <H5Cpp.h>
44#endif
45
46namespace oofem {
47
48#ifndef __HDF_MODULE
50{
51 OOFEM_ERROR("VTKHDF5Reader: HDF5 module not available, cannot read VTKHDF5 files");
52}
53
54
59void VTKHDF5Reader::readField(UnstructuredGridField&, TimeStep* tStep, const std::string &field_name) {}
60
61#else
62
63
64VTKHDF5Reader::VTKHDF5Reader(): stepValues()
65{
66 this->fileName = "";
67 this->file = NULL;
68}
69
71 this->finalize();
72}
73
74void
75VTKHDF5Reader::initialize (std::string& filename)
76{
77 this->fileName = filename;
78 // open hdf5 file with fileName
79 this->file = new H5::H5File(fileName, H5F_ACC_RDONLY);
80 // open VTHHDF group
81 // test if VTKHDF group exists
82 if ( !file->exists("/VTKHDF") ) {
83 OOFEM_ERROR("VTKHDF group not found in file");
84 }
85 this->topGroup = new H5::Group(file->openGroup("/VTKHDF"));
86 // read version attribute in topGroup
87 H5::Attribute versionAttr = topGroup->openAttribute("Version");
88 int version[2];
89 versionAttr.read(versionAttr.getDataType(), &version);
90
91 // Read type attribute
92 H5::Attribute typeAttr = topGroup->openAttribute("Type");
93 std::string type;
94 typeAttr.read(typeAttr.getDataType(), type);
95
96 // check version and type
97 if (version[0] != 2 || version[1] != 2 || type != "UnstructuredGrid") {
98 OOFEM_ERROR("Unsupported version or type of VTKHDF5 file, version 2.2 and UnstructuredGrid type is required.");
99 }
100
101 // read NSteps attribute from Steps group
102 this->stepsGroup = new H5::Group(topGroup->openGroup("Steps"));
103 H5::Attribute nstepsattr = stepsGroup->openAttribute("NSteps");
104 nstepsattr.read(nstepsattr.getDataType(), &numSteps);
105 // read step values
106 H5::DataSet values = stepsGroup->openDataSet("Values");
107 hsize_t dim[1];
108 values.getSpace().getSimpleExtentDims(dim);
109 this->stepValues.resize(dim[0]);
110 values.read(this->stepValues.givePointer(), values.getDataType());
111}
112
114{
115 if ( this->file ) {
116 delete this->topGroup;
117 delete this->stepsGroup;
118 delete this->file;
119 this->file=NULL;
120 }
121}
122
123
124void VTKHDF5Reader::readDataSet (H5::DataSet& dset, int rank, hsize_t* dim, hsize_t* offset, H5::DataType type, void* data)
125{
126 H5::DataSpace dspace = dset.getSpace();
127 /* create hyperslab to update point data */
128 dspace.selectHyperslab( H5S_SELECT_SET, dim, offset );
129 H5::DataSpace mem_space(rank, dim, nullptr);
130 dset.read(data, type, mem_space, dspace );
131}
132
133void VTKHDF5Reader::getTimeStepOffsets(TimeStep* tStep, int& nParts, int& pOffset, int& pointOffset, int& cellOffset, int& connIdOffset, int& offsetOfOffset, int& nPoints, int &nCells, int& nconectivities) {
134 H5::IntType itype(H5::PredType::NATIVE_UINT);
135 H5::DataType dtype(H5::PredType::NATIVE_DOUBLE);
136
137 // find if tStep time present in array of stepValues, assuming stepValues is sorted
138 bool found = false;
139 double tt = tStep->giveTargetTime();
140 unsigned int indx = 0;
141 // simple serach for matching time; could be optimized to take advantage of sorted array
142 for (indx = 0; indx < stepValues.giveSize(); indx++) {
143 if (fabs(stepValues[indx] - tt) < 1.e-6) {
144 found = true;
145 break;
146 }
147 }
148 if (found) {
149 // tStep time is present in stepValues array
150 // read PointOffsets, CellOffsets, and ConnectivityIdOffsets arrays from Steps group
151 H5::DataSet npDSet = stepsGroup->openDataSet("NumberOfParts");
152 H5::DataSet poDSet = stepsGroup->openDataSet("PartOffsets");
153 H5::DataSet pointOffsetsDSet = stepsGroup->openDataSet("PointOffsets");
154 H5::DataSet cellOffsetsDSet = stepsGroup->openDataSet("CellOffsets");
155 H5::DataSet connIdOffsetsDSet = stepsGroup->openDataSet("ConnectivityIdOffsets");
156 H5::DataSet offsetsDSet = topGroup->openDataSet( "Offsets" );
157 // read the data with offset corresponding to tStep number
158 hsize_t offset[] = {indx};
159 hsize_t dims[1] = {1};
160 this->readDataSet(npDSet, 1, dims, offset, itype, &nParts);
161 this->readDataSet(poDSet, 1, dims, offset, itype, &pOffset);
162
163 this->readDataSet(pointOffsetsDSet, 1, dims, offset, itype, &pointOffset);
164 hsize_t dims11[] = {1,1};
165 hsize_t offset11[] = {indx,0};
166 this->readDataSet(cellOffsetsDSet, 2, dims11, offset11, itype, &cellOffset);
167 this->readDataSet(connIdOffsetsDSet, 2, dims11, offset11, itype, &connIdOffset);
168
169
170 // read NumberOfPoints and NumberOfCells and NumberOfConnectivityIds
171 H5::DataSet numberOfPointsDSet = topGroup->openDataSet("NumberOfPoints");
172 H5::DataSet numberOfCellsDSet = topGroup->openDataSet("NumberOfCells");
173 H5::DataSet numberOfConnectivityIds = topGroup->openDataSet("NumberOfConnectivityIds");
174
175 // read numberOfCellsDSet data
176 int stepCells[numSteps];
177 numberOfCellsDSet.read(stepCells, numberOfCellsDSet.getDataType());
178 // evaluate offset array offset
179 offsetOfOffset = 0;
180 for (int i = 0; i < indx; i++) {
181 offsetOfOffset += stepCells[i]+1;
182 }
183 nCells = stepCells[indx];
184
185 this->readDataSet(numberOfPointsDSet, 1, dims, offset, itype, &nPoints);
186 //this->readDataSet(numberOfCellsDSet, 1, dims, offset, itype, &nCells);
187 this->readDataSet(numberOfConnectivityIds, 1, dims, offset, itype, &nconectivities);
188
189 } else {
190 // tStep time is not present in stepValues array
191 OOFEM_ERROR("Matching time not found, time=%lf, step number %d", tt, tStep->giveNumber());
192 }
193}
194
196VTKHDF5Reader::giveElementGeometryType(int vtkCellType)
197{
198 Element_Geometry_Type elemGT = EGT_unknown;
199
200
201 // implement reverse mapping from vtkCellType to Element_Geometry_Type
202 if ( vtkCellType == 1 ) {
203 elemGT = EGT_point;
204 } else if ( vtkCellType == 3 ) {
205 elemGT = EGT_line_1;
206 } else if ( vtkCellType == 21 ) {
207 elemGT = EGT_line_2;
208 } else if ( vtkCellType == 5 ) {
209 elemGT = EGT_triangle_1;
210 } else if ( vtkCellType == 22 ) {
211 elemGT = EGT_triangle_2;
212 } else if ( vtkCellType == 10 ) {
213 elemGT = EGT_tetra_1;
214 } else if ( vtkCellType == 24 ) {
215 elemGT = EGT_tetra_2;
216 } else if ( vtkCellType == 9 ) {
217 elemGT = EGT_quad_1;
218 } else if ( vtkCellType == 30 ) {
219 elemGT = EGT_quad_21_interface;
220 } else if ( vtkCellType == 23 ) {
221 elemGT = EGT_quad_2;
222 } else if ( vtkCellType == 12 ) {
223 elemGT = EGT_hexa_1;
224 } else if ( vtkCellType == 25 ) {
225 elemGT = EGT_hexa_2;
226 } else if ( vtkCellType == 29 ) {
227 elemGT = EGT_hexa_27;
228 } else if ( vtkCellType == 13 ) {
229 elemGT = EGT_wedge_1;
230 } else if ( vtkCellType == 26 ) {
231 elemGT = EGT_wedge_2;
232 } else {
233 OOFEM_ERROR("unsupported vtk cell type %d", vtkCellType);
234 }
235 return elemGT;
236}
237
239{
240 int nParts, pOffset, pointOffset, cellOffset, connIdOffset, offsetOfOffset, nPoints, nCells, nconectivities;
241 this->getTimeStepOffsets (tStep, nParts, pOffset, pointOffset, cellOffset, connIdOffset, offsetOfOffset, nPoints, nCells, nconectivities);
242 H5::IntType itype(H5::PredType::NATIVE_UINT);
243 H5::DataType dtype(H5::PredType::NATIVE_DOUBLE);
244 H5::DataSet pointsDSet = topGroup->openDataSet( "Points" );
245 H5::DataSet typesDSet = topGroup->openDataSet( "Types" );
246 H5::DataSet connectivityDSet = topGroup->openDataSet( "Connectivity" );
247 H5::DataSet offsetsDSet = topGroup->openDataSet( "Offsets" );
248
249 // read points
250 hsize_t dim2[]={nPoints,3};
251 hsize_t offset2[] = {pointOffset, 0};
252 double *points = new double[dim2[0]*3];
253 this->readDataSet(pointsDSet, 2, dim2, offset2, dtype, points);
254
255 // read cell types
256 hsize_t dim1[1]={nCells};
257 hsize_t offset1[] = {cellOffset};
258 unsigned int *types = new unsigned int[dim1[0]];
259 this->readDataSet(typesDSet, 1, dim1, offset1, itype, types);
260
261 // read cell connectivity
262 dim1[0]=nconectivities;
263 offset1[0] = connIdOffset;
264 unsigned int *connectivity = new unsigned int[dim1[0]];
265 this->readDataSet(connectivityDSet, 1, dim1, offset1, itype, connectivity);
266
267 // read cell offsets
268 dim1[0]=nCells+1;
269 offset1[0] = offsetOfOffset;
270 unsigned int *offsets = new unsigned int[dim1[0]];
271 this->readDataSet(offsetsDSet, 1, dim1, offset1, itype, offsets);
272
273 // set up the field mesh
274 f.initialize(nPoints, nCells);
275 // define mesh points
276 for (int i = 0; i < nPoints; i++) {
277 FloatArray coords(3);
278 coords.at(1) = points[i*3];
279 coords.at(2) = points[i*3+1];
280 coords.at(3) = points[i*3+2];
281 f.addVertex(i+1, coords); //1-based
282 }
283
284 // define mesh elements
285 for (int i = 0; i < nCells; i++) {
286 int type = types[i];
287 int nNodes = offsets[i+1] - offsets[i];
288 IntArray nodes(nNodes);
289 for (int j = 0; j < nNodes; j++) {
290 nodes[j] = connectivity[offsets[i]+j]+1; // 1-based
291 }
292 f.addCell(i+1, this->giveElementGeometryType(type), nodes) ; //1-based
293 }
294
295 delete points;
296 delete types;
297 delete connectivity;
298 delete offsets;
299
300 return;
301}
302
303void VTKHDF5Reader::readField(UnstructuredGridField& field, TimeStep* tStep, const std::string &field_name)
304{
305 int nParts, pOffset, pointOffset, cellOffset, connIdOffset, offsetOfOffset, nPoints, nCells, nconectivities;
306 this->getTimeStepOffsets (tStep, nParts, pOffset, pointOffset, cellOffset, connIdOffset, offsetOfOffset, nPoints, nCells, nconectivities);
307 // open PointData group in topGroup
308 H5::Group* pointDataGroup = new H5::Group(topGroup->openGroup("PointData"));
309 // open field_name dataset in PointData group
310 if (pointDataGroup->nameExists(field_name.c_str())) {
311 H5::DataSet dSet = pointDataGroup->openDataSet(field_name.c_str());
312 int nPoints = field.giveNumberOfVertices();
313 // read field data
314 H5::DataType dtype(H5::PredType::NATIVE_DOUBLE);
315 hsize_t dim[2];
316 dSet.getSpace().getSimpleExtentDims(dim);
317 dim[0] = nPoints;
318 double *fieldData = new double[nPoints*dim[1]];
319 hsize_t offset2[] = {pointOffset, 0};
320 this->readDataSet(dSet, 2, dim, offset2, dtype, fieldData);
321
322 FloatArray valueArray((int)dim[1]);
323 for ( unsigned int inode = 0; inode < nPoints; inode++ ) {
324 for (unsigned int i=0; i<dim[1]; i++) {
325 valueArray(i) = fieldData[(inode)*dim[1]+i];
326 }
327 field.setVertexValue(inode+1, valueArray);
328 }
329 delete fieldData;
330
331 } else {
332 OOFEM_ERROR("Field %s not found in VTKHDF5 file", field_name.c_str());
333 }
334 delete pointDataGroup;
335 return;
336}
337
338#endif // __HDF_MODULE
339
340} // end namespace oofem
std::string fileName
File name.
void initialize(std::string &fileName)
VTKHDF5Reader()
Constructor. Creates empty Output Manager. By default all components are selected.
virtual ~VTKHDF5Reader()
Destructor.
void readMesh(UnstructuredGridField &, TimeStep *tStep)
void readField(UnstructuredGridField &, TimeStep *tStep, const std::string &field_name)
#define OOFEM_ERROR(...)
Definition error.h:79

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011