![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /**
00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003 * storing and accessing finite element mesh data.
00004 *
00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract
00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007 * retains certain rights in this software.
00008 *
00009 * This library is free software; you can redistribute it and/or
00010 * modify it under the terms of the GNU Lesser General Public
00011 * License as published by the Free Software Foundation; either
00012 * version 2.1 of the License, or (at your option) any later version.
00013 *
00014 */
00015
00016 #ifndef READ_HDF5_HPP
00017 #define READ_HDF5_HPP
00018
00019 #include
00020 #include
00021 #include "mhdf.h"
00022 #include "moab/Forward.hpp"
00023 #include "moab/ReadUtilIface.hpp"
00024 #include "moab/Range.hpp"
00025 #include "moab/ReaderIface.hpp"
00026 #include "moab/RangeMap.hpp"
00027 #include "DebugOutput.hpp"
00028 #include "HDF5Common.hpp"
00029
00030 #ifdef MOAB_HAVE_MPI
00031 #include
00032 #endif
00033
00034 namespace moab
00035 {
00036
00037 class ParallelComm;
00038 class ReadHDF5Dataset;
00039 class CpuTimer;
00040
00041 /**
00042 * \brief Read mesh from MOAB HDF5 (.h5m) file.
00043 * \author Jason Kraftcheck
00044 * \date 18 April 2004
00045 */
00046 class ReadHDF5 : public ReaderIface
00047 {
00048 public:
00049 #ifdef MOAB_HAVE_MPI
00050 typedef MPI_Comm Comm;
00051 #else
00052 typedef int Comm;
00053 #endif
00054
00055 static ReaderIface* factory( Interface* );
00056
00057 ReadHDF5( Interface* iface );
00058
00059 virtual ~ReadHDF5();
00060
00061 /** Export specified meshsets to file
00062 * \param filename The filename to export. Must end in .mhdf
00063 * \param export_sets Array of handles to sets to export, or NULL to export all.
00064 * \param export_set_count Length of export_sets
array.
00065 */
00066 ErrorCode load_file( const char* file_name,
00067 const EntityHandle* file_set,
00068 const FileOptions& opts,
00069 const SubsetList* subset_list = 0,
00070 const Tag* file_id_tag = 0 );
00071
00072 ErrorCode read_tag_values( const char* file_name,
00073 const char* tag_name,
00074 const FileOptions& opts,
00075 std::vector< int >& tag_values_out,
00076 const SubsetList* subset_list = 0 );
00077 Interface* moab() const
00078 {
00079 return iFace;
00080 }
00081
00082 //! Store old HDF5 error handling function
00083 struct HDF5ErrorHandler
00084 {
00085 HDF5_Error_Func_Type func;
00086 void* data;
00087 };
00088
00089 protected:
00090 ErrorCode load_file_impl( const FileOptions& opts );
00091
00092 ErrorCode load_file_partial( const ReaderIface::IDTag* subset_list,
00093 int subset_list_length,
00094 int num_parts,
00095 int part_number,
00096 const FileOptions& opts );
00097
00098 ErrorCode read_tag_values_all( int tag_index, std::vector< int >& results );
00099 ErrorCode read_tag_values_partial( int tag_index, const Range& file_ids, std::vector< int >& results );
00100
00101 enum ReadTimingValues
00102 {
00103 TOTAL_TIME = 0,
00104 SET_META_TIME,
00105 SUBSET_IDS_TIME,
00106 GET_PARTITION_TIME,
00107 GET_SET_IDS_TIME,
00108 GET_SET_CONTENTS_TIME,
00109 GET_POLYHEDRA_TIME,
00110 GET_ELEMENTS_TIME,
00111 GET_NODES_TIME,
00112 GET_NODEADJ_TIME,
00113 GET_SIDEELEM_TIME,
00114 UPDATECONN_TIME,
00115 ADJACENCY_TIME,
00116 DELETE_NON_SIDEELEM_TIME,
00117 READ_SET_IDS_RECURS_TIME,
00118 FIND_SETS_CONTAINING_TIME,
00119 READ_SETS_TIME,
00120 READ_TAGS_TIME,
00121 STORE_FILE_IDS_TIME,
00122 READ_QA_TIME,
00123 NUM_TIMES
00124 };
00125
00126 void print_times();
00127
00128 private:
00129 ErrorCode init();
00130
00131 inline int is_error( mhdf_Status& status )
00132 {
00133 int i;
00134 if( ( i = mhdf_isError( &status ) ) ) MB_SET_ERR_CONT( mhdf_message( &status ) );
00135 return i;
00136 }
00137
00138 //! The size of the data buffer (dataBuffer
).
00139 int bufferSize;
00140 //! A memory buffer to use for all I/O operations.
00141 char* dataBuffer;
00142
00143 //! Interface pointer passed to constructor
00144 Interface* iFace;
00145
00146 //! The file handle from the mhdf library
00147 mhdf_FileHandle filePtr;
00148
00149 //! File summary
00150 mhdf_FileDesc* fileInfo;
00151
00152 //! Map from File ID to MOAB handle
00153 typedef RangeMap< long, EntityHandle > IDMap;
00154 IDMap idMap;
00155
00156 //! Cache pointer to read util
00157 ReadUtilIface* readUtil;
00158
00159 //! The type of an EntityHandle
00160 hid_t handleType;
00161
00162 //! List of connectivity arrays for which conversion from file ID
00163 //! to handle was deferred until later.
00164 struct IDConnectivity
00165 {
00166 EntityHandle handle; // Start_handle
00167 size_t count; // Num entities
00168 int nodes_per_elem; // Per-element connectivity length
00169 EntityHandle* array; // Connectivity array
00170 };
00171 //! List of connectivity arrays for which conversion from file ID
00172 //! to handle was deferred until later.
00173 std::vector< IDConnectivity > idConnectivityList;
00174
00175 //! Read/write property handle
00176 //! indepIO -> independent IO during true parallel read
00177 //! collIO -> collective IO during true parallel read
00178 //! Both are H5P_DEFAULT for serial IO and collective
00179 //! when reading the entire file on all processors.
00180 hid_t indepIO, collIO;
00181
00182 ParallelComm* myPcomm;
00183
00184 //! Use IODebugTrack instances to verify reads.
00185 //! Enable with the DEBUG_OVERLAPS option.
00186 bool debugTrack;
00187 //! Debug output. Verbosity controlled with DEBUG_FORMAT option.
00188 DebugOutput dbgOut;
00189 //! Doing true parallel read (PARALLEL=READ_PART)
00190 bool nativeParallel;
00191 //! MPI_Comm value (unused if \c !nativeParallel)
00192 Comm* mpiComm;
00193
00194 //! Flags for some behavior that can be changed through
00195 //! reader options
00196 bool blockedCoordinateIO;
00197 bool bcastSummary;
00198 bool bcastDuplicateReads;
00199
00200 //! Store old HDF5 error handling function
00201 HDF5ErrorHandler errorHandler;
00202
00203 long ( *setMeta )[4];
00204
00205 double _times[NUM_TIMES];
00206 CpuTimer* timer;
00207 bool cputime;
00208 ErrorCode read_all_set_meta();
00209
00210 ErrorCode set_up_read( const char* file_name, const FileOptions& opts );
00211 ErrorCode clean_up_read( const FileOptions& opts );
00212
00213 //! Given a list of tags and values, get the file ids for the
00214 //! corresponding entities in the file.
00215 ErrorCode get_subset_ids( const ReaderIface::IDTag* subset_list, int subset_list_length, Range& file_ids_out );
00216
00217 /**\brief Remove all but the specified fraction of sets from the passed range
00218 *
00219 * Select a subset of the gathered set of file ids to read in based on
00220 * communicator size and rank.
00221 *\param tmp_file_ids As input: sets to be read on all procs.
00222 * As output: sets to read on this proc.
00223 *\param num_parts communicator size
00224 *\param part_number communicator rank
00225 */
00226 ErrorCode get_partition( Range& tmp_file_ids, int num_parts, int part_number );
00227
00228 ErrorCode read_nodes( const Range& node_file_ids );
00229
00230 // Read elements in fileInfo->elems[index]
00231 ErrorCode read_elems( int index );
00232
00233 // Read subset of elements in fileInfo->elems[index]
00234 ErrorCode read_elems( int index, const Range& file_ids, Range* node_ids = 0 );
00235
00236 //! Read element connectivity.
00237 //!
00238 //!\param node_ids If this is non-null, the union of the connectivity list
00239 //! for all elements is passed back as FILE IDS in this
00240 //! range AND the connectivity list is left in the form
00241 //! of file IDs (NOT NODE HANDLES).
00242 ErrorCode read_elems( const mhdf_ElemDesc& elems, const Range& file_ids, Range* node_ids = 0 );
00243
00244 //! Update connectivity data for all element groups for which read_elems
00245 //! was called with a non-null \c node_ids argument.
00246 ErrorCode update_connectivity();
00247
00248 // Read connectivity data for a list of element file ids.
00249 // passing back the file IDs for the element connectivity
00250 // w/out actually creating any elements in MOAB.
00251 ErrorCode read_elems( int index, const Range& element_file_ids, Range& node_file_ids );
00252
00253 // Scan all elements in group. For each element for which all vertices
00254 // are contained in idMap (class member), read the element. All new
00255 // elements are added to idMap.
00256 //
00257 // NOTE: Collective IO calls in parallel.
00258 ErrorCode read_node_adj_elems( const mhdf_ElemDesc& group, Range* read_entities = 0 );
00259
00260 // Scan all elements in specified file table. For each element for
00261 // which all vertices are contained in idMap (class member), read the
00262 // element. All new elements are added to idMap.
00263 //
00264 // NOTE: Collective IO calls in parallel.
00265 ErrorCode read_node_adj_elems( const mhdf_ElemDesc& group, hid_t connectivity_handle, Range* read_entities = 0 );
00266
00267 //! Read poly(gons|hedra)
00268 ErrorCode read_poly( const mhdf_ElemDesc& elems, const Range& file_ids );
00269
00270 //! Clean up elements that were a) read because we had read all of the
00271 //! nodes and b) weren't actually sides of the top-dimension elements
00272 //! we were trying to read.
00273 ErrorCode delete_non_side_elements( const Range& side_ents );
00274
00275 //! Read sets
00276 ErrorCode read_sets( const Range& set_file_ids );
00277
00278 ErrorCode read_adjacencies( hid_t adjacency_table, long table_length );
00279
00280 //! Create tag and read all data.
00281 ErrorCode read_tag( int index );
00282
00283 //! Create new tag or verify type matches existing tag
00284 ErrorCode create_tag( const mhdf_TagDesc& info, Tag& handle, hid_t& type );
00285
00286 //! Read dense tag for all entities
00287 ErrorCode read_dense_tag( Tag tag_handle,
00288 const char* ent_name,
00289 hid_t hdf_read_type,
00290 hid_t data_table,
00291 long start_id,
00292 long count );
00293
00294 //! Read sparse tag for all entities.
00295 ErrorCode read_sparse_tag( Tag tag_handle,
00296 hid_t hdf_read_type,
00297 hid_t ent_table,
00298 hid_t val_table,
00299 long num_entities );
00300
00301 //! Read variable-length tag for all entities.
00302 ErrorCode read_var_len_tag( Tag tag_handle,
00303 hid_t hdf_read_type,
00304 hid_t ent_table,
00305 hid_t val_table,
00306 hid_t off_table,
00307 long num_entities,
00308 long num_values );
00309
00310 /**\brief Read index table for sparse tag.
00311 *
00312 * Read ID table for a sparse or variable-length tag, returning
00313 * the handles and offsets within the table for each file ID
00314 * that corresponds to an entity we've read from the file (an
00315 * entity that is in \c idMap).
00316 *
00317 * \param id_table The MOAB handle for the tag
00318 * \param start_offset Some non-zero value because ranges (in this case
00319 * the offset_range) cannot contain zeros.
00320 * \param offset_range Output: The offsets in the id table for which IDs
00321 * that occur in \c idMap were found. All values
00322 * are increased by \c start_offset to avoid
00323 * putting zeros in the range.
00324 * \param handle_range Output: For each valid ID read from the table,
00325 * the corresponding entity handle. Note: if
00326 * the IDs did not occur in handle order, then
00327 * this will be empty. Use \c handle_vect instead.
00328 * \param handle_vect Output: For each valid ID read from the table,
00329 * the corresponding entity handle. Note: if
00330 * the IDs occurred in handle order, then
00331 * this will be empty. Use \c handle_range instead.
00332 */
00333 ErrorCode read_sparse_tag_indices( const char* name,
00334 hid_t id_table,
00335 EntityHandle start_offset,
00336 Range& offset_range,
00337 Range& handle_range,
00338 std::vector< EntityHandle >& handle_vect );
00339
00340 ErrorCode read_qa( EntityHandle file_set );
00341
00342 public:
00343 ErrorCode convert_id_to_handle( EntityHandle* in_out_array, size_t array_length );
00344
00345 void convert_id_to_handle( EntityHandle* in_out_array, size_t array_length, size_t& array_length_out ) const
00346 {
00347 return convert_id_to_handle( in_out_array, array_length, array_length_out, idMap );
00348 }
00349
00350 ErrorCode convert_range_to_handle( const EntityHandle* ranges, size_t num_ranges, Range& merge );
00351
00352 static void convert_id_to_handle( EntityHandle* in_out_array,
00353 size_t array_length,
00354 const RangeMap< long, EntityHandle >& id_map );
00355
00356 static void convert_id_to_handle( EntityHandle* in_out_array,
00357 size_t array_length,
00358 size_t& array_length_out,
00359 const RangeMap< long, EntityHandle >& id_map );
00360
00361 static void convert_range_to_handle( const EntityHandle* ranges,
00362 size_t num_ranges,
00363 const RangeMap< long, EntityHandle >& id_map,
00364 Range& merge );
00365
00366 ErrorCode insert_in_id_map( const Range& file_ids, EntityHandle start_id );
00367
00368 ErrorCode insert_in_id_map( long file_id, EntityHandle handle );
00369
00370 private:
00371 /**\brief Search for entities with specified tag values
00372 *
00373 *\NOTE For parallel reads, this function does collective IO.
00374 *
00375 *\param tag_index Index into info->tags specifying which tag to search.
00376 *\param sorted_values List of tag values to check for, in ascending sorted
00377 * order.
00378 *\param file_ids_out File IDs for entities with specified tag values.
00379 */
00380 ErrorCode search_tag_values( int tag_index,
00381 const std::vector< int >& sorted_values,
00382 Range& file_ids_out,
00383 bool sets_only = false );
00384
00385 /**\brief Search for entities with specified tag
00386 *
00387 *\NOTE For parallel reads, this function does collective IO.
00388 *
00389 *\param tag_index Index into info->tags specifying which tag to search.
00390 *\param file_ids_out File IDs for entities with specified tag values.
00391 */
00392 ErrorCode get_tagged_entities( int tag_index, Range& file_ids_out );
00393
00394 /**\brief Search a table of tag data for a specified set of values.
00395 *
00396 * Search a table of tag values, returning the indices into the table
00397 * at which matches were found.
00398 *\NOTE For parallel reads, this function does collective IO.
00399 *
00400 *\param info Summary of data contained in file.
00401 *\param tag_table HDF5/mhdf handle for tag values
00402 *\param table_size Number of values in table
00403 *\param sorted_values Sorted list of values to search for.
00404 *\param value_indices Output: Offsets into the table of data at which
00405 * matching values were found.
00406 */
00407 ErrorCode search_tag_values( hid_t tag_table,
00408 unsigned long table_size,
00409 const std::vector< int >& sorted_values,
00410 std::vector< EntityHandle >& value_indices );
00411
00412 /**\brief Get the file IDs for nodes and elements contained in sets.
00413 *
00414 * Read the contents for the specified sets and return the file IDs
00415 * of all nodes and elements contained within those sets.
00416 *\param sets Container of file IDs designating entity sets.
00417 *\param file_ids Output: File IDs of entities contained in sets.
00418 */
00419 ErrorCode get_set_contents( const Range& sets, Range& file_ids );
00420
00421 /** Given a list of file IDs for entity sets, find all contained
00422 * or child sets (at any depth) and append them to the Range
00423 * of file IDs.
00424 */
00425 ErrorCode read_set_ids_recursive( Range& sets_in_out, bool containted_sets, bool child_sets );
00426
00427 /** Find all sets containing one or more entities read from the file
00428 * and added to idMap
00429 */
00430 ErrorCode find_sets_containing( Range& sets_out, bool read_set_containing_parents );
00431
00432 /**\brief Read sets from file into MOAB for partial read of file.
00433 *
00434 * Given the file IDs for entity sets (sets_in) and elements and
00435 * nodes (id_map), read in all sets containing any of the elements
00436 * or nodes and all sets that are (recursively) children of any
00437 * other set to be read (those in sets_in or those containing any
00438 * already-read element or node.)
00439 *\param sets_in File IDs for sets to read (unconditionally)
00440 */
00441 ErrorCode read_sets_partial( const Range& sets_in );
00442
00443 /** Find file IDs of sets containing any entities in the passed id_map */
00444 ErrorCode find_sets_containing( hid_t content_handle,
00445 hid_t content_type,
00446 long content_len,
00447 bool read_set_containing_parents,
00448 Range& file_ids );
00449
00450 public:
00451 enum SetMode
00452 {
00453 CONTENT = 0,
00454 CHILD = 1,
00455 PARENT = 2
00456 };
00457
00458 private:
00459 // Read the set data specified by by which_data.
00460 // Update set data in MOAB according to which_data,
00461 // unless file_ids_out is non-null. If file_ids_out is
00462 // non-null, then return the file IDs in the passed
00463 // range and do not make any changes to MOAB data
00464 // structures. If file_ids_out is NULL, then set_start_handle
00465 // is ignored.
00466 ErrorCode read_set_data( const Range& set_file_ids,
00467 EntityHandle set_start_handle,
00468 ReadHDF5Dataset& set_data_set,
00469 SetMode which_data,
00470 Range* file_ids_out = 0 );
00471
00472 /**\brief Store file IDS in tag values
00473 *
00474 * Copy file ID from IDMap for each entity read from file
00475 * into a tag value on the entity.
00476 */
00477 ErrorCode store_file_ids( Tag tag );
00478
00479 /**\brief Store sets file IDS in a custom tag
00480 *
00481 * Copy sets file ID from IDMap for each set read from file
00482 * into a custom tag on the sets
00483 * needed now for the VisIt plugin, to identify sets read
00484 */
00485 ErrorCode store_sets_file_ids();
00486
00487 /**\brief Find index in mhdf_FileDesc* fileInfo for specified tag name
00488 *
00489 * Given a tag name, find its index in fileInfo and verify that
00490 * each tag value is a single integer.
00491 */
00492 ErrorCode find_int_tag( const char* name, int& index_out );
00493
00494 void debug_barrier_line( int lineno );
00495 };
00496
00497 } // namespace moab
00498
00499 #endif