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.
proteusHdf5.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 /* Special purpose class for Proteus HDF5 files */
30 
31 #include "IO/proteusHdf5.H"
33 #include "Transfer/TransferBase.H"
34 #include "Drivers/TransferDriver.H"
35 
36 #include <stdio.h>
37 #include <string.h>
38 #include <vtkCell.h>
39 #include <vtkDataSet.h>
40 #include <vtkFeatureEdges.h>
41 #include <vtkIdList.h>
42 #include <vtkMath.h>
43 #include <vtkModelMetadata.h>
44 #include <vtkPointLocator.h>
45 #include <vtkPoints.h>
46 #include <vtkPolyData.h>
47 #include <vtkVersion.h>
48 
49 // MAdLib
50 #include <MAdLib.h>
51 #include <NodalDataManager.h>
52 
53 // GMsh
54 #include <gmsh/GModel.h>
55 
56 ///////////////////////////////////////////////////
57 // INITIALIZATION
58 ///////////////////////////////////////////////////
59 
60 proteusHdf5::proteusHdf5(std::string fname, std::string meshFname,
61  std::string edgeSidesetName, std::string exoMeshFName,
62  bool _lowOrder, bool bndryConst)
63  : hdf5Reader(fname, meshFname) {
64  // Set boolean determining whether to output higher order elements
65  // as lower order elements; useful for visualization
66  lowOrder = _lowOrder;
67 
68  // Open HDF5 file
69  openFile();
70 
71  // Get file system metadata
73  getVectorNames("ELEMENT_VECTOR_NAMES", elementVectorNames, numElementVectors);
74  getVectorNames("VERTEX_VECTOR_NAMES", vertexVectorNames, numVertexVectors);
75 
76  // Read in each block
77  getBlocks();
78 
79  // Merge block data
80  mergeBlocks();
81 
82  // Set HDF5 data
90 
91  // Export to VTK file
93 
94  // Export to MeshBase
96 
97  // Get VTK mesh
99 
100  // Add vertex data to meshBase
102 
103  // Add element data to meshBase
105 
106  // If mesh is 2d, get node ordering convention to follow when splitting cells
107  bool rhr;
108  // true = right-hand rule (projection of normal vector onto z-axis is +)
109  // false = left-hand rule (projection of normal vector onto z-axis is -)
110  if (getNumDimensions() == 2) {
111  std::cout << "Checking 2d cell node order" << std::endl;
113  if (rhr) {
114  std::cout << "2d node ordering right-hand rule: +z" << std::endl;
115  } else {
116  std::cout << "2d node ordering right-hand rule: -z" << std::endl;
117  }
118  }
119 
120  // Create a meshbase with quads removed (converted to tris)
121  std::cout << "Removing quad elements (converting to tris) for refinement"
122  << std::endl;
123  meshBase *myMeshBaseNoQuads = myMeshBase->convertQuads();
124 
125  // Check node ordering again after element conversion (all tris)
126  if (getNumDimensions() == 2) {
127  std::cout << "Checking 2d cell node order" << std::endl;
128  rhr = get2dCellNodeOrder(myMeshBaseNoQuads);
129  if (rhr) {
130  std::cout << "2d node ordering right-hand rule: +z" << std::endl;
131  } else {
132  std::cout << "2d node ordering right-hand rule: -z" << std::endl;
133  }
134  }
135 
136  std::cout << "Writing meshBase to file" << std::endl;
137  myMeshBase->write();
138 
139  // Transfer solution onto new mesh
140  std::cout << "Performing solution transfer" << std::endl;
141  // myMeshBase->transfer(myMeshBaseNoQuads, "Consistent Interpolation");
143  myMeshBase, myMeshBaseNoQuads, "Consistent Interpolation");
144  transfer->run();
145 
146  // debug
147  // myMeshBase->write();
148  // myGmshMeshBase->write();
149 
150  // Refine mesh
151  myMeshBaseNoQuads->refineMesh("uniform", 0.5, "refined.vtu", true,
152  bndryConst);
153 
154  // Read in refined mesh
155  meshBase *refinedMeshBase = meshBase::Create("refined.vtu");
156 
157  // Write refined mesh to file
158  myMeshBaseNoQuads->write();
159  // myGmshMeshNoQuads->write();
160 
161  // Write to file
162  // writeVTK();
163 
164  // Check node ordering again after refinement
165  if (getNumDimensions() == 2) {
166  std::cout << "Checking 2d cell node order" << std::endl;
167  rhr = get2dCellNodeOrder(refinedMeshBase);
168  if (rhr) {
169  std::cout << "2d node ordering right-hand rule: +z" << std::endl;
170  } else {
171  std::cout << "2d node ordering right-hand rule: -z" << std::endl;
172  }
173  }
174 
175  // Sideset implementation
176 
177  // Got coordinates for each boundary edge (two pts)
178  vtkSmartPointer<vtkPoints> startPts = vtkSmartPointer<vtkPoints>::New();
179  vtkSmartPointer<vtkPoints> endPts = vtkSmartPointer<vtkPoints>::New();
180  getBoundaryEdgePts(startPts, endPts);
181 
182  // Initialize lists for storing sideset quantities
183  vtkSmartPointer<vtkIdList> sidesetElementIdList =
185  vtkSmartPointer<vtkIdList> sidesetSideIdList =
187  // Find elements and sides in meshbase
188  // Create two arrays:
189  // -one with element ID for sideset cells
190  // -one with side ID for each sideset cell
191  getBoundarySideSets(refinedMeshBase, startPts, endPts, sidesetElementIdList,
192  sidesetSideIdList);
193 
194  // Setting meshbase metadata
195  // Set meshbase sideset metadata
196  vtkSmartPointer<vtkModelMetadata> sidesetData =
198  vtkSmartPointer<vtkStringArray> sidesetNames =
200  // currently supports one sideset
201  sidesetNames->InsertNextValue(edgeSidesetName);
202  sidesetData->SetSideSetNames(sidesetNames);
203 
204  // Convert sideset lists into int*
205  std::vector<int> _sidesetElementIdList;
206  for (int iId = 0; iId < sidesetElementIdList->GetNumberOfIds(); iId++) {
207  _sidesetElementIdList.push_back(sidesetElementIdList->GetId(iId));
208  }
209 
210  std::vector<int> _sidesetSideIdList;
211  for (int iId = 0; iId < sidesetSideIdList->GetNumberOfIds(); iId++) {
212  _sidesetSideIdList.push_back(sidesetSideIdList->GetId(iId));
213  }
214 
215  // Set sidesets to meshbase
216  sidesetData->SetSideSetElementList(_sidesetElementIdList.data());
217  sidesetData->SetSideSetSideList(_sidesetSideIdList.data());
218  int sidesetSizes[1] = {
219  static_cast<int>(sidesetElementIdList->GetNumberOfIds())};
220 
221  sidesetData->SetSideSetSize(sidesetSizes);
222  sidesetData->SetNumberOfSideSets(1);
223  refinedMeshBase->setMetadata(sidesetData);
224 
225  refinedMeshBase->write();
226 
227  std::vector<meshBase *> mbVec;
228  mbVec.push_back(refinedMeshBase);
229  std::string exoName = exoMeshFName;
230 
231  NEM::DRV::ConversionDriver::genExo(mbVec, exoName);
232 
233  // Close HDF5 file
234  closeFile();
235 }
236 
238 
240  std::cout << "Reading in PROTEUS control data..." << std::endl;
241 
242  // Set control buffer information
243  H5std_string dsetName("CONTROL");
244  int bufSize = 5;
245  std::vector<int> buffer(bufSize, 0);
246 
247  // Read dataset
248  readTopDataSet(dsetName, buffer);
249 
250  // Set control data
251  numBlocks = buffer[0];
252  numDimensions = buffer[1];
253  numVertexVectors = buffer[2];
254  numElementVectors = buffer[3];
255  charStringLength = buffer[4];
256 
257  // Output to info to screen
258  std::cout << " Number of Blocks: " << numBlocks << std::endl;
259  std::cout << " Number of Dimensions: " << numDimensions << std::endl;
260  std::cout << " Number of Vertex Vectors: " << numVertexVectors << std::endl;
261  std::cout << " Number of Element Vectors: " << numElementVectors
262  << std::endl;
263  std::cout << " Length of Character String: " << charStringLength
264  << std::endl;
265 }
266 
267 void proteusHdf5::getVectorNames(std::string name,
268  std::vector<std::string> &stringVector,
269  int numVectors) {
270  std::cout << "Reading in PROTEUS " << name << "..." << std::endl;
271 
272  // Set vector buffer information
273  H5std_string dsetName(name);
274  std::string buffer;
275 
276  // Read dataset
277  readTopDataSet(dsetName, buffer);
278 
279  // Set element vector names
280  int bufSize = numVectors * charStringLength;
281  std::string tmp = "";
282  std::string buf = "";
283  int iCharCnt = 0;
284  int iChar = 0;
285  while (iChar <= bufSize) {
286  buf = "";
287  buf += buffer[iChar];
288  if (!(iCharCnt < charStringLength)) {
289  stringVector.push_back(std::string(tmp));
290  tmp = "";
291  iCharCnt = 0;
292  }
293  if (buf.compare(" ") != 0) {
294  tmp += buffer[iChar];
295  }
296  iChar++;
297  iCharCnt++;
298  }
299 
300  // Output info to screen
301  std::cout << "Found " << name << ":" << std::endl;
302  for (auto nameItr = stringVector.begin(); nameItr != stringVector.end();
303  nameItr++) {
304  std::cout << " " << *nameItr << std::endl;
305  }
306 }
307 
309  std::cout << "Reading in PROTEUS block data..." << std::endl;
310 
311  for (int iBlock = 0; iBlock < numBlocks; iBlock++) {
312  // Set PROTEUS convention block name
313  std::string blockName = "BLOCK";
314  std::string numStr = std::to_string(iBlock + 1); // Proteus blocks 1-indexed
315  while (numStr.length() < 12) {
316  numStr.insert(0, "0");
317  }
318  blockName += numStr;
319  std::cout << "Reading in " + blockName + "..." << std::endl;
320 
321  // Create HDF5 Group object for block
322  Group group;
323  readGroup(blockName, group);
324 
325  // Create block object
326  proteusBlock myBlock = proteusBlock();
327  myBlock.blockName = blockName;
328 
329  // Read block info
330  getBlockInfo(group, myBlock);
331 
332  // Read coordinates
333  getBlockXYZ(group, myBlock);
334 
335  // Read global IDs
336  getBlockGlobalID(group, myBlock);
337 
338  // Read element data
339  getBlockElementData(group, myBlock);
340 
341  // Read vertex data
342  getBlockVertexData(group, myBlock);
343 
344  // Push back proteus block into data structure
345  proteusBlocks.push_back(myBlock);
346  }
347 
348  std::cout << "Finished reading PROTEUS block data..." << std::endl;
349 }
350 
352  std::cout << "Merging PROTEUS block data..." << std::endl;
353 
354  // Determine total number of vertices based on maximum global ID
355  int numGlobalVertices = 0;
356 
357  // Determine total number of elements
358  int numGlobalElements = 0;
359  int maxNumVerticesPerElement = 0;
360 
361  // Determine number of element types
362  std::vector<int> elementTypesList;
363  std::vector<int> originalElementTypesList;
364 
365  for (auto blockItr = proteusBlocks.begin(); blockItr != proteusBlocks.end();
366  blockItr++) {
367  // Get number of global vertex Ids
368  int localMaxVertexId = *std::max_element((*blockItr).loc2Glob.begin(),
369  (*blockItr).loc2Glob.end());
370  if (localMaxVertexId > numGlobalVertices) {
371  numGlobalVertices = localMaxVertexId;
372  }
373 
374  // Accumulate number of global element Ids
375  numGlobalElements += (*blockItr).numElements;
376 
377  // Get maximum number of vertices per element
378  if ((*blockItr).numVerticesPerElement > maxNumVerticesPerElement) {
379  maxNumVerticesPerElement = (*blockItr).numVerticesPerElement;
380  }
381 
382  if (std::find(originalElementTypesList.begin(),
383  originalElementTypesList.end(),
384  (*blockItr).originalVtkElementType) ==
385  originalElementTypesList.end()) {
386  originalElementTypesList.push_back((*blockItr).originalVtkElementType);
387  elementTypesList.push_back((*blockItr).vtkElementType);
388  }
389  }
390  numGlobalVertices++; // global vertices are 0-indexed, so total number is
391  // maxID+1
392 
393  // Set superblock info
394  mySuperBlock.numVertices = numGlobalVertices;
395  mySuperBlock.numElements = numGlobalElements;
396  mySuperBlock.maxNumVerticesPerElement = maxNumVerticesPerElement;
397 
398  std::cout << " Found " << numGlobalVertices << " global vertices"
399  << std::endl;
400  std::cout << " Found " << numGlobalElements << " global elements"
401  << std::endl;
402 
403  // Vector to store global vertices
404  std::vector<std::vector<double>> coordinates(
405  numGlobalVertices, std::vector<double>(numDimensions, 0.0));
406 
407  // Vector to store global elements
408  std::vector<std::vector<int>> elements(
409  numGlobalElements, std::vector<int>(maxNumVerticesPerElement, 0));
410 
411  // Map of element to VTK element type
412  std::vector<int> elementTypes(numGlobalElements);
413 
414  // Vector to store vertex data
415  std::vector<std::vector<double>> vertexData(
416  numVertexVectors, std::vector<double>(numGlobalVertices, 0.0));
417 
418  // Vector to store element data
419  std::vector<std::vector<double>> elementData(
420  numElementVectors, std::vector<double>(numGlobalElements, 0.0));
421 
422  // Instantiate variables for loops below
423  int locVertId, globElemId, locElemId;
424  int lId, gId, vertNo, dimNo, origId;
425  globElemId = 0;
426 
427  // Loop over blocks
428  std::cout << " Accumulating mesh information from each block..."
429  << std::endl;
430  for (auto blockItr = proteusBlocks.begin(); blockItr != proteusBlocks.end();
431  blockItr++) {
432  std::cout << " " << (*blockItr).blockName << ":" << std::endl;
433  locVertId = 0;
434  locElemId = 0;
435  // Loop over element coordinates
436  for (auto elemItr = (*blockItr).vertices.begin();
437  elemItr != (*blockItr).vertices.end(); elemItr++) {
438  // Loop over dimension coordinates
439  origId = locVertId;
440  for (auto dimItr = (*elemItr).begin(); dimItr != (*elemItr).end();
441  dimItr++) {
442  locVertId = origId;
443  dimNo = distance((*elemItr).begin(), dimItr);
444  // Loop over vertex coordinates
445  for (auto vertItr = (*dimItr).begin(); vertItr != (*dimItr).end();
446  vertItr++) {
447  vertNo = distance((*dimItr).begin(), vertItr);
448  elements[globElemId][vertNo] = (*blockItr).loc2Glob[locVertId];
449  coordinates[(*blockItr).loc2Glob[locVertId]][dimNo] = *vertItr;
450  locVertId++;
451  }
452  elementTypes[globElemId] = (*blockItr).vtkElementType;
453  }
454 
455  // Accumulate element field data
456  for (int iElemData = 0; iElemData < numElementVectors; iElemData++) {
457  elementData[iElemData][globElemId] =
458  (*blockItr).elementData[iElemData][locElemId];
459  }
460 
461  locElemId++;
462  globElemId++;
463  }
464 
465  // Loop over vertices
466  for (auto vertItr = (*blockItr).loc2Glob.begin();
467  vertItr != (*blockItr).loc2Glob.end(); vertItr++) {
468  lId = distance((*blockItr).loc2Glob.begin(), vertItr);
469  gId = *vertItr;
470  for (int iVertData = 0; iVertData < numVertexVectors; iVertData++) {
471  vertexData[iVertData][gId] = (*blockItr).vertexData[iVertData][lId];
472  }
473  }
474 
475  std::cout << " " << (*blockItr).vertices.size() << " vertices"
476  << std::endl;
477  std::cout << " " << (*blockItr).numElements << " elements"
478  << std::endl;
479  std::cout << " " << numVertexVectors << " vertex fields"
480  << std::endl;
481  std::cout << " " << numElementVectors << " element fields"
482  << std::endl;
483  }
484 
485  // Re-structure data into separate x,y,z coordinates (todo: could be done in
486  // loops above)
487  std::cout << " Separating coordinate arrays into individual dimension "
488  "arrays..."
489  << std::endl;
490  for (auto vertItr = coordinates.begin(); vertItr != coordinates.end();
491  vertItr++) {
492  mySuperBlock.xCrd.push_back((*vertItr)[0]);
493  if (numDimensions > 1) {
494  mySuperBlock.yCrd.push_back((*vertItr)[1]);
495  }
496  if (numDimensions > 2) {
497  mySuperBlock.zCrd.push_back((*vertItr)[2]);
498  }
499  }
500 
501  // Convert element connectivity information into a format that is easier to
502  // parse for hdf5Reader class. (todo: chould be done in loops above) Main
503  // structure shown below: elementConnectivity[element type no][global
504  // element id][vertex no] = [global vertex id] elementTypesList[element type
505  // no] = vtk element type integer
506  std::cout << " Sorting element connectivities by element type..."
507  << std::endl;
508  std::vector<std::map<int, std::vector<int>>> elementConnectivity;
509 
510  // Loop over original element type list (contains all element types read in
511  // across all blocks)
512  auto origTypeItr = originalElementTypesList.begin();
513  while (origTypeItr != originalElementTypesList.end()) {
514  // temporary map for storing connectivity for each element type
515  std::map<int, std::vector<int>> tmpElementConnectivity;
516 
517  int vertNum, elemId;
518  // Loop over elements and their types
519  auto elemItr = elements.begin();
520  auto elemTypeItr = elementTypes.begin();
521  while (elemItr != elements.end() || elemTypeItr != elementTypes.end()) {
522  // Get global element id
523  elemId = distance(elements.begin(), elemItr);
524  // Loop over all vertices of each element
525  for (auto vertItr = (*elemItr).begin(); vertItr != (*elemItr).end();
526  vertItr++) {
527  // Get vertex number
528  vertNum = distance((*elemItr).begin(), vertItr);
529  // Check element type against each supported type
530  if (*elemTypeItr == VTK_QUAD) {
531 // Remove extra vertices from high-order Lagrange quads if output
532 // to lower-order quad is desired
533 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
534  if (*origTypeItr == VTK_LAGRANGE_QUADRILATERAL) {
535  if (vertNum == 0 || vertNum == 3 || vertNum == 12 ||
536  vertNum == 15) {
537  tmpElementConnectivity[elemId].push_back(*vertItr);
538  }
539  } else {
540  tmpElementConnectivity[elemId].push_back(*vertItr);
541  }
542 #else
543  if (*origTypeItr == -1) // lower VTK versions don't have
544  // LAGRANGE_QUADRILATERAL types
545  {
546  if (vertNum == 0 || vertNum == 3 || vertNum == 12 ||
547  vertNum == 15) {
548  tmpElementConnectivity[elemId].push_back(*vertItr);
549  }
550  } else {
551  tmpElementConnectivity[elemId].push_back(*vertItr);
552  }
553 #endif
554  }
555 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
556  else if (*elemTypeItr == VTK_LAGRANGE_QUADRILATERAL) {
557  tmpElementConnectivity[elemId].push_back(*vertItr);
558  }
559 #endif
560  else if (*elemTypeItr == VTK_TRIANGLE) {
561  tmpElementConnectivity[elemId].push_back(*vertItr);
562  }
563  }
564 
565  // Increment element and element type iterators
566  if (elemItr != elements.end()) {
567  ++elemItr;
568  }
569  if (elemTypeItr != elementTypes.end()) {
570  ++elemTypeItr;
571  }
572  }
573 
574  // Push back each inidividual element type connectivity
575  // into vector containing all types
576  elementConnectivity.push_back(tmpElementConnectivity);
577 
578  if (origTypeItr != originalElementTypesList.end()) {
579  ++origTypeItr;
580  }
581  }
582 
583  // Re-order vertices per VTK convention
584  std::cout << " Re-ordering element vertices per VTK convention..."
585  << std::endl;
586  int vertCount;
587  int swapVert1 = -1, swapVert2 = -1;
588  int connId;
589  // If VTK_QUAD, re-order vertices
590  auto testIt =
591  std::find(elementTypesList.begin(), elementTypesList.end(), VTK_QUAD);
592  if (testIt != elementTypesList.end()) {
593  std::cout << " Re-ordering VTK_QUAD element vertices..."
594  << std::endl;
595  connId = distance(elementTypesList.begin(), testIt);
596  for (auto elemIt = elementConnectivity[connId].begin();
597  elemIt != elementConnectivity[connId].end(); elemIt++) {
598  vertCount = 0;
599  for (int i = 0; i < (elemIt->second).size(); i++) {
600  if (vertCount == 2) {
601  swapVert1 = (elemIt->second)[i];
602  }
603  if (vertCount == 3) {
604  swapVert2 = (elemIt->second)[i];
605  (elemIt->second)[i] = swapVert1;
606  (elemIt->second)[i - 1] = swapVert2;
607  vertCount = -1;
608  }
609  vertCount++;
610  }
611  }
612  }
613  // If VTK_TRI, re-order vertices
614  /*
615  testIt = std::find(elementTypesList.begin(), elementTypesList.end(),
616  VTK_TRIANGLE); if (testIt != elementTypesList.end())
617  {
618  std::cout << " Re-ordering VTK_TRIANGLE element vertices..." <<
619  std::endl; connId = distance(elementTypesList.begin(), testIt); for (auto
620  elemIt = elementConnectivity[connId].begin(); elemIt !=
621  elementConnectivity[connId].end(); elemIt++)
622  {
623  vertCount = 0;
624  for (int i = 0; i < (elemIt->second).size(); i++)
625  {
626  if (vertCount == 1)
627  {
628  swapVert1 = (elemIt->second)[i];
629  }
630  if (vertCount == 2)
631  {
632  swapVert2 = (elemIt->second)[i];
633  (elemIt->second)[i] = swapVert1;
634  (elemIt->second)[i-1] = swapVert2;
635  vertCount = -1;
636  }
637  vertCount++;
638  }
639  }
640  }
641  */
642 
643  // Set data in superBlock struct
644  std::cout << " Setting mesh data in PROTEUS superblock..." << std::endl;
645  mySuperBlock.coordinates = coordinates;
646  mySuperBlock.elements = elements;
647  mySuperBlock.vertexData = vertexData;
648  mySuperBlock.elementData = elementData;
650  mySuperBlock.elementTypesList = elementTypesList;
651  mySuperBlock.originalElementTypesList = originalElementTypesList;
652  mySuperBlock.elementTypes = elementTypes;
653 
654  std::cout << "Finished merging PROTEUS block data..." << std::endl;
655 }
656 
657 void proteusHdf5::getBlockInfo(Group &group, proteusBlock &myBlock) {
658  int bufSize = 3;
659  std::vector<int> buffer(bufSize, 0);
660  readGroupDataSet("INFO", group, buffer);
661 
662  std::vector<int> tmpVec;
663  for (int iBuf = 0; iBuf < bufSize; iBuf++) {
664  tmpVec.push_back(buffer[iBuf]);
665  }
666  myBlock.numElements = tmpVec[0];
667  myBlock.numVerticesPerElement = tmpVec[1];
668 
669  // parse element type
670  // Note: the element ID numbers below don't match up with the PROTEUS
671  // documentation, but have been implemented based on PROTEUS HDF5 test files
672  // provided
673  if (tmpVec[2] == 162) {
674  if (lowOrder) {
675 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
676  myBlock.originalVtkElementType = VTK_LAGRANGE_QUADRILATERAL;
677 #else
678  myBlock.originalVtkElementType = -1; // older VTK versions don't support
679  // LAGRANGE_QUADRILATERAL types
680 #endif
681  myBlock.vtkElementType = VTK_QUAD;
682  } else {
683 #if VTK_MAJOR_VERSION > 8 || (VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 1)
684  myBlock.originalVtkElementType = VTK_LAGRANGE_QUADRILATERAL;
685  myBlock.vtkElementType = VTK_LAGRANGE_QUADRILATERAL;
686 #else
687  myBlock.originalVtkElementType = VTK_QUAD;
688  myBlock.vtkElementType = VTK_QUAD;
689  std::cout << "Warning: VTK version " << vtkVersion::GetVTKSourceVersion()
690  << " does not support Lagrange Quadrilateral cells."
691  << std::endl;
692 #endif
693  }
694  } else if (tmpVec[2] == 160) {
695  myBlock.originalVtkElementType = VTK_QUAD;
696  myBlock.vtkElementType = VTK_QUAD;
697  }
698  // else if (tmpVec[2] == 110)
699  // It looks like some of the triangle elements in Proteus test files have an
700  // element type of 101 instead of 110, as documented in the user manual. I
701  // have just added this as an additional element type to catch this.
702  else if (tmpVec[2] == 110) {
703  myBlock.originalVtkElementType = VTK_TRIANGLE;
704  myBlock.vtkElementType = VTK_TRIANGLE;
705  } else {
706  std::cerr << "Element type not supported: " << tmpVec[2] << std::endl;
707  exit(-1);
708  }
709 
710  // Output info to screen
711  std::cout << " Info:" << std::endl;
712  std::cout << " Number of elements: " << tmpVec[0] << std::endl;
713  std::cout << " Number of vertices per element: "
714  << myBlock.numVerticesPerElement << std::endl;
715  std::cout << " VTK element type: " << myBlock.vtkElementType
716  << std::endl;
717 }
718 
719 void proteusHdf5::getBlockXYZ(Group &group, proteusBlock &myBlock) {
720  // Define xyz buffer
721  int bufSize =
722  numDimensions * myBlock.numElements * myBlock.numVerticesPerElement;
723  std::vector<float> buffer(bufSize, 0);
724 
725  // Read dataset from group
726  readGroupDataSet("XYZ", group, buffer);
727 
728  // Output info to screen
729  std::cout << " Coordinate info:" << std::endl;
730  std::cout << " Read in " << bufSize << " vertex coordinates"
731  << std::endl;
732  for (int iDim = 0; iDim < numDimensions; iDim++) {
733  std::cout << " " << myBlock.numElements * myBlock.numVerticesPerElement
734  << " in dimension " << iDim << std::endl;
735  }
736 
737  // Convert vertex coordinates into an un-flattened array using row-major
738  // ordering
739  std::vector<std::vector<std::vector<double>>> tmpVec(
740  myBlock.numElements,
741  std::vector<std::vector<double>>(
742  numDimensions,
743  std::vector<double>(myBlock.numVerticesPerElement, 0.0)));
744  int tmpInd = 0;
745  for (int iElem = 0; iElem < myBlock.numElements; iElem++) {
746  for (int iDim = 0; iDim < numDimensions; iDim++) {
747  for (int iVert = 0; iVert < myBlock.numVerticesPerElement; iVert++) {
748  tmpVec[iElem][iDim][iVert] = double(buffer[tmpInd]);
749  tmpInd++;
750  }
751  }
752  }
753 
754  // Assign vertex coordinates to block
755  myBlock.vertices = tmpVec;
756 }
757 
758 void proteusHdf5::getBlockGlobalID(Group &group, proteusBlock &myBlock) {
759  // Define GlobalID buffer
760  int bufSize = myBlock.numElements * myBlock.numVerticesPerElement;
761  std::vector<int> buffer(bufSize, 0);
762 
763  // Read dataset from group
764  readGroupDataSet("GLOBALID", group, buffer);
765 
766  // Output info to screen
767  std::cout << " Global ID info:" << std::endl;
768  std::cout << " Read in "
769  << myBlock.numElements * myBlock.numVerticesPerElement
770  << " global IDs" << std::endl;
771 
772  // Create a map from local to global ID
773  std::vector<int> tmpVec;
774  for (int iBuf = 0; iBuf < bufSize; iBuf++) {
775  tmpVec.push_back(buffer[iBuf]);
776  }
777 
778  // Assign local to global ID map to block
779  myBlock.loc2Glob = tmpVec;
780 }
781 
782 void proteusHdf5::getBlockElementData(Group &group, proteusBlock &myBlock) {
783  // Define GlobalID buffer
784  int bufDim1 = numElementVectors;
785  int bufDim2 = myBlock.numElements;
786  int bufDimFlat = bufDim1 * bufDim2;
787 
788  // Buffer for HDF read (float)
789  std::vector<float> flatBuffer(bufDimFlat, 0.0);
790 
791  // Buffer for proteusHDF5 object (2d double)
792  std::vector<std::vector<double>> buffer(bufDim1,
793  std::vector<double>(bufDim2, 0.0));
794 
795  // Read dataset from group
796  readGroupDataSet("ELEMENTDATA", group, flatBuffer);
797 
798  // Convert to double
799  std::vector<double> doubleFlatBuffer(flatBuffer.begin(), flatBuffer.end());
800 
801  // Unflatten buffer to 2d
802  unflattenBuffer2d(doubleFlatBuffer, buffer);
803  // Todo: Make this a generic templated function like flattenBuffer() above
804  // auto resizedBuffer = unflattenBuffer(flatBuffer);
805 
806  // Output info to screen
807  std::cout << " Element Data info:" << std::endl;
808  std::cout << " Read in " << numElementVectors
809  << " element data:" << std::endl;
810  for (auto edItr = elementVectorNames.begin();
811  edItr != elementVectorNames.end(); edItr++) {
812  std::cout << " " << *edItr << std::endl;
813  }
814 
815  // Assign element data to block
816  myBlock.elementData = buffer;
817 }
818 
819 void proteusHdf5::getBlockVertexData(Group &group, proteusBlock &myBlock) {
820  // Define GlobalID buffer
821  int bufDim1 = numVertexVectors;
822  int bufDim2 = myBlock.numElements * myBlock.numVerticesPerElement;
823  int bufDimFlat = bufDim1 * bufDim2;
824 
825  // Buffer for HDF read (float)
826  std::vector<float> flatBuffer(bufDimFlat, 0.0);
827 
828  // Buffer for proteusHDF5 object (2d double)
829  std::vector<std::vector<double>> buffer(bufDim1,
830  std::vector<double>(bufDim2, 0.0));
831 
832  // Read dataset from group
833  readGroupDataSet("VERTEXDATA", group, flatBuffer);
834 
835  // Convert to double
836  std::vector<double> doubleFlatBuffer(flatBuffer.begin(), flatBuffer.end());
837 
838  // Unflatten buffer to 2d
839  unflattenBuffer2d(doubleFlatBuffer, buffer);
840 
841  // Output info to screen
842  std::cout << " Vertex Data info:" << std::endl;
843  std::cout << " Read in " << numVertexVectors
844  << " vertex data:" << std::endl;
845  for (auto vdItr = vertexVectorNames.begin(); vdItr != vertexVectorNames.end();
846  vdItr++) {
847  std::cout << " " << *vdItr << std::endl;
848  }
849 
850  // Assign vertex data to block
851  myBlock.vertexData = buffer;
852 }
853 
854 // unused function for writing boundary condition information to json file
855 /*
856 void proteusHdf5::writeBcFile(meshBase* myMeshBase, std::string
857 edgeSidesetName)
858 {
859  if (numDimensions != 2)
860  {
861  std::cerr << "Error: Sidesets only supports for 2D meshes" << std::endl;
862  exit(-1);
863  }
864 
865  // Construct json data
866  json outJson;
867  outJson["Operation"] = "Boundary Condition Assignment";
868  outJson["Input Mesh"] = "refined.msh";
869 
870  json condJson;
871  condJson["Name"] = "side_set_0000001";
872  condJson["Boundary Type"] = "Edges";
873  condJson["Condition Type"] = "Fixed";
874 
875  json startArray = json::array();
876  json endArray = json::array();
877  json startSubArray = json::array();
878  json endSubArray = json::array();
879 
880  MAd::pGModel tmpMdl = NULL;
881  MAd::GM_create(&tmpMdl,"");
882  MAd::pMesh refinedMadMesh = MAd::M_new(tmpMdl);
883  MAd::M_load(refinedMadMesh,"refined.msh");
884 
885  MAd::GM_create(&tmpMdl,"");
886  MAd::pMesh skinnedMadMesh = MAd::M_new(tmpMdl);
887 
888  std::vector<int> regIds;
889  refinedMadMesh->skin_me(skinnedMadMesh, regIds);
890 
891  MAd::EIter eit = MAd::M_edgeIter(skinnedMadMesh);
892  MAd::pEdge pe;
893  while ((pe = MAd::EIter_next(eit)))
894  {
895  MAd::pVertex v = MAd::E_vertex(pe, 0);
896  startSubArray = json::array();
897  startSubArray.add(v->X);
898  startSubArray.add(v->Y);
899  startSubArray.add(v->Z);
900  startArray.add(startSubArray);
901 
902  v = MAd::E_vertex(pe, 1);
903  endSubArray = json::array();
904  endSubArray.add(v->X);
905  endSubArray.add(v->Y);
906  endSubArray.add(v->Z);
907  endArray.add(endSubArray);
908  }
909 
910  condJson["Params"]["Start"] = startArray;
911  condJson["Params"]["End"] = endArray;
912 
913  json condArray = json::array();
914  condArray.add(condJson);
915 
916  outJson["Condition"] = condArray;
917 
918  ofstream of("./bcs.json");
919  of << pretty_print(outJson);
920  of.close();
921 }
922 */
923 
924 void proteusHdf5::getBoundaryEdgePts(vtkSmartPointer<vtkPoints> startPts,
925  vtkSmartPointer<vtkPoints> endPts) {
926  if (numDimensions != 2) {
927  std::cerr << "Error: Sidesets only supports for 2D meshes" << std::endl;
928  exit(-1);
929  }
930 
931  MAd::pGModel tmpMdl = NULL;
932  MAd::GM_create(&tmpMdl, "");
933  MAd::pMesh refinedMadMesh = MAd::M_new(tmpMdl);
934  MAd::M_load(refinedMadMesh, "refined.msh");
935 
936  MAd::GM_create(&tmpMdl, "");
937  MAd::pMesh skinnedMadMesh = MAd::M_new(tmpMdl);
938 
939  std::vector<int> regIds;
940  refinedMadMesh->skin_me(skinnedMadMesh, regIds);
941 
942  MAd::EIter eit = MAd::M_edgeIter(skinnedMadMesh);
943  MAd::pEdge pe;
944  int edgeId = 0;
945  double coord[3];
946  while ((pe = MAd::EIter_next(eit))) {
947  MAd::pVertex v = MAd::E_vertex(pe, 0);
948  coord[0] = v->X;
949  coord[1] = v->Y;
950  coord[2] = v->Z;
951  startPts->InsertPoint(edgeId, coord);
952 
953  v = MAd::E_vertex(pe, 1);
954  coord[0] = v->X;
955  coord[1] = v->Y;
956  coord[2] = v->Z;
957  endPts->InsertPoint(edgeId, coord);
958 
959  edgeId++;
960  }
961 }
962 
964  meshBase *myMeshBase, vtkSmartPointer<vtkPoints> startPts,
965  vtkSmartPointer<vtkPoints> endPts,
966  vtkSmartPointer<vtkIdList> sidesetElementIdList,
967  vtkSmartPointer<vtkIdList> sidesetSideIdList) {
968  // Build up locator
969  vtkSmartPointer<vtkPointLocator> pointLocator =
971  pointLocator->SetDataSet(myMeshBase->getDataSet());
972  pointLocator->BuildLocator();
973 
974  // edge Pt iterators
975  vtkIdType id1, id2;
976  vtkSmartPointer<vtkIdList> cellList1 = vtkSmartPointer<vtkIdList>::New();
977  vtkSmartPointer<vtkIdList> cellList2 = vtkSmartPointer<vtkIdList>::New();
978  vtkCell *foundCell;
979  vtkSmartPointer<vtkIdList> edgeIdListCompare =
981  vtkSmartPointer<vtkIdList> edgeIdListOriginal =
983  vtkSmartPointer<vtkIdList> edgeIdListIntersection =
985  for (int iBndEdge = 0; iBndEdge < startPts->GetNumberOfPoints(); iBndEdge++) {
986  // std::cout << "boundary edge: " << iBndEdge << std::endl;
987  edgeIdListOriginal->Reset();
988 
989  id1 = pointLocator->FindClosestPoint(startPts->GetPoint(iBndEdge));
990  id2 = pointLocator->FindClosestPoint(endPts->GetPoint(iBndEdge));
991 
992  edgeIdListOriginal->InsertNextId(id1);
993  edgeIdListOriginal->InsertNextId(id2);
994 
995  myMeshBase->getDataSet()->GetPointCells(id1, cellList1);
996  myMeshBase->getDataSet()->GetPointCells(id2, cellList2);
997 
998  cellList1->IntersectWith(cellList2);
999  if (cellList1->GetNumberOfIds() != 1) {
1000  std::cerr << "Error: found multiple cells for boundary edge in a 2d mesh"
1001  << std::endl;
1002  exit(-1);
1003  } else {
1004  sidesetElementIdList->InsertNextId(cellList1->GetId(0));
1005  // std::cout << " elem ID = " << cellList1->GetId(0) << std::endl;
1006  foundCell = myMeshBase->getDataSet()->GetCell(cellList1->GetId(0));
1007  vtkSmartPointer<vtkIdList> cellPts = vtkSmartPointer<vtkIdList>::New();
1008  myMeshBase->getDataSet()->GetCellPoints(cellList1->GetId(0), cellPts);
1009  for (int ipt = 0; ipt < cellPts->GetNumberOfIds(); ipt++) {
1010  double position[3];
1011  myMeshBase->getDataSet()->GetPoint(cellPts->GetId(ipt), position);
1012  // std::cout << " ipt " << ipt << " position = " << position[0] << ",
1013  // "
1014  // << position[1] << ", " << position[2] << std::endl;
1015  }
1016  }
1017 
1018  for (int iCellEdge = 0; iCellEdge < foundCell->GetNumberOfEdges();
1019  iCellEdge++) {
1020  edgeIdListCompare = foundCell->GetEdge(iCellEdge)->GetPointIds();
1021 
1022  // Alternate 'intersection' implementation due to pointer issues
1023  edgeIdListIntersection->Reset();
1024  for (int iId = 0; iId < edgeIdListOriginal->GetNumberOfIds(); iId++) {
1025  for (int jId = 0; jId < edgeIdListCompare->GetNumberOfIds(); jId++) {
1026  if (edgeIdListOriginal->GetId(iId) == edgeIdListCompare->GetId(jId)) {
1027  edgeIdListIntersection->InsertNextId(
1028  edgeIdListOriginal->GetId(iId));
1029  }
1030  }
1031  }
1032 
1033  if (edgeIdListIntersection->GetNumberOfIds() == 2) {
1034  sidesetSideIdList->InsertNextId(iCellEdge);
1035  // std::cout << " side ID = " << iCellEdge << std::endl;
1036  break;
1037  }
1038  if (iCellEdge == foundCell->GetNumberOfEdges() - 1) {
1039  std::cout << "Couldn't find a matching side!" << std::endl;
1040  }
1041  }
1042  }
1043 }
1044 
1045 int proteusHdf5::getNumBlocks() const { return (numBlocks); }
1046 
1048 
1050 
1052 
1054 
1056  std::map<int, bool> rhr;
1057  for (int iCell = 0; iCell < myMeshBase->getDataSet()->GetNumberOfCells();
1058  iCell++) {
1059  // Get first cell
1060  vtkSmartPointer<vtkCell> testCell =
1061  myMeshBase->getDataSet()->GetCell(iCell);
1062  vtkSmartPointer<vtkPoints> cellPts = testCell->GetPoints();
1063  double pt0[3];
1064  double pt1[3];
1065  double pt2[3];
1066  double vc0[3];
1067  double vc1[3];
1068  double vc2[3];
1069  double zNorm[3] = {0, 0, 1};
1070  double res;
1071  if (testCell->GetCellType() == VTK_TRIANGLE) {
1072  cellPts->GetPoint(0, pt0);
1073  cellPts->GetPoint(1, pt1);
1074  cellPts->GetPoint(2, pt2);
1075  vtkMath::Subtract(pt1, pt0, vc0);
1076  vtkMath::Subtract(pt2, pt0, vc1);
1077  } else if (testCell->GetCellType() == VTK_QUAD) {
1078  cellPts->GetPoint(0, pt0);
1079  cellPts->GetPoint(1, pt1);
1080  cellPts->GetPoint(2, pt2);
1081  vtkMath::Subtract(pt1, pt0, vc0);
1082  vtkMath::Subtract(pt2, pt0, vc1);
1083  } else if (testCell->GetCellType() != VTK_QUAD &&
1084  testCell->GetCellType() != VTK_TRIANGLE) {
1085  std::cerr << "Only triangular and quadrilateral elements supported."
1086  << std::endl;
1087  exit(-1);
1088  } else {
1089  continue;
1090  }
1091  vtkMath::Cross(vc0, vc1, vc2);
1092  res = vtkMath::Dot(vc2, zNorm);
1093 
1094  bool ans;
1095  if (res > 0) {
1096  ans = true;
1097  } else {
1098  ans = false;
1099  }
1100  if ((testCell->GetCellType() == VTK_QUAD &&
1101  rhr.find(VTK_QUAD) == rhr.end()) ||
1102  (testCell->GetCellType() == VTK_TRIANGLE &&
1103  rhr.find(VTK_TRIANGLE) == rhr.end())) {
1104  rhr[testCell->GetCellType()] = ans;
1105  } else {
1106  if (rhr[testCell->GetCellType()] != ans) {
1107  std::cout << "Mismatched ordering for type " << testCell->GetCellType()
1108  << ", cell number " << iCell << std::endl;
1109  }
1110  }
1111  }
1112  bool conv = false;
1113  for (auto itr = rhr.begin(); itr != rhr.end(); itr++) {
1114  if (itr == rhr.begin()) {
1115  conv = itr->second;
1116  } else {
1117  if (conv != itr->second) {
1118  std::cerr << "Error: Mesh contains multiple element types with "
1119  "different node ordering."
1120  << std::endl;
1121  exit(-1);
1122  }
1123  }
1124  }
1125  return conv;
1126 }
int numElementVectors
number of element vector fields in Proteus file
Definition: proteusHdf5.H:247
bool lowOrder
Boolean converting high order cells to low order (useful for visualization)
Definition: proteusHdf5.H:240
std::vector< std::vector< double > > coordinates
coordinates[vertex id][dim] = coordinate
Definition: proteusHdf5.H:75
void setNumberOfVertices(int numVertices)
Set number of vertices in meshBase.
Definition: hdf5Reader.C:154
std::vector< std::vector< double > > elementData
elementData[field no][element id] = data
Definition: proteusHdf5.H:101
int originalVtkElementType
original VTK element type.
Definition: proteusHdf5.H:49
std::vector< double > yCrd
Definition: proteusHdf5.H:76
void refineMesh(const std::string &method, int arrayID, double dev_mult, bool maxIsmin, double edge_scale, const std::string &ofname, bool transferData, double sizeFactor=1., bool constrainBoundary=false)
perform sizefield-based h-refinement.
Definition: meshBase.C:1565
std::vector< int > elementTypes
Definition: proteusHdf5.H:83
void mergeBlocks()
Merge Proteus block together.
Definition: proteusHdf5.C:351
void setElementTypesList(std::vector< int > vtkElementTypesList)
Set list of each unique type of VTK element in mesh.
Definition: hdf5Reader.C:186
void unflattenBuffer2d(std::vector< T > flatBuffer, std::vector< std::vector< T >> &originalBuffer)
Unflatten 2d data buffer.
Definition: hdf5Reader.H:258
std::vector< int > originalElementTypesList
list of original element types, ordered by type according to elements vector
Definition: proteusHdf5.H:90
std::vector< std::string > elementVectorNames
vector containing names of element vectors
Definition: proteusHdf5.H:255
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
std::vector< std::vector< double > > elementData
element field data
Definition: proteusHdf5.H:59
void getBlocks()
Read Proteus blocks.
Definition: proteusHdf5.C:308
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
void getVectorNames(std::string name, std::vector< std::string > &stringVector, int numVectors)
Get names of Proteus vector fields.
Definition: proteusHdf5.C:267
void getBlockVertexData(Group &group, proteusBlock &myBlock)
Get vertex data for block.
Definition: proteusHdf5.C:819
std::vector< std::map< int, std::vector< int > > > elementConnectivity
element connectivity table
Definition: hdf5Reader.H:383
int getNumDimensions() const
Get number of spatial dimensions in Proteus file.
Definition: proteusHdf5.C:1047
int vtkElementType
VTK element type.
Definition: proteusHdf5.H:48
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
bool get2dCellNodeOrder(meshBase *myMeshBase)
Get normal vector for 2d meshes.
Definition: proteusHdf5.C:1055
int readGroup(std::string groupName, Group &group)
Read existing HDF5 Group.
Definition: hdf5Reader.C:135
std::vector< double > zCrd
coordinates separated out into x,y,z coordinates
Definition: proteusHdf5.H:76
int getCharStringLength() const
Get character string length of names in Proteus file.
Definition: proteusHdf5.C:1053
std::vector< std::vector< double > > vertexData
vertex field data
Definition: proteusHdf5.H:60
void getControlInformation()
Read Proteus control information.
Definition: proteusHdf5.C:239
proteusSuperBlock mySuperBlock
global block structure for entire Proteus mesh
Definition: proteusHdf5.H:258
std::string blockName
block name
Definition: proteusHdf5.H:45
void getBoundarySideSets(meshBase *myMeshBase, vtkSmartPointer< vtkPoints > startPts, vtkSmartPointer< vtkPoints > endPts, vtkSmartPointer< vtkIdList > sidesetElementIdList, vtkSmartPointer< vtkIdList > sidesetSideIdList)
Get boundary sidesets of mesh.
Definition: proteusHdf5.C:963
int numVerticesPerElement
number of vertices per element (only one element type allowed per block)
Definition: proteusHdf5.H:43
int numDimensions
number of spatial dimensions
Definition: proteusHdf5.H:245
int numElements
global number of elements
Definition: proteusHdf5.H:68
vtkSmartPointer< vtkDataSet > getDataSet() const
get this meshes&#39; dataSet
Definition: meshBase.H:308
void getBlockInfo(Group &group, proteusBlock &myBlock)
Read information for each Proteus block.
Definition: proteusHdf5.C:657
proteusHdf5(std::string fname, std::string outputFname, std::string edgeSidesetName, std::string exoMeshFName, bool lowOrder=false, bool bndryConst=true)
Construct Proteus HDF5 object.
Definition: proteusHdf5.C:60
void setConnectivities(std::vector< std::map< int, std::vector< int >>> elementConnectivity)
Set meshBase element connectivity table.
Definition: hdf5Reader.C:190
int numBlocks
number of Proteus blocks
Definition: proteusHdf5.H:244
int getNumElementVectors() const
Get number of element vectors in Proteus file.
Definition: proteusHdf5.C:1051
virtual void write() const
write the mesh to file named after the private var &#39;filename&#39;.
Definition: meshBase.H:598
void getBlockGlobalID(Group &group, proteusBlock &myBlock)
Get global coordinates of Proteus block.
Definition: proteusHdf5.C:758
meshBase * convertQuads()
Definition: meshBase.C:1769
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
void getBlockElementData(Group &group, proteusBlock &myBlock)
Get element data for block.
Definition: proteusHdf5.C:782
std::vector< proteusBlock > proteusBlocks
vector of all individual Proteus-style blocks
Definition: proteusHdf5.H:261
void getBoundaryEdgePts(vtkSmartPointer< vtkPoints > startPts, vtkSmartPointer< vtkPoints > endPts)
Write boundary condition information to json file.
Definition: proteusHdf5.C:924
void exportToMeshBase()
Export HDF5 mesh to meshBase object.
Definition: hdf5Reader.C:313
std::vector< int > loc2Glob
map between local and global IDs
Definition: proteusHdf5.H:56
meshBase * myMeshBase
meshBase object
Definition: hdf5Reader.H:378
int numElements
number of elements in block
Definition: proteusHdf5.H:42
int numVertexVectors
number of vertex vector fields in Proteus file
Definition: proteusHdf5.H:246
void getBlockXYZ(Group &group, proteusBlock &myBlock)
Get coordinates of Proteus block.
Definition: proteusHdf5.C:719
int maxNumVerticesPerElement
maximum number of vertices for all element types
Definition: proteusHdf5.H:70
std::vector< std::vector< std::vector< double > > > vertices
vertices
Definition: proteusHdf5.H:55
int numVertices
global number of vertices
Definition: proteusHdf5.H:69
void setNumberOfDimensions(int numDimensions)
Set number of spatial dimensions in meshBase.
Definition: hdf5Reader.C:162
std::vector< std::vector< double > > vertexData
cellData[field no][vertex id] = data
Definition: proteusHdf5.H:103
std::vector< double > xCrd
Definition: proteusHdf5.H:76
static std::shared_ptr< TransferBase > CreateTransferObject(meshBase *srcmsh, meshBase *trgmsh, const std::string &method)
int readGroupDataSet(std::string dsetName, Group &group, std::vector< T > &buffer)
Read numeric data from HDF5 group.
Definition: hdf5Reader.H:190
void setCoordinates(std::vector< double > xCrd)
Set meshBase 1d coordinate data.
Definition: hdf5Reader.C:166
std::vector< std::map< int, std::vector< int > > > vtkConnectivity
connectivity array for all element types by VTK convention, vtkConnectivity[element type][global elem...
Definition: proteusHdf5.H:95
std::vector< std::string > vertexVectorNames
vector containing names of vertex vectors
Definition: proteusHdf5.H:253
void setNumberOfElements(int numElements)
Set number of elements in meshBase.
Definition: hdf5Reader.C:158
Class for reading data from HDF5 files.
Definition: hdf5Reader.H:60
int getNumVertexVectors() const
Get number of vertex vectors in Proteus file.
Definition: proteusHdf5.C:1049
void setMetadata(vtkSmartPointer< vtkModelMetadata > _metadata)
Definition: meshBase.H:440
std::vector< int > elementTypesList
list of element types, ordered by type according to elements vector
Definition: proteusHdf5.H:86
int openFile()
Open HDF5 file.
Definition: hdf5Reader.C:41
std::vector< std::vector< int > > elements
connectivity info, elements[id][vertex no] = vertex id
Definition: proteusHdf5.H:81
static void genExo(std::vector< meshBase *> meshes, const std::string &fname)
stores information for each block of Proteus data
Definition: proteusHdf5.H:40
int charStringLength
string length of each Proteus variable name
Definition: proteusHdf5.H:249
int getNumBlocks() const
Get number of blocks in Proteus file.
Definition: proteusHdf5.C:1045