Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
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 
70 {
71  return new WriteDamsel( iface );
72 }
73 
75  : mbImpl( impl ), mWriteIface( NULL ), sequenceManager( NULL ), dU(), DAMSEL_FLAGS( DAMSEL_IS_TRACKING )
76 {
77  assert( impl != NULL );
78 
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" );
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" );
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" );
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" );
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 
122 {
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  MB_CHK_SET_ERR( mWriteIface->gather_entities( all_ents, meshset_list, num_sets ),
154  "Gather entities failed in WriteDamsel" );
155 
156  if( all_ents.empty() ) return MB_SUCCESS;
157 
158  // Create damsel tags for MOAB dense, sparse, and conventional tags
160 
161  // Iterate through the groups of contiguous sequences of handles
163  rval = rsi.init( all_ents.begin(), all_ents.end() );
164 
165  while( MB_SUCCESS == rval )
166  {
167  // Write subrange of things to damsel: map handles, map entity definition data
168  // (connectivity/coords/set contents), map dense tags
169  MB_CHK_SET_ERR( write_subrange( rsi ), "Failed to write subrange" );
170 
171  rval = rsi.step();
172  while( MB_ENTITY_NOT_FOUND == rval )
173  rval = rsi.step();
174  }
175 
176  // Write sparse tags
177  MB_CHK_SET_ERR( map_sparse_tags(), "Failed to write sparse tags" );
178 
179  // damsel_request_t request;
180  // err = DMSLmodel_transfer_async(dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE, &request);
181  err = DMSLmodel_transfer_sync( dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE );
182  CHK_DMSL_ERR( err, "DMSLmodel_transfer_asynch failed" );
183 
184  // damsel_status_t status;
185  // err = DMSLmodel_wait(request, &status);CHK_DMSL_ERR(err, "DMSLmodel_wait failed");
186 
187  DMSLmodel_close( dU.dmslModel );
188 
189  DMSLlib_finalize( dU.dmslLib );
190 
191  // We should be done
192  return MB_SUCCESS;
193 }
194 
196 {
197  // Initialize allTags and tagIndices
198  std::vector< Tag > tmp_mtags;
199  MB_CHK_SET_ERR( mbImpl->tag_get_tags( tmp_mtags ), "Failed to get all tag handles." );
200  int dum_size;
201  damsel_err_t err;
202 
203  // Define damsel tag handles for all dense/sparse tags
204  for( std::vector< Tag >::iterator vit = tmp_mtags.begin(); vit != tmp_mtags.end(); ++vit )
205  {
206  if( ( ( *vit )->get_storage_type() != MB_TAG_DENSE && ( *vit )->get_storage_type() != MB_TAG_SPARSE ) ||
207  mbImpl->tag_get_length( *vit, dum_size ) == MB_VARIABLE_DATA_LENGTH || dum_size != 1 )
208  {
209  std::cerr << "Warning: tag " << ( *vit )->get_name()
210  << "is not of type dense or sparse, and is not currently supported by the "
211  "damsel writer."
212  << std::endl;
213  continue;
214  }
215 
216  std::vector< DamselUtil::tinfo >::iterator vit2 =
217  std::find_if( dU.tagMap.begin(), dU.tagMap.end(), DamselUtil::MtagP< DamselUtil::tinfo >( *vit ) );
218 
219  if( vit2 != dU.tagMap.end() && ( *vit2 ).tagType == MB_TAG_ANY )
220  // Conventional tag - skip
221  continue;
222 
223  else if( vit2 == dU.tagMap.end() )
224  {
225  // Create a damsel counterpart for this tag
226  Tag thandle = *vit;
227  err = DMSLtag_define( dU.dmslModel, (damsel_handle_ptr)&thandle,
228  DamselUtil::mtod_data_type[( *vit )->get_data_type()], ( *vit )->get_name().c_str() );
229  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
230  dU.tagMap.push_back( DamselUtil::tinfo( thandle, 0, ( *vit )->get_storage_type() ) );
231  }
232  else
233  {
234  // Assert there's a corresponding moab tag handle
235  assert( ( *vit2 ).mTagh );
236  }
237  }
238 
239  // Do the same for conventional tags:
240  // XCOORDS
241  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.xcoordsTag.mTagh ),
243  dU.tagMap.push_back( dU.xcoordsTag );
244  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
245 
246  // YCOORDS
247  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.ycoordsTag.mTagh ),
249  dU.tagMap.push_back( dU.ycoordsTag );
250  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
251 
252  // ZCOORDS
253  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.zcoordsTag.mTagh ),
255  dU.tagMap.push_back( dU.zcoordsTag );
256  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
257 
258  // COLL_FLAGS
259  err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ),
261  dU.tagMap.push_back( dU.collFlagsTag );
262  CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
263 
264  /*
265  SKIP PARENTS/CHILDREN FOR NOW, UNTIL WE HAVE VAR LENGTH TAGS IN DAMSEL
266 
267  // PARENTS
268  dU.parentsTagPair.second = DMSLtag_define(dU.dmslModel,
269  (damsel_handle_ptr)&(dU.collFlagsTagPair.first),
270  DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()],
271  (dU.parentsTagPair.first)->get_name().c_str());
272  if (DAMSEL_TAG_INVALID == dtag)
273  MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " <<
274  (dU.parentsTagPair.first)->get_name());
275 
276  // CHILDREN
277  dU.childrenTagPair.second = DMSLtag_define(dU.dmslModel,
278  (damsel_handle_ptr)&(dU.collFlagsTagPair.first),
279  DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()],
280  (dU.childrenTagPair.first)->get_name().c_str());
281  if (DAMSEL_TAG_INVALID == dtag)
282  MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " <<
283  (dU.childrenTagPair.first)->get_name());
284  */
285 
286  // Map the tag handles in one big call
287  int num_tags = dU.tagMap.size();
288  std::vector< Tag > moab_taghs;
289  moab_taghs.reserve( num_tags );
290  for( std::vector< DamselUtil::tinfo >::iterator vit = dU.tagMap.begin(); vit != dU.tagMap.end(); ++vit )
291  {
292  moab_taghs.push_back( ( *vit ).mTagh );
293  }
294 
295  damsel_container mtags =
296  DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&moab_taghs[0], moab_taghs.size() );
297  std::cerr << "MOAB: created model container: mtags = " << mtags << std::endl;
298 
299  err = DMSLmodel_map_handles_inventing_file_handles( mtags );
300  CHK_DMSL_ERR( err, "Failed to map tag handles" );
301 
302  err = DMSLcontainer_release( mtags );
303  CHK_DMSL_ERR( err, "Problem releasing tag handle container" );
304 
305  return MB_SUCCESS;
306 }
307 
309 {
310  // Write the vertices; these vertices will be in the same sequence and will be contiguous,
311  // guaranteed
312  EntityHandle start_vert = rsi.get_start_handle(), end_vert = rsi.get_end_handle();
313 
314  // Create a damsel container for these vertex handles
315  damsel_container vertex_cont =
316  DMSLcontainer_create_sequence( dU.dmslModel, start_vert, (int)( end_vert - start_vert + 1 ), 1 );
317  std::cerr << "MOAB: created model container: vertex_cont = " << vertex_cont << std::endl;
318  if( DAMSEL_CONTAINER_INVALID == vertex_cont )
319  MB_SET_ERR( MB_FAILURE,
320  "Failed to create vertex sequence for vertices starting with handle " << rsi.get_start_handle() );
321 
322  damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( vertex_cont );
323  CHK_DMSL_ERR( err, "Failed to map handles" );
324 
325  // Define the entities to damsel
326  err = DMSLentity_define( vertex_cont, DAMSEL_ENTITY_TYPE_VERTEX, 1, vertex_cont );
327  CHK_DMSL_ERR( err, "Failure in DMSLentity_define for vertices starting with handle " << rsi.get_start_handle() );
328 
329  // Get the vertex coordinates storage locations and pass to damsel
330  Range vert_range( start_vert, end_vert );
331  double *xcoords = NULL, *ycoords = NULL, *zcoords = NULL;
332  int count;
333  MB_CHK_SET_ERR( mbImpl->coords_iterate( vert_range.begin(), vert_range.end(), xcoords, ycoords, zcoords, count ),
334  "Failed to get coordinate iterator for vertices starting with handle " << rsi.get_start_handle() );
335  if( count != (int)vert_range.size() )
336  {
337  MB_SET_ERR( MB_FAILURE, "Vertex subrange not in the same sequence for vertices starting with handle "
338  << rsi.get_start_handle() );
339  }
340 
341  if( xcoords && !ycoords && !zcoords )
342  {
343  // Interleaved
344 
345  // Map the data to damsel
346  err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh );
347  CHK_DMSL_ERR( err, "Failed to assign vertex coordinates tag for vertices starting with handle "
348  << rsi.get_start_handle() );
349  }
350  else
351  {
352  // Map the data to damsel
353  err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh );
354  CHK_DMSL_ERR( err, "Failed to assign vertex x coordinates tag for vertices starting with handle "
355  << rsi.get_start_handle() );
356  err = DMSLmodel_map_tag( ycoords, vertex_cont, (damsel_handle_ptr)&dU.ycoordsTag.mTagh );
357  CHK_DMSL_ERR( err, "Failed to assign vertex y coordinates tag for vertices starting with handle "
358  << rsi.get_start_handle() );
359  err = DMSLmodel_map_tag( zcoords, vertex_cont, (damsel_handle_ptr)&dU.zcoordsTag.mTagh );
360  CHK_DMSL_ERR( err, "Failed to assign vertex z coordinates tag for vertices starting with handle "
361  << rsi.get_start_handle() );
362  }
363 
364  // Write/map dense tags
365  MB_CHK_ERR( map_dense_tags( rsi, vertex_cont ) );
366 
367  err = DMSLcontainer_release( vertex_cont );
368  CHK_DMSL_ERR( err, "Problem releasing vertex handle container" );
369 
370  return MB_SUCCESS;
371 }
372 
374 {
375  // Write the entities; these entities will be in the same sequence and will be contiguous,
376  // guaranteed
377  EntityHandle start_ent = rsi.get_start_handle(), end_ent = rsi.get_end_handle();
378 
379  // Create a damsel container for these entity handles
380  damsel_container ent_cont;
381  ent_cont = DMSLcontainer_create_sequence( dU.dmslModel, start_ent, (int)( end_ent - start_ent + 1 ), 1 );
382  std::cerr << "MOAB: created model container: ent_cont = " << ent_cont << std::endl;
383  if( DAMSEL_CONTAINER_INVALID == ent_cont ) MB_SET_ERR( MB_FAILURE, "Bad sequence returned by Damsel" );
384 
385  damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( ent_cont );
386  CHK_DMSL_ERR( err, "Failed to map handles" );
387 
388  // Get # verts per entity and entity type
389  EntityType etype = mbImpl->type_from_handle( start_ent );
390  assert( MBMAXTYPE != etype );
391  int num_connect = rsi.get_sequence()->values_per_entity();
392  assert( 0 < num_connect );
393 
394  // Get the connectivity storage location and pass to damsel
395  Range ent_range( start_ent, end_ent );
396  int count;
397  EntityHandle* connect;
398  int verts_per_ent;
399  MB_CHK_SET_ERR( mbImpl->connect_iterate( ent_range.begin(), ent_range.end(), connect, verts_per_ent, count ),
400  "Failed to get connect iterator for entities starting with handle " << rsi.get_start_handle() );
401  if( count != (int)ent_range.size() )
402  MB_SET_ERR( MB_FAILURE, "Entity subrange not in the same sequence for entities starting with handle "
403  << rsi.get_start_handle() );
404 
405  // Define the entities to damsel
406  err = DMSLentity_define_fast( ent_cont, DamselUtil::mtod_entity_type[etype], num_connect, (damsel_handle*)connect );
407  CHK_DMSL_ERR( err, "DMSLentity_define failed for entities starting with handle " << rsi.get_start_handle() );
408 
409  // Write dense tags
410  MB_CHK_ERR( map_dense_tags( rsi, ent_cont ) );
411 
412  err = DMSLcontainer_release( ent_cont );
413  CHK_DMSL_ERR( err, "Problem releasing entity handle container" );
414 
415  return MB_SUCCESS;
416 }
417 
419 {
420  // All dense_tags have been initialized before this, so here we just go through
421  // them and map data if there is any
422  const unsigned char* val_ptr;
423  ErrorCode rval = MB_SUCCESS;
424  std::vector< DamselUtil::tinfo >::iterator tagit;
425  damsel_err_t err;
426  for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit )
427  {
428  if( ( *tagit ).tagType != MB_TAG_DENSE ) continue;
429 
430  // Get a ptr to memory for this tag/sequence
431  DenseTag* dtag = dynamic_cast< DenseTag* >( ( *tagit ).mTagh );
432  assert( dtag );
433  MB_CHK_SET_ERR( dtag->get_array( rsi.get_sequence(), val_ptr ),
434  "Failed to get tag coordinates pointer for vertices starting with handle "
435  << rsi.get_start_handle() );
436 
437  // If ptr is NULL, no data for this tag in this sequence
438  if( !val_ptr ) continue;
439 
440  // Else, register with damsel
441  err = DMSLmodel_map_tag( (void*)val_ptr, ent_cont, (damsel_handle_ptr)&dtag );
442  CHK_DMSL_ERR( err,
443  "Failed to write coordinates tag for vertices starting with handle " << rsi.get_start_handle() );
444  }
445 
446  return rval;
447 }
448 
450 {
451  // All sparse_tags have been initialized before this, so here we just go through
452  // them and map data if there is any
453  ErrorCode rval = MB_SUCCESS;
454  damsel_err_t err;
455  std::vector< DamselUtil::tinfo >::iterator tagit;
456  std::vector< unsigned char > tag_values;
457  std::vector< EntityHandle > tagged_ents;
458  damsel_container ent_cont;
459  for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit )
460  {
461  if( ( *tagit ).tagType != MB_TAG_SPARSE ) continue;
462  // Get a ptr to memory for this tag/sequence
463  SparseTag* stag = dynamic_cast< SparseTag* >( ( *tagit ).mTagh );
464  assert( stag );
465  Range output_ents;
466  MB_CHK_SET_ERR( stag->get_tagged_entities( sequenceManager, output_ents ),
467  "Trouble getting tagged entities for tag " << stag->get_name() );
468 
469  // If no entities have this tag set, don't map it
470  if( output_ents.empty() ) continue;
471 
472  // Else, register with damsel
473  // Allocate space for and get values
474  tag_values.resize( stag->get_size() * output_ents.size() );
475  MB_CHK_SET_ERR( mbImpl->tag_get_data( stag, output_ents, &tag_values[0] ),
476  "Trouble getting tag values for tag " << stag->get_name() );
477 
478  // Build a vector of entity handles from the range, and a container from that
479  tagged_ents.resize( output_ents.size() );
480  std::copy( output_ents.begin(), output_ents.end(), tagged_ents.begin() );
481  ent_cont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&tagged_ents[0], tagged_ents.size() );
482  std::cerr << "MOAB: created model container: sparse_tag_ent_cont = " << ent_cont << std::endl;
483  if( DAMSEL_CONTAINER_INVALID == ent_cont )
484  MB_SET_ERR( MB_FAILURE, "Trouble creating entity handle container for tag " << stag->get_name() );
485 
486  // Now map it
487  err = DMSLmodel_map_tag( (void*)&tag_values[0], ent_cont, (damsel_handle_ptr)&stag );
488  CHK_DMSL_ERR( err, "Failed to write tag " << stag->get_name() );
489 
490  err = DMSLcontainer_release( ent_cont );
491  CHK_DMSL_ERR( err, "Problem releasing entity handle container" );
492  }
493 
494  return rval;
495 }
496 
498 {
499  // Write the sets
500  ErrorCode rval = MB_SUCCESS;
501  std::vector< EntityHandle > ents;
502  damsel_container mcont;
503  damsel_err_t err;
504  unsigned int i, num_sets = rsi.get_end_handle() - rsi.get_start_handle() + 1;
505  std::vector< unsigned int > set_flags( num_sets, 0 );
506  EntityHandle seth;
507  for( seth = rsi.get_start_handle(), i = 0; seth <= rsi.get_end_handle(); seth++, i++ )
508  {
509  // Get all the entities in the set
510  ents.clear();
512  "get_entities_by_handle failed for set " << seth );
513  if( !ents.empty() )
514  {
515  mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)&ents[0], ents.size() );
516  }
517  else
518  {
519  mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)NULL, 0 );
520  }
521  std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl;
522 
523  // Get the set type (range or set)
524  unsigned int opts;
525  MB_CHK_SET_ERR( mbImpl->get_meshset_options( seth, opts ), "Failed to get options for meshset " << seth );
526  damsel_collection_type coll_type =
527  ( opts & MESHSET_SET ? DAMSEL_HANDLE_COLLECTION_TYPE_SET : DAMSEL_HANDLE_COLLECTION_TYPE_VECTOR );
528 
529  // Parents/children...
530 
531  // Set flags
532  if( opts & MESHSET_TRACK_OWNER )
533  set_flags[i] |= MESHSET_TRACK_OWNER;
534  else
535  set_flags[i] &= !MESHSET_TRACK_OWNER;
536 
537  // Create the collection
538  DMSLcoll_create( dU.dmslModel, (damsel_handle_ptr)&seth, mcont, coll_type );
539 
540  // Release the container
541  err = DMSLcontainer_release( mcont );
542  CHK_DMSL_ERR( err, "Problem releasing set entity handle container" );
543  }
544 
545  // Set the COLL_FLAGS tag, using assign (direct)
546  // Make a container of set handles...
547  mcont = DMSLcontainer_create_sequence( dU.dmslModel, rsi.get_start_handle(), num_sets, 1 );
548  std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl;
549 
550  // Assign the tags on them
551  err = DMSLmodel_map_tag( &set_flags[0], mcont, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ) );
552  CHK_DMSL_ERR( err, "Failed to assign COLL_FLAGS tag for sets" );
553 
554  // Map set handles
555  err = DMSLmodel_map_handles_inventing_file_handles( mcont );
556  CHK_DMSL_ERR( err, "Failed to map set handles" );
557 
558  // Map other dense tags
559  MB_CHK_SET_ERR( map_dense_tags( rsi, mcont ), "Failed to map dense tags for sets" );
560 
561  return rval;
562 }
563 
564 } // namespace moab