Mesh Oriented datABase  (version 5.5.1)
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  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
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 
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 ),
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 ),
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 ),
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 ),
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 
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 
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 
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 
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 
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