1
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
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 ,
128 const FileOptions& opts,
129 const EntityHandle* meshset_list,
130 const int num_sets,
131 const std::vector< std::string >& ,
132 const Tag* ,
133 int ,
134 int )
135 {
136
137 Range all_ents;
138 ErrorCode rval;
139 damsel_err_t err;
140
141 dU.dmslLib = DMSLlib_init();
142
143
144 dU.dmslModel =
145 DMSLmodel_create( sizeof( EntityHandle ) == 8 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 );
146
147
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
158 rval = init_tag_info();MB_CHK_ERR( rval );
159
160
161 RangeSeqIntersectIter rsi( sequenceManager );
162 rval = rsi.init( all_ents.begin(), all_ents.end() );
163
164 while( MB_SUCCESS == rval )
165 {
166
167
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
176 rval = map_sparse_tags();MB_CHK_SET_ERR( rval, "Failed to write sparse tags" );
177
178
179
180 err = DMSLmodel_transfer_sync( dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE );
181 CHK_DMSL_ERR( err, "DMSLmodel_transfer_asynch failed" );
182
183
184
185
186 DMSLmodel_close( dU.dmslModel );
187
188 DMSLlib_finalize( dU.dmslLib );
189
190
191 return MB_SUCCESS;
192 }
193
194 ErrorCode WriteDamsel::init_tag_info()
195 {
196
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
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
220 continue;
221
222 else if( vit2 == dU.tagMap.end() )
223 {
224
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
234 assert( ( *vit2 ).mTagh );
235 }
236 }
237
238
239
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
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
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
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
284
285
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
310
311 EntityHandle start_vert = rsi.get_start_handle(), end_vert = rsi.get_end_handle();
312
313
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
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
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
343
344
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
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
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
375
376 EntityHandle start_ent = rsi.get_start_handle(), end_ent = rsi.get_end_handle();
377
378
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
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
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
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
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
420
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
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
436 if( !val_ptr ) continue;
437
438
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
450
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
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
467 if( output_ents.empty() ) continue;
468
469
470
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
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
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
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
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
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
525
526
527 if( opts & MESHSET_TRACK_OWNER )
528 set_flags[i] |= MESHSET_TRACK_OWNER;
529 else
530 set_flags[i] &= !MESHSET_TRACK_OWNER;
531
532
533 DMSLcoll_create( dU.dmslModel, (damsel_handle_ptr)&seth, mcont, coll_type );
534
535
536 err = DMSLcontainer_release( mcont );
537 CHK_DMSL_ERR( err, "Problem releasing set entity handle container" );
538 }
539
540
541
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
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
550 err = DMSLmodel_map_handles_inventing_file_handles( mcont );
551 CHK_DMSL_ERR( err, "Failed to map set handles" );
552
553
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 }