LifeV
ExporterHDF5Mesh3D.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5 Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6 Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8 This file is part of LifeV.
9 
10 LifeV is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14 
15 LifeV is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 /*!
27  @file
28  @brief Class derived from ExporterHDF5 to provide I/O for the mesh partitions (RegionMesh only)
29 
30  @date 9-07-2010
31  @author Radu Popescu <radu.popescu@epfl.ch>
32 
33  @maintainer Radu Popescu <radu.popescu@epfl.ch>
34 
35  This class has been deprecated and will be removed in future releases.
36  Please use the PartitionIO class in its place.
37 */
38 
39 #ifndef EXPORTER_HDF5_MESH_3D_H
40 #define EXPORTER_HDF5_MESH_3D_H 1
41 
42 
43 #include <lifev/core/LifeV.hpp>
44 
45 #ifdef HAVE_HDF5
46 
47 #include <lifev/core/filter/ExporterHDF5.hpp>
48 #include <lifev/core/fem/DOFInterface3Dto3D.hpp>
49 
50 namespace LifeV
51 {
52 
53 //! Class derived from ExporterHDF5 to provide I/O for the mesh partitions (RegionMesh only)
54 /*!
55  @author Radu Popescu <radu.popescu@epfl.ch>
56 
57  Usage: two steps
58  <ol>
59  <li> first: add the variables using addVariable
60  <li> second: call postProcess( time );
61  </ol>
62 
63  Guidelines when operating with partition information:
64  <ol>
65  <li> Use different objects for import and export
66  <li> When exporting graph and partition(s) create a ExporterHDF5 to be used for output.
67  Call methods: addPartitionGraph, addMeshPartitionAll, or addMyMeshPartition
68  Call postProcess to write data
69  Call CloseFile
70  <li> When importing graph and/or partition create a ExporterHDF5 to be used for input,
71  Call loadGraph and partitionMesh::update, call loadMyPartition
72  Call CloseFile
73  </ol>
74 */
75 template <typename MeshType>
76 class ExporterHDF5Mesh3D : public ExporterHDF5<MeshType>
77 {
78 public:
79  typedef MeshType mesh_Type;
80  typedef ExporterHDF5<MeshType> base;
81  typedef typename base::meshPtr_Type meshPtr_Type;
82  typedef typename base::vector_Type vector_Type;
83  typedef typename base::vectorPtr_Type vectorPtr_Type;
84  typedef typename base::exporterData_Type exporterData_Type;
85 
86  typedef EpetraExt::HDF5 hdf5_Type;
87  typedef std::shared_ptr<hdf5_Type> hdf5Ptr_Type;
88  typedef std::vector<std::vector<Int> > graph_Type;
89  typedef std::shared_ptr<graph_Type> graphPtr_Type;
90  typedef std::shared_ptr<std::vector<meshPtr_Type> > serialMeshPtr_Type;
91 
92  typedef DOFInterface3Dto3D interface_Type;
93  typedef std::shared_ptr<interface_Type> interfacePtr_Type;
94  typedef std::vector<interfacePtr_Type> interfaceVector_Type;
95  // The vector contains pointers to each fluid partition's interface with
96  // the solid.
97  typedef std::shared_ptr<interfaceVector_Type> interfaceVectorPtr_Type;
98 
99 
100  //! @name Constructor & Destructor
101  //@{
102 
103  //! Empty Constructor for ExporterHDF5Mesh3D
104  ExporterHDF5Mesh3D() {}
105 
106  //! Constructor for ExporterHDF5Mesh3D
107  /*!
108  @param dataFile the GetPot data file where you must provide an [exporter] section with:
109  "start" (start index for sections in the hdf5 data structure 0 for 000, 1 for 001 etc.),
110  "save" (how many time steps per postprocessing)
111  "multimesh" ( = true if the mesh has to be saved at each post-processing step)
112  @param mesh the mesh
113  @param the prefix for the case file (ex. "test" for test.case)
114  @param the procId determines de CPU id. if negative, it ussemes there is only one processor
115  */
116  ExporterHDF5Mesh3D (const GetPot& dataFile, meshPtr_Type mesh, const std::string& prefix, const Int& procId);
117 
118  //! Constructor for ExporterHDF5Mesh3D without prefix and procID
119  /*!
120  @param dataFile the GetPot data file where you must provide an [exporter] section with:
121  "start" (start index for sections in the hdf5 data structure 0 for 000, 1 for 001 etc.),
122  "save" (how many time steps per postprocessing)
123  "multimesh" ( = true if the mesh has to be saved at each post-processing step)
124  @param mesh the mesh
125  */
126  ExporterHDF5Mesh3D (const GetPot& dataFile, const std::string& prefix);
127 
128  //! Destructor for ExporterHDF5Mesh3D
129  virtual ~ExporterHDF5Mesh3D() {}
130 
131  //@}
132 
133  //! @name Pubic Methods
134  //@{
135  virtual void postProcess (const Real& time);
136 
137  //! Add the partition graph to the post processing data file
138  /*!
139  Add the partition graph to the post processing data file.
140  \param graph - shared_ptr<vector<vector<Int> > > - shared pointer to the partition graph data structure
141  (as returned by partitionMesh::graph() )
142  \param comm - Epetra_Comm* - raw pointer to the Epetra communicator to be used
143  */
144  void addPartitionGraph (const graphPtr_Type& graph, std::shared_ptr<Epetra_Comm>& comm)
145  {
146  M_graph = graph;
147  M_comm = comm;
148  }
149 
150  //! Add all of the mesh partitions to the post processing data file (serial operation)
151  /*!
152  Add all of the mesh partitions to the post processing data file.
153  \param meshPointer - shared_ptr<vector<shared_ptr<MeshType> > > - shared pointer to the vector storing
154  pointers to the mesh partitions (as returned by partitionMesh::meshAllPartitions() )
155  \param comm - Epetra_Comm* - raw pointer to the Epetra communicator to be used
156  */
157  void addMeshPartitionAll (const serialMeshPtr_Type& meshPointer, std::shared_ptr<Epetra_Comm>& comm)
158  {
159  M_serialMesh = meshPointer;
160  M_parallelMesh.reset();
161  M_comm = comm;
162  }
163 
164  //! Add to HDF5 file the mesh partition that belongs to the current process (parallel operation)
165  /*!
166  After the mesh partition is loaded from the HDF5 file, the simulation is run and
167  ExporterHDF5Mesh3D::postProcess() is called, the original contents of the HDF5 will be lost.
168  To keep mesh partition, call:
169  ExporterHDF5Mesh3D::addMyMeshPartition() before calling ExporterHDF5Mesh3D::postProcess();
170  \param meshPointer - shared_ptr<Mesh> - shared pointer to a mesh partition (as returned by
171  partitionMesh::mesh() )
172  \param comm - Epetra_Comm* - raw pointer to the Epetra communicator to be used
173  */
174  void addMyMeshPartition ( const meshPtr_Type& /*meshPointer*/, std::shared_ptr<Epetra_Comm>& /*comm*/ )
175  {
176  /*M_parallelMesh = meshPointer; M_serialMesh.reset(); M_comm = comm;*/
177  }
178 
179  //! Add a DOF interface for writing to file
180  /*!
181  Add a DOF interface to the member vector M_interfaceData, for writing to the HDF5
182  file. Call once for each interface that is to be written.
183  */
184  void addDOFInterface (const interfaceVectorPtr_Type& interfaces,
185  const std::string& type,
186  const Int& firstInterfaceFlag,
187  const Int& secondInterfaceFlag,
188  const std::shared_ptr<Epetra_Comm>& comm);
189 
190  //! Get the number of stored DOF interfaces
191  Int queryStoredInterfaceNumber();
192 
193  //! Get the types of the stored DOF interfaces
194  std::vector<std::string> queryStoredInterfaceTypes();
195 
196  //! Return a pointer to the graph
197  graphPtr_Type getGraph();
198 
199  //! Return a pointer to the mesh partition that corresponds to the current MPI rank
200  meshPtr_Type getMeshPartition();
201 
202  //! Return a pointer to the k-th interface stored inside the file
203  std::shared_ptr< std::map<UInt, UInt> > getStoredInterface (Int k) ;
204 
205  // When reading back partitions and interfaces, the comm member must be set explicitly.
206  // This is intended for use with getMeshPartition and getStoredInterface
207  //! Set the M_comm data member.
208  void setComm ( const std::shared_ptr<Epetra_Comm>& comm )
209  {
210  M_comm = comm;
211  }
212  //@}
213 
214 private:
215 
216  //! @name Private methods
217  //@{
218  // The following private methods are for writing the partitioned graph
219  // and mesh to the output file
220  void writeGraph();
221  void writePartition (meshPtr_Type partition, std::string& suffix);
222  void writeParallelMesh();
223  void writeSerialMesh();
224  void writeInterfaces();
225  //@}
226 
227  serialMeshPtr_Type M_serialMesh;
228  meshPtr_Type M_parallelMesh;
229  graphPtr_Type M_graph;
230  // Use a vector to store the data of all interfaces we wish to write to disk
231  std::vector<interfaceVectorPtr_Type> M_DOFInterfaces;
232  std::vector<std::string> M_interfaceTypes;
233  std::vector<Int> M_firstInterfaceFlags;
234  std::vector<Int> M_secondInterfaceFlags;
235  std::shared_ptr<Epetra_Comm> M_comm;
236 
237 };
238 
239 // ===================================================
240 // Constructors
241 // ===================================================
242 
243 template<typename MeshType>
244 ExporterHDF5Mesh3D<MeshType>::ExporterHDF5Mesh3D (const GetPot& dataFile, meshPtr_Type mesh,
245  const std::string& prefix,
246  const Int& procId) :
247  base ( dataFile, mesh, prefix, procId )
248 {
249 }
250 
251 template<typename MeshType>
252 ExporterHDF5Mesh3D<MeshType>::ExporterHDF5Mesh3D (const GetPot& dataFile, const std::string& prefix) :
253  base ( dataFile, prefix )
254 {
255 }
256 
257 // ===================================================
258 // Pubic Methods
259 // ===================================================
260 
261 template<typename MeshType>
262 void ExporterHDF5Mesh3D<MeshType>::addDOFInterface (const interfaceVectorPtr_Type& interfaces,
263  const std::string& type,
264  const Int& firstInterfaceFlag,
265  const Int& secondInterfaceFlag,
266  const std::shared_ptr<Epetra_Comm>& comm)
267 {
268  M_DOFInterfaces.push_back (interfaces);
269  M_interfaceTypes.push_back (type);
270  M_firstInterfaceFlags.push_back (firstInterfaceFlag);
271  M_secondInterfaceFlags.push_back (secondInterfaceFlag);
272 
273  M_comm = comm;
274 }
275 
276 template<typename MeshType>
277 void ExporterHDF5Mesh3D<MeshType>::postProcess (const Real& time)
278 {
279  if ( this->M_HDF5.get() == 0)
280  {
281  if (this->M_dataVector.size() != 0)
282  {
283  this->M_HDF5.reset (new hdf5_Type (this->M_dataVector.begin()->storedArrayPtr()->comm() ) );
284  }
285  else
286  {
287  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
288  }
289  this->M_outputFileName = this->M_prefix + ".h5";
290  this->M_HDF5->Create (this->M_postDir + this->M_outputFileName);
291 
292  // write empty xdmf file
293  this->writeInitXdmf();
294 
295  if (!this->M_multimesh)
296  {
297  if (this->M_dataVector.size() != 0)
298  {
299  this->writeGeometry(); // see also writeGeometrymetry
300  }
301 
302  if (M_graph.get() != 0)
303  {
304  if (M_comm->MyPID() == 0)
305  {
306  // Write the partition graph to file
307  writeGraph();
308  }
309  }
310  if (M_serialMesh.get() != 0)
311  {
312  // Write all the mesh partitions to file
313  writeSerialMesh();
314  }
315  if (M_parallelMesh.get() != 0)
316  {
317  // Write mesh partition that belongs to you (parallel op)
318  writeParallelMesh();
319  }
320  if (M_DOFInterfaces.size() != 0)
321  {
322  writeInterfaces();
323  }
324  this->M_HDF5->Flush();
325  }
326  }
327 
328  // typedef typename std::list< exporterData_Type >::const_iterator Iterator;
329 
330  this->computePostfix();
331 
332  if ( this->M_postfix != "*****" )
333  {
334  if (!this->M_procId)
335  {
336  std::cout << " X- HDF5 post-processing ... " << std::flush;
337  }
338  LifeChrono chrono;
339  chrono.start();
340  for (typename base::dataVectorIterator_Type i = this->M_dataVector.begin(); i != this->M_dataVector.end(); ++i)
341  {
342  this->writeVariable (*i);
343  }
344  // pushing time
345  this->M_timeSteps.push_back (time);
346 
347  this->writeXdmf (time);
348 
349  if (this->M_multimesh)
350  {
351  this->writeGeometry(); // see also writeGeometry
352  }
353 
354  chrono.stop();
355 
356  // Write to file without closing the file
357  this->M_HDF5->Flush();
358 
359  if (!this->M_procId)
360  {
361  std::cout << " done in " << chrono.diff() << " s." << std::endl;
362  }
363  }
364 }
365 
366 template <typename MeshType>
367 int ExporterHDF5Mesh3D<MeshType>::queryStoredInterfaceNumber()
368 {
369  if (this->M_HDF5.get() == 0)
370  {
371  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
372  }
373  if (! this->M_HDF5->IsOpen() )
374  {
375  this->M_HDF5->Open (this->M_postDir + this->M_prefix + ".h5", H5F_ACC_RDONLY);
376  }
377 
378  Int storedInterfaceNumber;
379  this->M_HDF5->Read ("Interfaces", "Number", storedInterfaceNumber);
380 
381  return storedInterfaceNumber;
382 }
383 
384 template <typename MeshType>
385 std::vector<std::string> ExporterHDF5Mesh3D<MeshType>::queryStoredInterfaceTypes()
386 {
387  if (this->M_HDF5.get() == 0)
388  {
389  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
390  }
391  if (! this->M_HDF5->IsOpen() )
392  {
393  this->M_HDF5->Open (this->M_postDir + this->M_prefix + ".h5", H5F_ACC_RDONLY);
394  }
395 
396  int storedInterfaceNumber;
397  this->M_HDF5->Read ("Interfaces", "Number", storedInterfaceNumber);
398 
399  std::vector<std::string> storedInterfaceTypes (storedInterfaceNumber);
400  for (Int k = 0; k < storedInterfaceNumber; ++k)
401  {
402  std::stringstream idx;
403  idx << k;
404  this->M_HDF5->Read ("Interfaces", "Type." + idx.str(), storedInterfaceTypes[k]);
405  }
406 
407  return storedInterfaceTypes;
408 }
409 
410 template <typename MeshType>
411 typename ExporterHDF5Mesh3D<MeshType>::graphPtr_Type ExporterHDF5Mesh3D<MeshType>::getGraph()
412 {
413  graphPtr_Type tempGraph (new graphPtr_Type::element_type);
414 
415  if (this->M_HDF5.get() == 0)
416  {
417  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
418  }
419  if (! this->M_HDF5->IsOpen() )
420  {
421  this->M_HDF5->Open (this->M_postDir + this->M_prefix + ".h5", H5F_ACC_RDONLY);
422  }
423 
424  Int nPartitions;
425 
426  this->M_HDF5->Read ("Graph", "number_partitions", nPartitions);
427 
428  std::vector<Int> partitionSizes (nPartitions);
429  this->M_HDF5->Read ("Graph", "partition_sizes", H5T_NATIVE_INT, nPartitions,
430  &partitionSizes[0]);
431 
432  tempGraph->resize (0);
433  tempGraph->reserve (nPartitions);
434 
435  std::vector<Int> partBuffer;
436  std::stringstream index;
437 
438  for (Int i = 0; i < nPartitions; ++i)
439  {
440  partBuffer.resize (partitionSizes[i]);
441  index << i;
442  this->M_HDF5->Read ("Graph_partitions", "P" + index.str(),
443  H5T_NATIVE_INT, partitionSizes[i],
444  &partBuffer[0]);
445  tempGraph->push_back (partBuffer);
446  index.str (std::string() );
447  index.clear();
448  }
449 
450  return tempGraph;
451 }
452 
453 template <typename MeshType>
454 typename ExporterHDF5Mesh3D<MeshType>::meshPtr_Type ExporterHDF5Mesh3D<MeshType>::getMeshPartition()
455 {
456  meshPtr_Type tempMesh ( new MeshType ( M_comm ) );
457 
458  UInt elementNodes, faceNodes;
459  switch (MeshType::elementShape_Type::S_shape)
460  {
461  case HEXA:
462  elementNodes = 8;
463  faceNodes = 4;
464  break;
465  case TETRA:
466  elementNodes = 4;
467  faceNodes = 3;
468  }
469 
470  if (this->M_HDF5.get() == 0)
471  {
472  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
473  }
474  if (! this->M_HDF5->IsOpen() )
475  {
476  this->M_HDF5->Open (this->M_postDir + this->M_prefix + ".h5", H5F_ACC_RDONLY);
477  }
478 
479  std::stringstream index;
480  index << M_comm->MyPID();
481  std::string suffix = "." + index.str();
482 
483  // Read counters from file and set them in the mesh
484 
485  std::vector<Int> counters (13);
486  this->M_HDF5->Read ("Mesh_counters", "P" + suffix, H5T_NATIVE_INT, 13, &counters[0]);
487  // Points
488  Int numPoints = counters[0];
489  tempMesh->setMaxNumPoints (counters[0], true);
490  tempMesh->setNumBPoints (counters[1]);
491 
492  // Vertices
493  tempMesh->setNumVertices (counters[2]);
494  tempMesh->setNumBVertices (counters[3]);
495  tempMesh->setNumGlobalVertices (counters[4]);
496 
497  // Edges
498  Int numEdges = counters[5];
499  tempMesh->setNumEdges (counters[5]);
500  tempMesh->setMaxNumEdges (counters[5]);
501  tempMesh->setNumBEdges (counters[6]);
502  tempMesh->setMaxNumGlobalEdges (counters[7]);
503 
504  // Faces
505  Int numFaces = counters[8];
506  tempMesh->setNumFaces (counters[8]);
507  tempMesh->setMaxNumFaces (counters[8]);
508  tempMesh->setNumBFaces (counters[9]);
509  tempMesh->setMaxNumGlobalFaces (counters[10]);
510 
511  // Volumes
512  Int numVolumes = counters[11];
513  tempMesh->setMaxNumVolumes (counters[11], true);
514  tempMesh->setMaxNumGlobalVolumes (counters[12]);
515 
516  // Read the list of points
517  std::vector<Real> tmpVectorDouble (numPoints);
518  std::vector<std::vector<Real> > pointCoordinates (3, tmpVectorDouble);
519 
520  std::vector<Int> pointMarkers (numPoints);
521  std::vector<Int> pointFlags (numPoints);
522  std::vector<Int> pointBoundaryFlags (numPoints);
523  std::vector<Int> pointGlobalId (numPoints);
524 
525  this->M_HDF5->Read ("Mesh_points_coordinates_x", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[0][0]);
526  this->M_HDF5->Read ("Mesh_points_coordinates_y", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[1][0]);
527  this->M_HDF5->Read ("Mesh_points_coordinates_z", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[2][0]);
528  this->M_HDF5->Read ("Mesh_points_markers", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointMarkers[0]);
529  this->M_HDF5->Read ("Mesh_points_flags", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointFlags[0]);
530  this->M_HDF5->Read ("Mesh_points_boundary_flag", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointBoundaryFlags[0]);
531  this->M_HDF5->Read ("Mesh_points_gid", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointGlobalId[0]);
532 
533  tempMesh->pointList.reserve (numPoints);
534  tempMesh->_bPoints.reserve (tempMesh->numBPoints() );
535 
536  typename MeshType::point_Type* pp = 0;
537 
538  for (Int j = 0; j < numPoints; ++j)
539  {
540  pp = & (tempMesh->addPoint (false, false) );
541  pp->setMarkerID (pointMarkers[j]);
542  pp->setFlag (pointFlags[j]);
543  pp->x() = pointCoordinates[0][j];
544  pp->y() = pointCoordinates[1][j];
545  pp->z() = pointCoordinates[2][j];
546  pp->setId (pointGlobalId[j]);
547  }
548 
549  pointCoordinates.clear();
550  pointMarkers.clear();
551  pointFlags.clear();
552  pointBoundaryFlags.clear();
553  pointGlobalId.clear();
554 
555  // Read the list of edges
556  std::vector<Int> tmpVectorInt (numEdges);
557  std::vector<std::vector<Int> > edgePoints (2, tmpVectorInt);
558 
559  std::vector<Int> edgeMarkers (numEdges);
560  std::vector<Int> edgeFlags (numEdges);
561  std::vector<Int> edgeGlobalId (numEdges);
562  std::vector<Int> edgeBoundaryFlags (numEdges);
563 
564  this->M_HDF5->Read ("Mesh_edges_p1", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgePoints[0][0]);
565  this->M_HDF5->Read ("Mesh_edges_p2", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgePoints[1][0]);
566  this->M_HDF5->Read ("Mesh_edges_markers", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeMarkers[0]);
567  this->M_HDF5->Read ("Mesh_edges_flags", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeFlags[0]);
568  this->M_HDF5->Read ("Mesh_edges_gid", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeGlobalId[0]);
569  this->M_HDF5->Read ("Mesh_edges_boundary_flag", "P" + suffix, H5T_NATIVE_INT, numEdges,
570  &edgeBoundaryFlags[0]);
571 
572  tempMesh->edgeList.reserve (numEdges);
573 
574  typename MeshType::edge_Type* pe;
575 
576  for (Int j = 0; j < numEdges; ++j)
577  {
578  pe = & (tempMesh->addEdge (edgeBoundaryFlags[j]) );
579  pe->setId (edgeGlobalId[j]);
580  pe->setPoint (0, tempMesh->point (edgePoints[0][j]) );
581  pe->setPoint (1, tempMesh->point (edgePoints[1][j]) );
582  pe->setMarkerID (edgeMarkers[j]);
583  pe->setFlag (edgeFlags[j]);
584  }
585 
586  edgePoints.clear();
587  edgeMarkers.clear();
588  edgeFlags.clear();
589  edgeGlobalId.clear();
590  edgeBoundaryFlags.clear();
591 
592  // Read the list of faces
593  tmpVectorInt.resize (numFaces);
594  std::vector<std::vector<Int> > facePoints (faceNodes, tmpVectorInt);
595 
596  std::vector<Int> faceMarkers (numFaces);
597  std::vector<Int> faceFlags (numFaces);
598  std::vector<Int> faceGlobalId (numFaces);
599  std::vector<Int> faceBoundaryFlags (numFaces);
600 
601  std::vector<std::vector<Int> > faceNeighbourId (2, tmpVectorInt);
602  std::vector<std::vector<Int> > faceNeighbourPos (2, tmpVectorInt);
603 
604  std::stringstream idx;
605  for (UInt k = 0; k < faceNodes; ++k)
606  {
607  idx << k + 1;
608  this->M_HDF5->Read ("Mesh_faces_points", "P" + idx.str() + suffix, H5T_NATIVE_INT, numFaces,
609  &facePoints[k][0]);
610  idx.str (std::string() );
611  idx.clear();
612  }
613  this->M_HDF5->Read ("Mesh_faces_markers", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceMarkers[0]);
614  this->M_HDF5->Read ("Mesh_faces_flags", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceFlags[0]);
615  this->M_HDF5->Read ("Mesh_faces_gid", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceGlobalId[0]);
616  this->M_HDF5->Read ("Mesh_faces_boundary_flags", "P" + suffix, H5T_NATIVE_INT, numFaces,
617  &faceBoundaryFlags[0]);
618 
619  this->M_HDF5->Read ("Mesh_faces_neighbour1", "P" + suffix, H5T_NATIVE_INT, numFaces,
620  &faceNeighbourId[0][0]);
621  this->M_HDF5->Read ("Mesh_faces_neighbour2", "P" + suffix, H5T_NATIVE_INT, numFaces,
622  &faceNeighbourId[1][0]);
623  this->M_HDF5->Read ("Mesh_faces_neighbour_pos1", "P" + suffix, H5T_NATIVE_INT, numFaces,
624  &faceNeighbourPos[0][0]);
625  this->M_HDF5->Read ("Mesh_faces_neighbour_pos2", "P" + suffix, H5T_NATIVE_INT, numFaces,
626  &faceNeighbourPos[1][0]);
627 
628 
629  typename MeshType::face_Type* pf = 0;
630 
631  tempMesh->faceList.reserve (numFaces);
632 
633  for (Int j = 0; j < numFaces; ++j)
634  {
635  pf = & (tempMesh->addFace (faceBoundaryFlags[j]) );
636  pf->setId (faceGlobalId[j]);
637 
638  pf->firstAdjacentElementIdentity() = faceNeighbourId[0][j];
639  pf->secondAdjacentElementIdentity() = faceNeighbourId[1][j];
640  pf->firstAdjacentElementPosition() = faceNeighbourPos[0][j];
641  pf->secondAdjacentElementPosition() = faceNeighbourPos[1][j];
642 
643  pf->setMarkerID (faceMarkers[j]);
644  pf->setFlag (faceFlags[j]);
645  for (UInt k = 0; k < faceNodes; ++k)
646  {
647  pf->setPoint (k, tempMesh->point (facePoints[k][j]) );
648  }
649  }
650 
651  tempMesh->setLinkSwitch ("HAS_ALL_FACETS");
652  tempMesh->setLinkSwitch ("FACETS_HAVE_ADIACENCY");
653 
654  facePoints.clear();
655  faceMarkers.clear();
656  faceFlags.clear();
657  faceGlobalId.clear();
658  faceBoundaryFlags.clear();
659  faceNeighbourId.clear();
660  faceNeighbourPos.clear();
661 
662  // Read the list of volumes
663  tmpVectorInt.resize (numVolumes);
664  std::vector<std::vector<Int> > volumePoints (elementNodes, tmpVectorInt);
665 
666  std::vector<Int> volumeMarkers (numVolumes);
667  std::vector<Int> volumeFlags (numVolumes);
668  std::vector<Int> volumeGlobalId (numVolumes);
669 
670  for (UInt k = 0; k < elementNodes; ++k)
671  {
672  idx << k + 1;
673  this->M_HDF5->Read ("Mesh_volumes_points", "P" + idx.str() + suffix, H5T_NATIVE_INT, numVolumes,
674  &volumePoints[k][0]);
675  idx.str (std::string() );
676  idx.clear();
677  }
678  this->M_HDF5->Read ("Mesh_volumes_markers", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeMarkers[0]);
679  this->M_HDF5->Read ("Mesh_volumes_flags", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeFlags[0]);
680  this->M_HDF5->Read ("Mesh_volumes_gid", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeGlobalId[0]);
681 
682  tempMesh->volumeList.reserve (numVolumes);
683 
684  typename MeshType::volume_Type* pv = 0;
685 
686  for (Int j = 0; j < numVolumes; ++j)
687  {
688  pv = & (tempMesh->addVolume() );
689  pv->setId (volumeGlobalId[j]);
690  for (UInt k = 0; k < elementNodes; ++k)
691  {
692  pv->setPoint (k, tempMesh->point (volumePoints[k][j]) );
693  }
694  pv->setMarkerID (volumeMarkers[j]);
695  pv->setFlag (volumeFlags[j]);
696  }
697 
698  volumePoints.clear();
699  volumeMarkers.clear();
700  volumeFlags.clear();
701  volumeGlobalId.clear();
702 
703  tempMesh->updateElementEdges (false, false);
704  tempMesh->updateElementFaces (false, false);
705 
706  return tempMesh;
707 }
708 
709 template <typename MeshType>
710 std::shared_ptr< std::map<UInt, UInt> > ExporterHDF5Mesh3D<MeshType>::getStoredInterface (int k)
711 {
712  if (this->M_HDF5.get() == 0)
713  {
714  this->M_HDF5.reset (new hdf5_Type (*M_comm) );
715  }
716  if (! this->M_HDF5->IsOpen() )
717  {
718  this->M_HDF5->Open (this->M_postDir + this->M_prefix + ".h5", H5F_ACC_RDONLY);
719  }
720 
721  int myRank = M_comm->MyPID();
722 
723  std::stringstream idx;
724  idx << k << "." << myRank;
725 
726  std::shared_ptr<std::map<UInt, UInt> > interface (new std::map<UInt, UInt>);
727 
728  Int size;
729  this->M_HDF5->Read ("Interfaces", "Size." + idx.str(), size);
730 
731  std::vector<UInt> keyVector (size);
732  std::vector<UInt> valueVector (size);
733 
734  this->M_HDF5->Read ("Interfaces", "Key." + idx.str(), H5T_NATIVE_INT, size,
735  &keyVector[0]);
736  this->M_HDF5->Read ("Interfaces", "Value." + idx.str(), H5T_NATIVE_INT, size,
737  &valueVector[0]);
738 
739  for (Int i = 0; i < size; ++i)
740  {
741  interface->insert (std::make_pair (keyVector[i], valueVector[i]) );
742  }
743 
744  return interface;
745 }
746 
747 // ========================
748 // Private methods
749 // ========================
750 
751 template <typename MeshType>
752 void ExporterHDF5Mesh3D<MeshType>::writeGraph()
753 {
754  std::vector<Int> partitionSizes;
755  Int size, maxSize = 0;
756 
757  // Calculate the maximum size of the partitions and store partition
758  // sizes
759  partitionSizes.reserve (M_graph->size() );
760  for (std::vector<std::vector<Int> >::iterator it = M_graph->begin();
761  it != M_graph->end(); ++it)
762  {
763  size = it->size();
764  if (size > maxSize)
765  {
766  maxSize = size;
767  }
768  partitionSizes.push_back (size);
769  }
770 
771  this->M_HDF5->Write ("Graph", "partition_sizes", H5T_NATIVE_INT,
772  M_graph->size(), &partitionSizes[0]);
773 
774  // Write partition array size
775  this->M_HDF5->Write ("Graph", "number_partitions", static_cast<Int> ( (M_graph->size() ) ) );
776 
777  // Write partition array
778  std::stringstream index;
779  for (UInt i = 0; i < M_graph->size(); ++i)
780  {
781  index << i;
782  this->M_HDF5->Write ("Graph_partitions", "P" + index.str(),
783  H5T_NATIVE_INT, partitionSizes[i],
784  & (*M_graph) [i][0]);
785  index.str (std::string() );
786  index.clear();
787 
788  this->M_HDF5->Flush();
789 
790  std::cout << "Wrote graph for partition " << i << std::endl;
791  }
792 }
793 
794 template <typename MeshType>
795 void ExporterHDF5Mesh3D<MeshType>::writePartition (meshPtr_Type mesh, std::string& suffix)
796 {
797  UInt elementNodes, faceNodes;
798  switch (MeshType::elementShape_Type::S_shape)
799  {
800  case HEXA:
801  elementNodes = 8;
802  faceNodes = 4;
803  break;
804  case TETRA:
805  elementNodes = 4;
806  faceNodes = 3;
807  default:
808  ERROR_MSG ("element type not supported");
809  }
810 
811  std::vector<Int> counters;
812  counters.push_back (static_cast<Int> (mesh->numPoints() ) );
813  counters.push_back (static_cast<Int> (mesh->numBPoints() ) );
814  counters.push_back (static_cast<Int> (mesh->numVertices() ) );
815  counters.push_back (static_cast<Int> (mesh->numBVertices() ) );
816  counters.push_back (static_cast<Int> (mesh->numGlobalVertices() ) );
817  counters.push_back (static_cast<Int> (mesh->numEdges() ) );
818  counters.push_back (static_cast<Int> (mesh->numBEdges() ) );
819  counters.push_back (static_cast<Int> (mesh->numGlobalEdges() ) );
820  counters.push_back (static_cast<Int> (mesh->numFaces() ) );
821  counters.push_back (static_cast<Int> (mesh->numBFaces() ) );
822  counters.push_back (static_cast<Int> (mesh->numGlobalFaces() ) );
823  counters.push_back (static_cast<Int> (mesh->numVolumes() ) );
824  counters.push_back (static_cast<Int> (mesh->numGlobalVolumes() ) );
825 
826  this->M_HDF5->Write ("Mesh_counters", "P" + suffix, H5T_NATIVE_INT, 13, &counters[0]);
827  this->M_HDF5->Flush();
828 
829  UInt numPoints = mesh->numPoints();
830  std::vector<Real> tmpVectorDouble (numPoints);
831  std::vector<std::vector<Real> > pointCoordinates (3, tmpVectorDouble);
832 
833  std::vector<Int> pointMarkers (numPoints);
834  std::vector<Int> pointFlags (numPoints);
835  std::vector<Int> pointGlobalId (numPoints);
836  std::vector<Int> pointBoundaryFlags (numPoints);
837 
838  for (UInt j = 0; j < numPoints; ++j)
839  {
840  pointCoordinates[0][j] = mesh->pointList[j].x();
841  pointCoordinates[1][j] = mesh->pointList[j].y();
842  pointCoordinates[2][j] = mesh->pointList[j].z();
843  pointMarkers[j] = mesh->pointList[j].markerID();
844  pointFlags[j] = mesh->pointList[j].flag();
845  pointGlobalId[j] = mesh->point (j).id();
846  if (mesh->isBoundaryPoint (j) )
847  {
848  pointBoundaryFlags[j] = 1;
849  }
850  }
851 
852  this->M_HDF5->Write ("Mesh_points_coordinates_x", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[0][0]);
853  this->M_HDF5->Write ("Mesh_points_coordinates_y", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[1][0]);
854  this->M_HDF5->Write ("Mesh_points_coordinates_z", "P" + suffix, H5T_NATIVE_DOUBLE, numPoints, &pointCoordinates[2][0]);
855  this->M_HDF5->Write ("Mesh_points_markers", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointMarkers[0]);
856  this->M_HDF5->Write ("Mesh_points_flags", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointFlags[0]);
857  this->M_HDF5->Write ("Mesh_points_gid", "P" + suffix, H5T_NATIVE_INT, numPoints, &pointGlobalId[0]);
858  this->M_HDF5->Write ("Mesh_points_boundary_flag", "P" + suffix, H5T_NATIVE_INT, numPoints,
859  &pointBoundaryFlags[0]);
860 
861  this->M_HDF5->Flush();
862 
863  pointCoordinates.clear();
864  pointMarkers.clear();
865  pointFlags.clear();
866  pointBoundaryFlags.clear();
867  pointGlobalId.clear();
868 
869  Int numEdges = mesh->numEdges();
870  std::vector<Int> tmpVectorInt (numEdges);
871  std::vector<std::vector<Int> > edgePoints (2, tmpVectorInt);
872 
873  std::vector<Int> edgeMarkers (numEdges);
874  std::vector<Int> edgeFlags (numEdges);
875  std::vector<Int> edgeGlobalId (numEdges);
876  std::vector<Int> edgeBoundaryFlags (numEdges);
877 
878  for (Int j = 0; j < numEdges; ++j)
879  {
880  edgePoints[0][j] = mesh->edgeList[j].point (0).localId();
881  edgePoints[1][j] = mesh->edgeList[j].point (1).localId();
882  edgeMarkers[j] = mesh->edgeList[j].markerID();
883  edgeFlags[j] = mesh->edgeList[j].flag();
884  edgeGlobalId[j] = mesh->edgeList[j].id();
885 
886  if (mesh->isBoundaryEdge (j) )
887  {
888  edgeBoundaryFlags[j] = 1;
889  }
890  }
891 
892  this->M_HDF5->Write ("Mesh_edges_p1", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgePoints[0][0]);
893  this->M_HDF5->Write ("Mesh_edges_p2", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgePoints[1][0]);
894  this->M_HDF5->Write ("Mesh_edges_markers", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeMarkers[0]);
895  this->M_HDF5->Write ("Mesh_edges_flags", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeFlags[0]);
896  this->M_HDF5->Write ("Mesh_edges_gid", "P" + suffix, H5T_NATIVE_INT, numEdges, &edgeGlobalId[0]);
897  this->M_HDF5->Write ("Mesh_edges_boundary_flag", "P" + suffix, H5T_NATIVE_INT, numEdges,
898  &edgeBoundaryFlags[0]);
899 
900  this->M_HDF5->Flush();
901 
902  edgePoints.clear();
903  edgeMarkers.clear();
904  edgeFlags.clear();
905  edgeGlobalId.clear();
906  edgeBoundaryFlags.clear();
907 
908  Int numFaces = mesh->numFaces();
909  tmpVectorInt.resize (numFaces);
910  std::vector<std::vector<Int> > facePoints (faceNodes, tmpVectorInt);
911 
912  std::vector<Int> faceMarkers (numFaces);
913  std::vector<Int> faceFlags (numFaces);
914  std::vector<Int> faceGlobalId (numFaces);
915  std::vector<Int> faceBoundaryFlags (numFaces);
916 
917  std::vector<std::vector<Int> > faceNeighbourId (2, tmpVectorInt);
918  std::vector<std::vector<Int> > faceNeighbourPos (2, tmpVectorInt);
919 
920  for (Int j = 0; j < numFaces; ++j)
921  {
922  for (UInt k = 0; k < faceNodes; ++k)
923  {
924  facePoints[k][j] = mesh->faceList[j].point (k).localId();
925  }
926  faceMarkers[j] = mesh->faceList[j].markerID();
927  faceFlags[j] = mesh->faceList[j].flag();
928  faceGlobalId[j] = mesh->faceList[j].id();
929 
930  faceNeighbourId[0][j] = mesh->faceList[j].firstAdjacentElementIdentity();
931  faceNeighbourId[1][j] = mesh->faceList[j].secondAdjacentElementIdentity();
932  faceNeighbourPos[0][j] = mesh->faceList[j].firstAdjacentElementPosition();
933  faceNeighbourPos[1][j] = mesh->faceList[j].secondAdjacentElementPosition();
934 
935  if (mesh->isBoundaryFace (j) )
936  {
937  faceBoundaryFlags[j] = 1;
938  }
939  }
940 
941  std::stringstream idx;
942  for (UInt k = 0; k < faceNodes; ++k)
943  {
944  idx << k + 1;
945  this->M_HDF5->Write ("Mesh_faces_points", "P" + idx.str() + suffix, H5T_NATIVE_INT, numFaces,
946  &facePoints[k][0]);
947  idx.str (std::string() );
948  idx.clear();
949  }
950  this->M_HDF5->Write ("Mesh_faces_markers", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceMarkers[0]);
951  this->M_HDF5->Write ("Mesh_faces_flags", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceFlags[0]);
952  this->M_HDF5->Write ("Mesh_faces_gid", "P" + suffix, H5T_NATIVE_INT, numFaces, &faceGlobalId[0]);
953  this->M_HDF5->Write ("Mesh_faces_boundary_flags", "P" + suffix, H5T_NATIVE_INT, numFaces,
954  &faceBoundaryFlags[0]);
955 
956  this->M_HDF5->Write ("Mesh_faces_neighbour1", "P" + suffix, H5T_NATIVE_INT, numFaces,
957  &faceNeighbourId[0][0]);
958  this->M_HDF5->Write ("Mesh_faces_neighbour2", "P" + suffix, H5T_NATIVE_INT, numFaces,
959  &faceNeighbourId[1][0]);
960  this->M_HDF5->Write ("Mesh_faces_neighbour_pos1", "P" + suffix, H5T_NATIVE_INT, numFaces,
961  &faceNeighbourPos[0][0]);
962  this->M_HDF5->Write ("Mesh_faces_neighbour_pos2", "P" + suffix, H5T_NATIVE_INT, numFaces,
963  &faceNeighbourPos[1][0]);
964 
965  this->M_HDF5->Flush();
966 
967  facePoints.clear();
968  faceMarkers.clear();
969  faceFlags.clear();
970  faceGlobalId.clear();
971  faceBoundaryFlags.clear();
972  faceNeighbourId.clear();
973  faceNeighbourPos.clear();
974 
975  Int numVolumes = mesh->numVolumes();
976  tmpVectorInt.resize (numVolumes);
977  std::vector<std::vector<Int> > volumePoints (elementNodes, tmpVectorInt);
978 
979  std::vector<Int> volumeMarkers (numVolumes);
980  std::vector<Int> volumeFlags (numVolumes);
981  std::vector<Int> volumeGlobalId (numVolumes);
982 
983  for (Int j = 0; j < numVolumes; ++j)
984  {
985  for (UInt k = 0; k < elementNodes; ++k)
986  {
987  volumePoints[k][j] = mesh->volumeList[j].point (k).localId();
988  }
989  volumeMarkers[j] = mesh->volumeList[j].markerID();
990  volumeFlags[j] = mesh->volumeList[j].flag();
991  volumeGlobalId[j] = mesh->volumeList[j].id();
992  }
993 
994  for (UInt k = 0; k < elementNodes; ++k)
995  {
996  idx << k + 1;
997  this->M_HDF5->Write ("Mesh_volumes_points", "P" + idx.str() + suffix, H5T_NATIVE_INT, numVolumes,
998  &volumePoints[k][0]);
999  idx.str (std::string() );
1000  idx.clear();
1001  }
1002  this->M_HDF5->Write ("Mesh_volumes_markers", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeMarkers[0]);
1003  this->M_HDF5->Write ("Mesh_volumes_flags", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeFlags[0]);
1004  this->M_HDF5->Write ("Mesh_volumes_gid", "P" + suffix, H5T_NATIVE_INT, numVolumes, &volumeGlobalId[0]);
1005 
1006  this->M_HDF5->Flush();
1007 
1008  volumePoints.clear();
1009  volumeMarkers.clear();
1010  volumeFlags.clear();
1011  volumeGlobalId.clear();
1012 }
1013 
1014 template <typename MeshType>
1015 void ExporterHDF5Mesh3D<MeshType>::writeSerialMesh()
1016 {
1017  std::stringstream index;
1018  std::string suffix;
1019 
1020  for (UInt i = 0; i < M_serialMesh->size(); ++i)
1021  {
1022  index << i;
1023  suffix = "." + index.str();
1024 
1025  writePartition ( (*M_serialMesh) [i], suffix);
1026 
1027  index.str (std::string() );
1028  index.clear();
1029 
1030  std::cout << "Wrote mesh partition " << i << std::endl;
1031  }
1032 }
1033 
1034 template <typename MeshType>
1035 void ExporterHDF5Mesh3D<MeshType>::writeParallelMesh()
1036 {
1037  std::stringstream index;
1038  std::string suffix;
1039 
1040  index << M_comm->MyPID();
1041  suffix = "." + index.str();
1042 
1043  writePartition (M_parallelMesh, suffix);
1044 }
1045 
1046 template <typename MeshType>
1047 void ExporterHDF5Mesh3D<MeshType>::writeInterfaces()
1048 {
1049  Int interfaceNumber = M_DOFInterfaces.size();
1050 
1051  std::vector<Int> firstDOF;
1052  std::vector<Int> secondDOF;
1053 
1054  this->M_HDF5->Write ("Interfaces", "Number", interfaceNumber);
1055 
1056  for (Int i = 0; i < interfaceNumber; ++i)
1057  {
1058  interfaceVector_Type& currentInterfaceSet = * (M_DOFInterfaces[i]);
1059 
1060  Int partitionNumber = currentInterfaceSet.size();
1061  std::stringstream idx;
1062  idx << i;
1063  this->M_HDF5->Write ("Interfaces", "Partitions." + idx.str(), partitionNumber);
1064 
1065  Int flag1 = M_firstInterfaceFlags[i];
1066  Int flag2 = M_secondInterfaceFlags[i];
1067  std::string type = M_interfaceTypes[i];
1068 
1069  this->M_HDF5->Write ("Interfaces", "Flag1." + idx.str(), flag1);
1070  this->M_HDF5->Write ("Interfaces", "Flag2." + idx.str(), flag2);
1071  this->M_HDF5->Write ("Interfaces", "Type." + idx.str(), type);
1072 
1073  for (Int j = 0; j < partitionNumber; ++j)
1074  {
1075  interface_Type& currentInterface = * (currentInterfaceSet[j]);
1076 
1077  const std::map<UInt, UInt>& locDofMap = currentInterface.localDofMap();
1078 
1079  Int size = locDofMap.size();
1080 
1081  idx.str (std::string() );
1082  idx.clear();
1083  idx << i << "." << j;
1084  this->M_HDF5->Write ("Interfaces", "Size." + idx.str(), size);
1085 
1086  firstDOF.clear();
1087  secondDOF.clear();
1088  firstDOF.resize (size);
1089  secondDOF.resize (size);
1090 
1091  Int k = 0;
1092  for (std::map<UInt, UInt>::const_iterator it = locDofMap.begin();
1093  it != locDofMap.end(); ++it)
1094  {
1095  firstDOF[k] = it->first;
1096  secondDOF[k] = it->second;
1097  ++k;
1098  }
1099  this->M_HDF5->Write ("Interfaces", "Key." + idx.str(), H5T_NATIVE_INT, size, &firstDOF[0]);
1100  this->M_HDF5->Write ("Interfaces", "Value." + idx.str(), H5T_NATIVE_INT, size, &secondDOF[0]);
1101  }
1102 
1103  }
1104 }
1105 
1106 } // Namespace LifeV
1107 
1108 #endif // HAVE_HDF5
1109 
1110 #endif // EXPORTER_HDF5_MESH_3D_H