Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ReadHDF5.hpp
Go to the documentation of this file.
1 /** 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 #ifndef READ_HDF5_HPP 17 #define READ_HDF5_HPP 18  19 #include <cstdlib> 20 #include <list> 21 #include "mhdf.h" 22 #include "moab/Forward.hpp" 23 #include "moab/ReadUtilIface.hpp" 24 #include "moab/Range.hpp" 25 #include "moab/ReaderIface.hpp" 26 #include "moab/RangeMap.hpp" 27 #include "DebugOutput.hpp" 28 #include "HDF5Common.hpp" 29  30 #ifdef MOAB_HAVE_MPI 31 #include <moab_mpi.h> 32 #endif 33  34 namespace moab 35 { 36  37 class ParallelComm; 38 class ReadHDF5Dataset; 39 class CpuTimer; 40  41 /** 42  * \brief Read mesh from MOAB HDF5 (.h5m) file. 43  * \author Jason Kraftcheck 44  * \date 18 April 2004 45  */ 46 class ReadHDF5 : public ReaderIface 47 { 48  public: 49 #ifdef MOAB_HAVE_MPI 50  typedef MPI_Comm Comm; 51 #else 52  typedef int Comm; 53 #endif 54  55  static ReaderIface* factory( Interface* ); 56  57  ReadHDF5( Interface* iface ); 58  59  virtual ~ReadHDF5(); 60  61  /** Export specified meshsets to file 62  * \param filename The filename to export. Must end in <em>.mhdf</em> 63  * \param export_sets Array of handles to sets to export, or NULL to export all. 64  * \param export_set_count Length of <code>export_sets</code> array. 65  */ 66  ErrorCode load_file( const char* file_name, 67  const EntityHandle* file_set, 68  const FileOptions& opts, 69  const SubsetList* subset_list = 0, 70  const Tag* file_id_tag = 0 ); 71  72  ErrorCode read_tag_values( const char* file_name, 73  const char* tag_name, 74  const FileOptions& opts, 75  std::vector< int >& tag_values_out, 76  const SubsetList* subset_list = 0 ); 77  Interface* moab() const 78  { 79  return iFace; 80  } 81  82  //! Store old HDF5 error handling function 83  struct HDF5ErrorHandler 84  { 85  HDF5_Error_Func_Type func; 86  void* data; 87  }; 88  89  protected: 90  ErrorCode load_file_impl( const FileOptions& opts ); 91  92  ErrorCode load_file_partial( const ReaderIface::IDTag* subset_list, 93  int subset_list_length, 94  int num_parts, 95  int part_number, 96  const FileOptions& opts ); 97  98  ErrorCode read_tag_values_all( int tag_index, std::vector< int >& results ); 99  ErrorCode read_tag_values_partial( int tag_index, const Range& file_ids, std::vector< int >& results ); 100  101  enum ReadTimingValues 102  { 103  TOTAL_TIME = 0, 104  SET_META_TIME, 105  SUBSET_IDS_TIME, 106  GET_PARTITION_TIME, 107  GET_SET_IDS_TIME, 108  GET_SET_CONTENTS_TIME, 109  GET_POLYHEDRA_TIME, 110  GET_ELEMENTS_TIME, 111  GET_NODES_TIME, 112  GET_NODEADJ_TIME, 113  GET_SIDEELEM_TIME, 114  UPDATECONN_TIME, 115  ADJACENCY_TIME, 116  DELETE_NON_SIDEELEM_TIME, 117  READ_SET_IDS_RECURS_TIME, 118  FIND_SETS_CONTAINING_TIME, 119  READ_SETS_TIME, 120  READ_TAGS_TIME, 121  STORE_FILE_IDS_TIME, 122  READ_QA_TIME, 123  NUM_TIMES 124  }; 125  126  void print_times(); 127  128  private: 129  ErrorCode init(); 130  131  inline int is_error( mhdf_Status& status ) 132  { 133  int i; 134  if( ( i = mhdf_isError( &status ) ) ) MB_SET_ERR_CONT( mhdf_message( &status ) ); 135  return i; 136  } 137  138  //! The size of the data buffer (<code>dataBuffer</code>). 139  int bufferSize; 140  //! A memory buffer to use for all I/O operations. 141  char* dataBuffer; 142  143  //! Interface pointer passed to constructor 144  Interface* iFace; 145  146  //! The file handle from the mhdf library 147  mhdf_FileHandle filePtr; 148  149  //! File summary 150  mhdf_FileDesc* fileInfo; 151  152  //! Map from File ID to MOAB handle 153  typedef RangeMap< long, EntityHandle > IDMap; 154  IDMap idMap; 155  156  //! Cache pointer to read util 157  ReadUtilIface* readUtil; 158  159  //! The type of an EntityHandle 160  hid_t handleType; 161  162  //! List of connectivity arrays for which conversion from file ID 163  //! to handle was deferred until later. 164  struct IDConnectivity 165  { 166  EntityHandle handle; // Start_handle 167  size_t count; // Num entities 168  int nodes_per_elem; // Per-element connectivity length 169  EntityHandle* array; // Connectivity array 170  }; 171  //! List of connectivity arrays for which conversion from file ID 172  //! to handle was deferred until later. 173  std::vector< IDConnectivity > idConnectivityList; 174  175  //! Read/write property handle 176  //! indepIO -> independent IO during true parallel read 177  //! collIO -> collective IO during true parallel read 178  //! Both are H5P_DEFAULT for serial IO and collective 179  //! when reading the entire file on all processors. 180  hid_t indepIO, collIO; 181  182  ParallelComm* myPcomm; 183  184  //! Use IODebugTrack instances to verify reads. 185  //! Enable with the DEBUG_OVERLAPS option. 186  bool debugTrack; 187  //! Debug output. Verbosity controlled with DEBUG_FORMAT option. 188  DebugOutput dbgOut; 189  //! Doing true parallel read (PARALLEL=READ_PART) 190  bool nativeParallel; 191  //! MPI_Comm value (unused if \c !nativeParallel) 192  Comm* mpiComm; 193  194  //! Flags for some behavior that can be changed through 195  //! reader options 196  bool blockedCoordinateIO; 197  bool bcastSummary; 198  bool bcastDuplicateReads; 199  200  //! Store old HDF5 error handling function 201  HDF5ErrorHandler errorHandler; 202  203  long ( *setMeta )[4]; 204  205  double _times[NUM_TIMES]; 206  CpuTimer* timer; 207  bool cputime; 208  ErrorCode read_all_set_meta(); 209  210  ErrorCode set_up_read( const char* file_name, const FileOptions& opts ); 211  ErrorCode clean_up_read( const FileOptions& opts ); 212  213  //! Given a list of tags and values, get the file ids for the 214  //! corresponding entities in the file. 215  ErrorCode get_subset_ids( const ReaderIface::IDTag* subset_list, int subset_list_length, Range& file_ids_out ); 216  217  /**\brief Remove all but the specified fraction of sets from the passed range 218  * 219  * Select a subset of the gathered set of file ids to read in based on 220  * communicator size and rank. 221  *\param tmp_file_ids As input: sets to be read on all procs. 222  * As output: sets to read on this proc. 223  *\param num_parts communicator size 224  *\param part_number communicator rank 225  */ 226  ErrorCode get_partition( Range& tmp_file_ids, int num_parts, int part_number ); 227  228  ErrorCode read_nodes( const Range& node_file_ids ); 229  230  // Read elements in fileInfo->elems[index] 231  ErrorCode read_elems( int index ); 232  233  // Read subset of elements in fileInfo->elems[index] 234  ErrorCode read_elems( int index, const Range& file_ids, Range* node_ids = 0 ); 235  236  //! Read element connectivity. 237  //! 238  //!\param node_ids If this is non-null, the union of the connectivity list 239  //! for all elements is passed back as FILE IDS in this 240  //! range AND the connectivity list is left in the form 241  //! of file IDs (NOT NODE HANDLES). 242  ErrorCode read_elems( const mhdf_ElemDesc& elems, const Range& file_ids, Range* node_ids = 0 ); 243  244  //! Update connectivity data for all element groups for which read_elems 245  //! was called with a non-null \c node_ids argument. 246  ErrorCode update_connectivity(); 247  248  // Read connectivity data for a list of element file ids. 249  // passing back the file IDs for the element connectivity 250  // w/out actually creating any elements in MOAB. 251  ErrorCode read_elems( int index, const Range& element_file_ids, Range& node_file_ids ); 252  253  // Scan all elements in group. For each element for which all vertices 254  // are contained in idMap (class member), read the element. All new 255  // elements are added to idMap. 256  // 257  // NOTE: Collective IO calls in parallel. 258  ErrorCode read_node_adj_elems( const mhdf_ElemDesc& group, Range* read_entities = 0 ); 259  260  // Scan all elements in specified file table. For each element for 261  // which all vertices are contained in idMap (class member), read the 262  // element. All new elements are added to idMap. 263  // 264  // NOTE: Collective IO calls in parallel. 265  ErrorCode read_node_adj_elems( const mhdf_ElemDesc& group, hid_t connectivity_handle, Range* read_entities = 0 ); 266  267  //! Read poly(gons|hedra) 268  ErrorCode read_poly( const mhdf_ElemDesc& elems, const Range& file_ids ); 269  270  //! Clean up elements that were a) read because we had read all of the 271  //! nodes and b) weren't actually sides of the top-dimension elements 272  //! we were trying to read. 273  ErrorCode delete_non_side_elements( const Range& side_ents ); 274  275  //! Read sets 276  ErrorCode read_sets( const Range& set_file_ids ); 277  278  ErrorCode read_adjacencies( hid_t adjacency_table, long table_length ); 279  280  //! Create tag and read all data. 281  ErrorCode read_tag( int index ); 282  283  //! Create new tag or verify type matches existing tag 284  ErrorCode create_tag( const mhdf_TagDesc& info, Tag& handle, hid_t& type ); 285  286  //! Read dense tag for all entities 287  ErrorCode read_dense_tag( Tag tag_handle, 288  const char* ent_name, 289  hid_t hdf_read_type, 290  hid_t data_table, 291  long start_id, 292  long count ); 293  294  //! Read sparse tag for all entities. 295  ErrorCode read_sparse_tag( Tag tag_handle, 296  hid_t hdf_read_type, 297  hid_t ent_table, 298  hid_t val_table, 299  long num_entities ); 300  301  //! Read variable-length tag for all entities. 302  ErrorCode read_var_len_tag( Tag tag_handle, 303  hid_t hdf_read_type, 304  hid_t ent_table, 305  hid_t val_table, 306  hid_t off_table, 307  long num_entities, 308  long num_values ); 309  310  /**\brief Read index table for sparse tag. 311  * 312  * Read ID table for a sparse or variable-length tag, returning 313  * the handles and offsets within the table for each file ID 314  * that corresponds to an entity we've read from the file (an 315  * entity that is in \c idMap). 316  * 317  * \param id_table The MOAB handle for the tag 318  * \param start_offset Some non-zero value because ranges (in this case 319  * the offset_range) cannot contain zeros. 320  * \param offset_range Output: The offsets in the id table for which IDs 321  * that occur in \c idMap were found. All values 322  * are increased by \c start_offset to avoid 323  * putting zeros in the range. 324  * \param handle_range Output: For each valid ID read from the table, 325  * the corresponding entity handle. Note: if 326  * the IDs did not occur in handle order, then 327  * this will be empty. Use \c handle_vect instead. 328  * \param handle_vect Output: For each valid ID read from the table, 329  * the corresponding entity handle. Note: if 330  * the IDs occurred in handle order, then 331  * this will be empty. Use \c handle_range instead. 332  */ 333  ErrorCode read_sparse_tag_indices( const char* name, 334  hid_t id_table, 335  EntityHandle start_offset, 336  Range& offset_range, 337  Range& handle_range, 338  std::vector< EntityHandle >& handle_vect ); 339  340  ErrorCode read_qa( EntityHandle file_set ); 341  342  public: 343  ErrorCode convert_id_to_handle( EntityHandle* in_out_array, size_t array_length ); 344  345  void convert_id_to_handle( EntityHandle* in_out_array, size_t array_length, size_t& array_length_out ) const 346  { 347  return convert_id_to_handle( in_out_array, array_length, array_length_out, idMap ); 348  } 349  350  ErrorCode convert_range_to_handle( const EntityHandle* ranges, size_t num_ranges, Range& merge ); 351  352  static void convert_id_to_handle( EntityHandle* in_out_array, 353  size_t array_length, 354  const RangeMap< long, EntityHandle >& id_map ); 355  356  static void convert_id_to_handle( EntityHandle* in_out_array, 357  size_t array_length, 358  size_t& array_length_out, 359  const RangeMap< long, EntityHandle >& id_map ); 360  361  static void convert_range_to_handle( const EntityHandle* ranges, 362  size_t num_ranges, 363  const RangeMap< long, EntityHandle >& id_map, 364  Range& merge ); 365  366  ErrorCode insert_in_id_map( const Range& file_ids, EntityHandle start_id ); 367  368  ErrorCode insert_in_id_map( long file_id, EntityHandle handle ); 369  370  private: 371  /**\brief Search for entities with specified tag values 372  * 373  *\NOTE For parallel reads, this function does collective IO. 374  * 375  *\param tag_index Index into info->tags specifying which tag to search. 376  *\param sorted_values List of tag values to check for, in ascending sorted 377  * order. 378  *\param file_ids_out File IDs for entities with specified tag values. 379  */ 380  ErrorCode search_tag_values( int tag_index, 381  const std::vector< int >& sorted_values, 382  Range& file_ids_out, 383  bool sets_only = false ); 384  385  /**\brief Search for entities with specified tag 386  * 387  *\NOTE For parallel reads, this function does collective IO. 388  * 389  *\param tag_index Index into info->tags specifying which tag to search. 390  *\param file_ids_out File IDs for entities with specified tag values. 391  */ 392  ErrorCode get_tagged_entities( int tag_index, Range& file_ids_out ); 393  394  /**\brief Search a table of tag data for a specified set of values. 395  * 396  * Search a table of tag values, returning the indices into the table 397  * at which matches were found. 398  *\NOTE For parallel reads, this function does collective IO. 399  * 400  *\param info Summary of data contained in file. 401  *\param tag_table HDF5/mhdf handle for tag values 402  *\param table_size Number of values in table 403  *\param sorted_values Sorted list of values to search for. 404  *\param value_indices Output: Offsets into the table of data at which 405  * matching values were found. 406  */ 407  ErrorCode search_tag_values( hid_t tag_table, 408  unsigned long table_size, 409  const std::vector< int >& sorted_values, 410  std::vector< EntityHandle >& value_indices ); 411  412  /**\brief Get the file IDs for nodes and elements contained in sets. 413  * 414  * Read the contents for the specified sets and return the file IDs 415  * of all nodes and elements contained within those sets. 416  *\param sets Container of file IDs designating entity sets. 417  *\param file_ids Output: File IDs of entities contained in sets. 418  */ 419  ErrorCode get_set_contents( const Range& sets, Range& file_ids ); 420  421  /** Given a list of file IDs for entity sets, find all contained 422  * or child sets (at any depth) and append them to the Range 423  * of file IDs. 424  */ 425  ErrorCode read_set_ids_recursive( Range& sets_in_out, bool containted_sets, bool child_sets ); 426  427  /** Find all sets containing one or more entities read from the file 428  * and added to idMap 429  */ 430  ErrorCode find_sets_containing( Range& sets_out, bool read_set_containing_parents ); 431  432  /**\brief Read sets from file into MOAB for partial read of file. 433  * 434  * Given the file IDs for entity sets (sets_in) and elements and 435  * nodes (id_map), read in all sets containing any of the elements 436  * or nodes and all sets that are (recursively) children of any 437  * other set to be read (those in sets_in or those containing any 438  * already-read element or node.) 439  *\param sets_in File IDs for sets to read (unconditionally) 440  */ 441  ErrorCode read_sets_partial( const Range& sets_in ); 442  443  /** Find file IDs of sets containing any entities in the passed id_map */ 444  ErrorCode find_sets_containing( hid_t content_handle, 445  hid_t content_type, 446  long content_len, 447  bool read_set_containing_parents, 448  Range& file_ids ); 449  450  public: 451  enum SetMode 452  { 453  CONTENT = 0, 454  CHILD = 1, 455  PARENT = 2 456  }; 457  458  private: 459  // Read the set data specified by by which_data. 460  // Update set data in MOAB according to which_data, 461  // unless file_ids_out is non-null. If file_ids_out is 462  // non-null, then return the file IDs in the passed 463  // range and do not make any changes to MOAB data 464  // structures. If file_ids_out is NULL, then set_start_handle 465  // is ignored. 466  ErrorCode read_set_data( const Range& set_file_ids, 467  EntityHandle set_start_handle, 468  ReadHDF5Dataset& set_data_set, 469  SetMode which_data, 470  Range* file_ids_out = 0 ); 471  472  /**\brief Store file IDS in tag values 473  * 474  * Copy file ID from IDMap for each entity read from file 475  * into a tag value on the entity. 476  */ 477  ErrorCode store_file_ids( Tag tag ); 478  479  /**\brief Store sets file IDS in a custom tag 480  * 481  * Copy sets file ID from IDMap for each set read from file 482  * into a custom tag on the sets 483  * needed now for the VisIt plugin, to identify sets read 484  */ 485  ErrorCode store_sets_file_ids(); 486  487  /**\brief Find index in mhdf_FileDesc* fileInfo for specified tag name 488  * 489  * Given a tag name, find its index in fileInfo and verify that 490  * each tag value is a single integer. 491  */ 492  ErrorCode find_int_tag( const char* name, int& index_out ); 493  494  void debug_barrier_line( int lineno ); 495 }; 496  497 } // namespace moab 498  499 #endif