Loading [MathJax]/extensions/tex2jax.js
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
WriteDamsel.cpp
Go to the documentation of this file.
1 /* WriteDamsel.cpp 2  * The Damsel library provides mesh-aware parallel I/O; see 3  * http://cucis.ece.northwestern.edu/projects/DAMSEL/ for details, though for now that site is 4  * restricted to project participants. Damsel uses a data model that's very similar to that used in 5  * MOAB. It uses the same basic data model concepts of entities, sets, tags, and 6  * interface. In theory, we should be able to completely save/restore to/from Damsel any data that 7  * can be saved/restored to/from our native HDF5-based reader/writer. 8  * 9  * Mapping between MOAB-Damsel data models 10  * ======================================= 11  * Basic data model entities, MOAB <--> Damsel: 12  * Entity <--> Entity 13  * EntitySet <--> Collection 14  * Tag <--> Tag 15  * API/data strutures: 16  * Range (n1) <--> Sequence container 17  * std::vector <--> Vector container 18  * Range (n2) <--> Tree container 19  * 20  * n1: single contiguous subrange 21  * n2: multiple subranges 22  * 23  * Conventions 24  * =========== 25  * There are parts of MOAB data structures that need to be stored to Damsel that aren't represented 26  * in the Damsel data model, e.g. dense vs. sparse storage type, set tracking flags. 27  * - We need to store these as tags in Damsel. 28  * - Since Damsel tags need to have a MOAB counterpart, we have to create those as tag data in MOAB 29  * too (duplicating the data in the data structures, bummer). 30  * - Because we may want to use these tags for multiple Damsel writes/models, we create the 31  * MOAB-side tags in the WriteDamsel constructor, not in the init_tags function that's called for 32  * every write 33  * - Conventional tags have names prefixed with mbdmsl_ to avoid name conflicts with other MOAB 34  * tags. Here we list the conventional tags used by MOAB's Damsel reader/writer. 35  * 36  * Tag name Tag char's (storage type, data type, length, def val) Values, 37  * used for what 38  * -------- ----------------------------------------------------- 39  * -------------------- mbdmsl_XCOORDS dense; double[1]; 0.0 MOAB vertex x coordinate 40  * mbdmsl_YCOORDS dense; double[1]; 0.0 MOAB 41  * vertex y coordinate mbdmsl_ZCOORDS dense; double[1]; 0.0 MOAB vertex z coordinate 42  * mbdmsl_COLL_FLAGS sparse; char; 1; 0x0 bit 0: 43  * 0=set-type, 1=vector-type 1: 1=tracking, 0=not tracking mbdmsl_PARENTS sparse; handle; var; 44  * (list of parent sets) mbdmsl_CHILDS sparse; handle; var; (list of child sets) 45  * 46  * 47  * 48  */ 49  50 #include "WriteDamsel.hpp" 51  52 #include "DamselUtil.hpp" 53 #include "damsel.h" 54 #include <cassert> 55 #include "moab/Interface.hpp" 56 #include "moab/Core.hpp" 57 #include "moab/Range.hpp" 58 #include "moab/Error.hpp" 59 #include "moab/WriteUtilIface.hpp" 60 #include "MBTagConventions.hpp" 61 #include "EntitySequence.hpp" 62 #include "Internals.hpp" 63 #include "DenseTag.hpp" 64 #include "SparseTag.hpp" 65  66 namespace moab 67 { 68  69 WriterIface* WriteDamsel::factory( Interface* iface ) 70 { 71  return new WriteDamsel( iface ); 72 } 73  74 WriteDamsel::WriteDamsel( Interface* impl ) 75  : mbImpl( impl ), mWriteIface( NULL ), sequenceManager( NULL ), dU(), DAMSEL_FLAGS( DAMSEL_IS_TRACKING ) 76 { 77  assert( impl != NULL ); 78  79  impl->query_interface( mWriteIface ); 80  assert( mWriteIface ); 81  82  sequenceManager = dynamic_cast< Core* >( impl )->sequence_manager(); 83  assert( sequenceManager ); 84  85  ErrorCode rval = 86  mbImpl->tag_get_handle( "mbdmsl_XCOORDS", 1, MB_TYPE_DOUBLE, dU.xcoordsTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR_CONT( rval, "Failed to create_tag mbdmsl_XCOORDS" ); 87  dU.xcoordsTag.tagType = MB_TAG_ANY; 88  dU.tagMap.push_back( dU.xcoordsTag ); 89  rval = 90  mbImpl->tag_get_handle( "mbdmsl_YCOORDS", 1, MB_TYPE_DOUBLE, dU.ycoordsTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR_CONT( rval, "Failed to create_tag mbdmsl_YCOORDS" ); 91  dU.ycoordsTag.tagType = MB_TAG_ANY; 92  dU.tagMap.push_back( dU.ycoordsTag ); 93  94  rval = 95  mbImpl->tag_get_handle( "mbdmsl_ZCOORDS", 1, MB_TYPE_DOUBLE, dU.zcoordsTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR_CONT( rval, "Failed to create_tag mbdmsl_ZCOORDS" ); 96  dU.zcoordsTag.tagType = MB_TAG_ANY; 97  dU.tagMap.push_back( dU.zcoordsTag ); 98  99  rval = mbImpl->tag_get_handle( "mbdmsl_COLL_FLAGS", 1, MB_TYPE_INTEGER, dU.collFlagsTag.mTagh, 100  MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR_CONT( rval, "Failed to create_tag mbdmsl_COLL_FLAGS" ); 101  dU.collFlagsTag.tagType = MB_TAG_ANY; 102  dU.tagMap.push_back( dU.collFlagsTag ); 103  104  /* 105  rval = mbImpl->tag_get_handle("mbdmsl_PARENTS", 1, MB_TYPE_HANDLE, 106  dU.parentsTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT | 107  MB_TAG_VARLEN);MB_CHK_SET_ERR_CONT(rval, "Failed to create_tag mbdmsl_PARENTS"); 108  dU.parentsTag.tagType = MB_TAG_DENSE; 109  dU.tagMap.push_back(dU.parentsTag); 110  111  rval = mbImpl->tag_get_handle("mbdmsl_CHILDREN", 1, MB_TYPE_HANDLE, 112  dU.childrenTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT | 113  MB_TAG_VARLEN);MB_CHK_SET_ERR_CONT(rval, "Failed to create_tag mbdmsl_CHILDREN"); 114  dU.childrenTag.tagType = MB_TAG_DENSE; 115  dU.tagMap.push_back(dU.childrenTag); 116  */ 117  118  dU.moabHandleType = ( sizeof( EntityHandle ) == 64 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 ); 119 } 120  121 WriteDamsel::~WriteDamsel() 122 { 123  if( mWriteIface ) mbImpl->release_interface( mWriteIface ); 124 } 125  126 ErrorCode WriteDamsel::write_file( const char* file_name, 127  const bool /* overwrite */, 128  const FileOptions& opts, 129  const EntityHandle* meshset_list, 130  const int num_sets, 131  const std::vector< std::string >& /* qa_records */, 132  const Tag* /* tag_list */, 133  int /* num_tags */, 134  int /* requested_output_dimension */ ) 135 { 136  // Gather all entities into one big range 137  Range all_ents; 138  ErrorCode rval; 139  damsel_err_t err; 140  141  dU.dmslLib = DMSLlib_init(); 142  143  // Create a damsel model 144  dU.dmslModel = 145  DMSLmodel_create( sizeof( EntityHandle ) == 8 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 ); 146  147  // Attach to a file, since we need it for creating containers 148  MPI_Comm comm = MPI_COMM_WORLD; 149  unlink( file_name ); 150  err = DMSLmodel_attach( dU.dmslModel, file_name, comm, NULL ); 151  CHK_DMSL_ERR( err, "DMSLmodel_attach failed" ); 152  153  rval = mWriteIface->gather_entities( all_ents, meshset_list, num_sets );MB_CHK_SET_ERR( rval, "Gather entities failed in WriteDamsel" ); 154  155  if( all_ents.empty() ) return MB_SUCCESS; 156  157  // Create damsel tags for MOAB dense, sparse, and conventional tags 158  rval = init_tag_info();MB_CHK_ERR( rval ); 159  160  // Iterate through the groups of contiguous sequences of handles 161  RangeSeqIntersectIter rsi( sequenceManager ); 162  rval = rsi.init( all_ents.begin(), all_ents.end() ); 163  164  while( MB_SUCCESS == rval ) 165  { 166  // Write subrange of things to damsel: map handles, map entity definition data 167  // (connectivity/coords/set contents), map dense tags 168  rval = write_subrange( rsi );MB_CHK_SET_ERR( rval, "Failed to write subrange" ); 169  170  rval = rsi.step(); 171  while( MB_ENTITY_NOT_FOUND == rval ) 172  rval = rsi.step(); 173  } 174  175  // Write sparse tags 176  rval = map_sparse_tags();MB_CHK_SET_ERR( rval, "Failed to write sparse tags" ); 177  178  // damsel_request_t request; 179  // err = DMSLmodel_transfer_async(dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE, &request); 180  err = DMSLmodel_transfer_sync( dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE ); 181  CHK_DMSL_ERR( err, "DMSLmodel_transfer_asynch failed" ); 182  183  // damsel_status_t status; 184  // err = DMSLmodel_wait(request, &status);CHK_DMSL_ERR(err, "DMSLmodel_wait failed"); 185  186  DMSLmodel_close( dU.dmslModel ); 187  188  DMSLlib_finalize( dU.dmslLib ); 189  190  // We should be done 191  return MB_SUCCESS; 192 } 193  194 ErrorCode WriteDamsel::init_tag_info() 195 { 196  // Initialize allTags and tagIndices 197  std::vector< Tag > tmp_mtags; 198  ErrorCode rval = mbImpl->tag_get_tags( tmp_mtags );MB_CHK_SET_ERR( rval, "Failed to get all tag handles." ); 199  int dum_size; 200  damsel_err_t err; 201  202  // Define damsel tag handles for all dense/sparse tags 203  for( std::vector< Tag >::iterator vit = tmp_mtags.begin(); vit != tmp_mtags.end(); ++vit ) 204  { 205  if( ( ( *vit )->get_storage_type() != MB_TAG_DENSE && ( *vit )->get_storage_type() != MB_TAG_SPARSE ) || 206  mbImpl->tag_get_length( *vit, dum_size ) == MB_VARIABLE_DATA_LENGTH || dum_size != 1 ) 207  { 208  std::cerr << "Warning: tag " << ( *vit )->get_name() 209  << "is not of type dense or sparse, and is not currently supported by the " 210  "damsel writer." 211  << std::endl; 212  continue; 213  } 214  215  std::vector< DamselUtil::tinfo >::iterator vit2 = 216  std::find_if( dU.tagMap.begin(), dU.tagMap.end(), DamselUtil::MtagP< DamselUtil::tinfo >( *vit ) ); 217  218  if( vit2 != dU.tagMap.end() && ( *vit2 ).tagType == MB_TAG_ANY ) 219  // Conventional tag - skip 220  continue; 221  222  else if( vit2 == dU.tagMap.end() ) 223  { 224  // Create a damsel counterpart for this tag 225  Tag thandle = *vit; 226  err = DMSLtag_define( dU.dmslModel, (damsel_handle_ptr)&thandle, 227  DamselUtil::mtod_data_type[( *vit )->get_data_type()], ( *vit )->get_name().c_str() ); 228  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" ); 229  dU.tagMap.push_back( DamselUtil::tinfo( thandle, 0, ( *vit )->get_storage_type() ) ); 230  } 231  else 232  { 233  // Assert there's a corresponding moab tag handle 234  assert( ( *vit2 ).mTagh ); 235  } 236  } 237  238  // Do the same for conventional tags: 239  // XCOORDS 240  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.xcoordsTag.mTagh ), 241  DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.xcoordsTag.mTagh->get_name().c_str() ); 242  dU.tagMap.push_back( dU.xcoordsTag ); 243  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" ); 244  245  // YCOORDS 246  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.ycoordsTag.mTagh ), 247  DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.ycoordsTag.mTagh->get_name().c_str() ); 248  dU.tagMap.push_back( dU.ycoordsTag ); 249  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" ); 250  251  // ZCOORDS 252  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.zcoordsTag.mTagh ), 253  DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.zcoordsTag.mTagh->get_name().c_str() ); 254  dU.tagMap.push_back( dU.zcoordsTag ); 255  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" ); 256  257  // COLL_FLAGS 258  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ), 259  DamselUtil::mtod_data_type[MB_TYPE_INTEGER], dU.collFlagsTag.mTagh->get_name().c_str() ); 260  dU.tagMap.push_back( dU.collFlagsTag ); 261  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" ); 262  263  /* 264  SKIP PARENTS/CHILDREN FOR NOW, UNTIL WE HAVE VAR LENGTH TAGS IN DAMSEL 265  266  // PARENTS 267  dU.parentsTagPair.second = DMSLtag_define(dU.dmslModel, 268  (damsel_handle_ptr)&(dU.collFlagsTagPair.first), 269  DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()], 270  (dU.parentsTagPair.first)->get_name().c_str()); 271  if (DAMSEL_TAG_INVALID == dtag) 272  MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " << 273  (dU.parentsTagPair.first)->get_name()); 274  275  // CHILDREN 276  dU.childrenTagPair.second = DMSLtag_define(dU.dmslModel, 277  (damsel_handle_ptr)&(dU.collFlagsTagPair.first), 278  DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()], 279  (dU.childrenTagPair.first)->get_name().c_str()); 280  if (DAMSEL_TAG_INVALID == dtag) 281  MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " << 282  (dU.childrenTagPair.first)->get_name()); 283  */ 284  285  // Map the tag handles in one big call 286  int num_tags = dU.tagMap.size(); 287  std::vector< Tag > moab_taghs; 288  moab_taghs.reserve( num_tags ); 289  for( std::vector< DamselUtil::tinfo >::iterator vit = dU.tagMap.begin(); vit != dU.tagMap.end(); ++vit ) 290  { 291  moab_taghs.push_back( ( *vit ).mTagh ); 292  } 293  294  damsel_container mtags = 295  DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&moab_taghs[0], moab_taghs.size() ); 296  std::cerr << "MOAB: created model container: mtags = " << mtags << std::endl; 297  298  err = DMSLmodel_map_handles_inventing_file_handles( mtags ); 299  CHK_DMSL_ERR( err, "Failed to map tag handles" ); 300  301  err = DMSLcontainer_release( mtags ); 302  CHK_DMSL_ERR( err, "Problem releasing tag handle container" ); 303  304  return MB_SUCCESS; 305 } 306  307 ErrorCode WriteDamsel::write_vertices( RangeSeqIntersectIter& rsi ) 308 { 309  // Write the vertices; these vertices will be in the same sequence and will be contiguous, 310  // guaranteed 311  EntityHandle start_vert = rsi.get_start_handle(), end_vert = rsi.get_end_handle(); 312  313  // Create a damsel container for these vertex handles 314  damsel_container vertex_cont = 315  DMSLcontainer_create_sequence( dU.dmslModel, start_vert, (int)( end_vert - start_vert + 1 ), 1 ); 316  std::cerr << "MOAB: created model container: vertex_cont = " << vertex_cont << std::endl; 317  if( DAMSEL_CONTAINER_INVALID == vertex_cont ) 318  MB_SET_ERR( MB_FAILURE, 319  "Failed to create vertex sequence for vertices starting with handle " << rsi.get_start_handle() ); 320  321  damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( vertex_cont ); 322  CHK_DMSL_ERR( err, "Failed to map handles" ); 323  324  // Define the entities to damsel 325  err = DMSLentity_define( vertex_cont, DAMSEL_ENTITY_TYPE_VERTEX, 1, vertex_cont ); 326  CHK_DMSL_ERR( err, "Failure in DMSLentity_define for vertices starting with handle " << rsi.get_start_handle() ); 327  328  // Get the vertex coordinates storage locations and pass to damsel 329  Range vert_range( start_vert, end_vert ); 330  double *xcoords = NULL, *ycoords = NULL, *zcoords = NULL; 331  int count; 332  ErrorCode rval = mbImpl->coords_iterate( vert_range.begin(), vert_range.end(), xcoords, ycoords, zcoords, count );MB_CHK_SET_ERR( rval, 333  "Failed to get coordinate iterator for vertices starting with handle " << rsi.get_start_handle() ); 334  if( count != (int)vert_range.size() ) 335  { 336  MB_SET_ERR( MB_FAILURE, "Vertex subrange not in the same sequence for vertices starting with handle " 337  << rsi.get_start_handle() ); 338  } 339  340  if( xcoords && !ycoords && !zcoords ) 341  { 342  // Interleaved 343  344  // Map the data to damsel 345  err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh ); 346  CHK_DMSL_ERR( err, "Failed to assign vertex coordinates tag for vertices starting with handle " 347  << rsi.get_start_handle() ); 348  } 349  else 350  { 351  // Map the data to damsel 352  err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh ); 353  CHK_DMSL_ERR( err, "Failed to assign vertex x coordinates tag for vertices starting with handle " 354  << rsi.get_start_handle() ); 355  err = DMSLmodel_map_tag( ycoords, vertex_cont, (damsel_handle_ptr)&dU.ycoordsTag.mTagh ); 356  CHK_DMSL_ERR( err, "Failed to assign vertex y coordinates tag for vertices starting with handle " 357  << rsi.get_start_handle() ); 358  err = DMSLmodel_map_tag( zcoords, vertex_cont, (damsel_handle_ptr)&dU.zcoordsTag.mTagh ); 359  CHK_DMSL_ERR( err, "Failed to assign vertex z coordinates tag for vertices starting with handle " 360  << rsi.get_start_handle() ); 361  } 362  363  // Write/map dense tags 364  rval = map_dense_tags( rsi, vertex_cont );MB_CHK_ERR( rval ); 365  366  err = DMSLcontainer_release( vertex_cont ); 367  CHK_DMSL_ERR( err, "Problem releasing vertex handle container" ); 368  369  return MB_SUCCESS; 370 } 371  372 ErrorCode WriteDamsel::write_entities( RangeSeqIntersectIter& rsi ) 373 { 374  // Write the entities; these entities will be in the same sequence and will be contiguous, 375  // guaranteed 376  EntityHandle start_ent = rsi.get_start_handle(), end_ent = rsi.get_end_handle(); 377  378  // Create a damsel container for these entity handles 379  damsel_container ent_cont; 380  ent_cont = DMSLcontainer_create_sequence( dU.dmslModel, start_ent, (int)( end_ent - start_ent + 1 ), 1 ); 381  std::cerr << "MOAB: created model container: ent_cont = " << ent_cont << std::endl; 382  if( DAMSEL_CONTAINER_INVALID == ent_cont ) MB_SET_ERR( MB_FAILURE, "Bad sequence returned by Damsel" ); 383  384  damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( ent_cont ); 385  CHK_DMSL_ERR( err, "Failed to map handles" ); 386  387  // Get # verts per entity and entity type 388  EntityType etype = mbImpl->type_from_handle( start_ent ); 389  assert( MBMAXTYPE != etype ); 390  int num_connect = rsi.get_sequence()->values_per_entity(); 391  assert( 0 < num_connect ); 392  393  // Get the connectivity storage location and pass to damsel 394  Range ent_range( start_ent, end_ent ); 395  int count; 396  EntityHandle* connect; 397  int verts_per_ent; 398  ErrorCode rval = mbImpl->connect_iterate( ent_range.begin(), ent_range.end(), connect, verts_per_ent, count );MB_CHK_SET_ERR( rval, 399  "Failed to get connect iterator for entities starting with handle " << rsi.get_start_handle() ); 400  if( count != (int)ent_range.size() ) 401  MB_SET_ERR( MB_FAILURE, "Entity subrange not in the same sequence for entities starting with handle " 402  << rsi.get_start_handle() ); 403  404  // Define the entities to damsel 405  err = DMSLentity_define_fast( ent_cont, DamselUtil::mtod_entity_type[etype], num_connect, (damsel_handle*)connect ); 406  CHK_DMSL_ERR( err, "DMSLentity_define failed for entities starting with handle " << rsi.get_start_handle() ); 407  408  // Write dense tags 409  rval = map_dense_tags( rsi, ent_cont );MB_CHK_ERR( rval ); 410  411  err = DMSLcontainer_release( ent_cont ); 412  CHK_DMSL_ERR( err, "Problem releasing entity handle container" ); 413  414  return MB_SUCCESS; 415 } 416  417 ErrorCode WriteDamsel::map_dense_tags( RangeSeqIntersectIter& rsi, damsel_container& ent_cont ) 418 { 419  // All dense_tags have been initialized before this, so here we just go through 420  // them and map data if there is any 421  const unsigned char* val_ptr; 422  ErrorCode rval = MB_SUCCESS; 423  std::vector< DamselUtil::tinfo >::iterator tagit; 424  damsel_err_t err; 425  for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit ) 426  { 427  if( ( *tagit ).tagType != MB_TAG_DENSE ) continue; 428  429  // Get a ptr to memory for this tag/sequence 430  DenseTag* dtag = dynamic_cast< DenseTag* >( ( *tagit ).mTagh ); 431  assert( dtag ); 432  rval = dtag->get_array( rsi.get_sequence(), val_ptr );MB_CHK_SET_ERR( rval, "Failed to get tag coordinates pointer for vertices starting with handle " 433  << rsi.get_start_handle() ); 434  435  // If ptr is NULL, no data for this tag in this sequence 436  if( !val_ptr ) continue; 437  438  // Else, register with damsel 439  err = DMSLmodel_map_tag( (void*)val_ptr, ent_cont, (damsel_handle_ptr)&dtag ); 440  CHK_DMSL_ERR( err, 441  "Failed to write coordinates tag for vertices starting with handle " << rsi.get_start_handle() ); 442  } 443  444  return rval; 445 } 446  447 ErrorCode WriteDamsel::map_sparse_tags() 448 { 449  // All sparse_tags have been initialized before this, so here we just go through 450  // them and map data if there is any 451  ErrorCode rval = MB_SUCCESS; 452  damsel_err_t err; 453  std::vector< DamselUtil::tinfo >::iterator tagit; 454  std::vector< unsigned char > tag_values; 455  std::vector< EntityHandle > tagged_ents; 456  damsel_container ent_cont; 457  for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit ) 458  { 459  if( ( *tagit ).tagType != MB_TAG_SPARSE ) continue; 460  // Get a ptr to memory for this tag/sequence 461  SparseTag* stag = dynamic_cast< SparseTag* >( ( *tagit ).mTagh ); 462  assert( stag ); 463  Range output_ents; 464  rval = stag->get_tagged_entities( sequenceManager, output_ents );MB_CHK_SET_ERR( rval, "Trouble getting tagged entities for tag " << stag->get_name() ); 465  466  // If no entities have this tag set, don't map it 467  if( output_ents.empty() ) continue; 468  469  // Else, register with damsel 470  // Allocate space for and get values 471  tag_values.resize( stag->get_size() * output_ents.size() ); 472  rval = mbImpl->tag_get_data( stag, output_ents, &tag_values[0] );MB_CHK_SET_ERR( rval, "Trouble getting tag values for tag " << stag->get_name() ); 473  474  // Build a vector of entity handles from the range, and a container from that 475  tagged_ents.resize( output_ents.size() ); 476  std::copy( output_ents.begin(), output_ents.end(), tagged_ents.begin() ); 477  ent_cont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&tagged_ents[0], tagged_ents.size() ); 478  std::cerr << "MOAB: created model container: sparse_tag_ent_cont = " << ent_cont << std::endl; 479  if( DAMSEL_CONTAINER_INVALID == ent_cont ) 480  MB_SET_ERR( MB_FAILURE, "Trouble creating entity handle container for tag " << stag->get_name() ); 481  482  // Now map it 483  err = DMSLmodel_map_tag( (void*)&tag_values[0], ent_cont, (damsel_handle_ptr)&stag ); 484  CHK_DMSL_ERR( err, "Failed to write tag " << stag->get_name() ); 485  486  err = DMSLcontainer_release( ent_cont ); 487  CHK_DMSL_ERR( err, "Problem releasing entity handle container" ); 488  } 489  490  return rval; 491 } 492  493 ErrorCode WriteDamsel::write_sets( RangeSeqIntersectIter& rsi ) 494 { 495  // Write the sets 496  ErrorCode rval = MB_SUCCESS; 497  std::vector< EntityHandle > ents; 498  damsel_container mcont; 499  damsel_err_t err; 500  unsigned int i, num_sets = rsi.get_end_handle() - rsi.get_start_handle() + 1; 501  std::vector< unsigned int > set_flags( num_sets, 0 ); 502  EntityHandle seth; 503  for( seth = rsi.get_start_handle(), i = 0; seth <= rsi.get_end_handle(); seth++, i++ ) 504  { 505  // Get all the entities in the set 506  ents.clear(); 507  rval = mbImpl->get_entities_by_handle( seth, ents );MB_CHK_SET_ERR( rval, "get_entities_by_handle failed for set " << seth ); 508  if( !ents.empty() ) 509  { 510  mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)&ents[0], ents.size() ); 511  } 512  else 513  { 514  mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)NULL, 0 ); 515  } 516  std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl; 517  518  // Get the set type (range or set) 519  unsigned int opts; 520  rval = mbImpl->get_meshset_options( seth, opts );MB_CHK_SET_ERR( rval, "Failed to get options for meshset " << seth ); 521  damsel_collection_type coll_type = 522  ( opts & MESHSET_SET ? DAMSEL_HANDLE_COLLECTION_TYPE_SET : DAMSEL_HANDLE_COLLECTION_TYPE_VECTOR ); 523  524  // Parents/children... 525  526  // Set flags 527  if( opts & MESHSET_TRACK_OWNER ) 528  set_flags[i] |= MESHSET_TRACK_OWNER; 529  else 530  set_flags[i] &= !MESHSET_TRACK_OWNER; 531  532  // Create the collection 533  DMSLcoll_create( dU.dmslModel, (damsel_handle_ptr)&seth, mcont, coll_type ); 534  535  // Release the container 536  err = DMSLcontainer_release( mcont ); 537  CHK_DMSL_ERR( err, "Problem releasing set entity handle container" ); 538  } 539  540  // Set the COLL_FLAGS tag, using assign (direct) 541  // Make a container of set handles... 542  mcont = DMSLcontainer_create_sequence( dU.dmslModel, rsi.get_start_handle(), num_sets, 1 ); 543  std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl; 544  545  // Assign the tags on them 546  err = DMSLmodel_map_tag( &set_flags[0], mcont, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ) ); 547  CHK_DMSL_ERR( err, "Failed to assign COLL_FLAGS tag for sets" ); 548  549  // Map set handles 550  err = DMSLmodel_map_handles_inventing_file_handles( mcont ); 551  CHK_DMSL_ERR( err, "Failed to map set handles" ); 552  553  // Map other dense tags 554  rval = map_dense_tags( rsi, mcont );MB_CHK_SET_ERR( rval, "Failed to map dense tags for sets" ); 555  556  return rval; 557 } 558  559 } // namespace moab