1
5
6 #include "moab/ParallelComm.hpp"
7
8 #include "ReadDamsel.hpp"
9
10 #include <cassert>
11 #include "moab/Interface.hpp"
12 #include "moab/Core.hpp"
13 #include "moab/Range.hpp"
14 #include "moab/Error.hpp"
15 #include "moab/ReadUtilIface.hpp"
16 #include "moab/FileOptions.hpp"
17 #include "MBTagConventions.hpp"
18 #include "EntitySequence.hpp"
19 #include "Internals.hpp"
20 #include "DenseTag.hpp"
21
22 namespace moab
23 {
24
25 ReaderIface* ReadDamsel::factory( Interface* iface )
26 {
27 return new ReadDamsel( iface );
28 }
29
30 ReadDamsel::ReadDamsel( Interface* impl )
31 : mbImpl( impl ), readMeshIface( NULL ), nativeParallel( false ), myPcomm( NULL ), mGlobalIdTag( 0 ), dU()
32 {
33 init();
34 }
35
36 ReadDamsel::~ReadDamsel()
37 {
38 if( readMeshIface ) mbImpl->release_interface( readMeshIface );
39
40 DMSLlib_finalize( dU.dmslLib );
41 }
42
43 ErrorCode ReadDamsel::init()
44 {
45 mbImpl->query_interface( readMeshIface );
46 assert( readMeshIface );
47
48 return MB_SUCCESS;
49 }
50
51 ErrorCode ReadDamsel::parse_options( const FileOptions& opts, bool& parallel )
52 {
53
54 bool use_mpio = ( MB_SUCCESS == opts.get_null_option( "USE_MPIO" ) );
55 ErrorCode rval = opts.match_option( "PARALLEL", "READ_PART" );
56 parallel = ( rval != MB_ENTITY_NOT_FOUND );
57 nativeParallel = ( rval == MB_SUCCESS );
58 if( use_mpio && !parallel )
59 {
60 MB_SET_ERR( MB_NOT_IMPLEMENTED, "'USE_MPIO' option specified w/out 'PARALLEL' option" );
61 }
62
63 return MB_SUCCESS;
64 }
65
66
67
68
69
70 ErrorCode ReadDamsel::load_file( const char* filename,
71 const EntityHandle* file_set,
72 const FileOptions& opts,
73 const ReaderIface::SubsetList* subset_list,
74 const Tag* file_id_tag )
75 {
76 ErrorCode rval;
77
78 rval = parse_options( opts, nativeParallel );
79 if( MB_SUCCESS != rval ) return rval;
80
81
82 dU.dmslLib = DMSLlib_init();
83
84
85 dU.dmslModel =
86 DMSLmodel_create( sizeof( EntityHandle ) == 8 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 );
87
88
89 #ifdef MOAB_HAVE_MPI
90 MPI_Comm comm = MPI_COMM_WORLD;
91 if( nativeParallel )
92 {
93 comm = myPcomm->proc_config().proc_comm();
94 }
95 #endif
96
97 damsel_err_t err;
98 err = DMSLmodel_attach( dU.dmslModel, filename, comm, NULL );
99 CHK_DMSL_ERR( err, "DMSLmodel_attach failed" );
100 err = DMSLmodel_populate( dU.dmslModel );
101 CHK_DMSL_ERR( err, "DMSLmodel_populate failed" );
102
103
104 int num_containers = 0, num_tag_infos = 0, num_ent_infos = 0;
105 DMSLmodel_get_tuple_count( dU.dmslModel, &num_containers, &num_tag_infos );
106 num_ent_infos = DMSLmodel_get_entity_count( dU.dmslModel );
107 int num_coll_infos = DMSLmodel_get_collection_count( dU.dmslModel );
108 CHK_DMSL_ERR( err, "DMSLmodel_get_collection_count failed" );
109 if( -1 == num_containers || -1 == num_tag_infos || -1 == num_ent_infos )
110 MB_SET_ERR( MB_FAILURE, "Bad count for containers/tags/ents" );
111
112 std::vector< damsel_entity_buf_type > ent_infos( num_ent_infos );
113 std::vector< damsel_collection_buf_type > coll_infos( num_coll_infos );
114 std::vector< damsel_tag_buf_type > tag_infos( num_tag_infos );
115 std::vector< damsel_container_buf_type > cont_infos( num_containers );
116 err = DMSLmodel_get_entity_infos( dU.dmslModel, &ent_infos[0] );
117 CHK_DMSL_ERR( err, "Failure getting entity infos" );
118 err = DMSLmodel_get_collection_infos( dU.dmslModel, &coll_infos[0] );
119 CHK_DMSL_ERR( err, "Failure getting collection infos" );
120 err = DMSLmodel_get_tag_infos( dU.dmslModel, &tag_infos[0] );
121 CHK_DMSL_ERR( err, "Failure getting tag infos" );
122 err = DMSLmodel_get_container_infos( dU.dmslModel, &cont_infos[0] );
123 CHK_DMSL_ERR( err, "Failure getting container infos" );
124
125
126 rval = process_tags( tag_infos );MB_CHK_SET_ERR( rval, "Error processing tags" );
127
128
183
184
185
186
187
188 std::vector< damsel_entity_buf_type >::iterator eiit;
189
190
191 for( eiit = ent_infos.begin(); eiit != ent_infos.end(); ++eiit )
192 {
193 if( ( *eiit ).entity_type == DAMSEL_ENTITY_TYPE_VERTEX )
194 {
195 rval = process_ent_info( *eiit );MB_CHK_ERR( rval );
196 }
197 }
198
199 for( eiit = ent_infos.begin(); eiit != ent_infos.end(); ++eiit )
200 {
201 if( ( *eiit ).entity_type != DAMSEL_ENTITY_TYPE_VERTEX )
202 {
203 rval = process_ent_info( *eiit );MB_CHK_ERR( rval );
204 }
205 }
206
207
247
248 return MB_SUCCESS;
249 }
250
251 ErrorCode ReadDamsel::read_tag_values( const char* file_name,
252 const char* tag_name,
253 const FileOptions& opts,
254 std::vector< int >& tag_values_out,
255 const SubsetList* subset_list )
256 {
257 return MB_FAILURE;
258 }
259
260 ErrorCode ReadDamsel::process_tags( std::vector< damsel_tag_buf_type >& tag_infos )
261 {
262 Tag tagh;
263 ErrorCode rval = MB_SUCCESS, tmp_rval;
264 for( std::vector< damsel_tag_buf_type >::iterator tit = tag_infos.begin(); tit != tag_infos.end(); ++tit )
265 {
266 if( DamselUtil::dtom_data_type[( *tit ).tag_datatype] == MB_TYPE_OPAQUE )
267 {
268 std::cout << "Damsel reader encountered opaque tag." << std::endl;
269 continue;
270 }
271
272 tmp_rval = mbImpl->tag_get_handle( ( *tit ).name, 1, DamselUtil::dtom_data_type[( *tit ).tag_datatype], tagh,
273 MB_TAG_CREAT | MB_TAG_DENSE );
274 if( MB_SUCCESS != tmp_rval )
275 rval = tmp_rval;
276 else
277 {
278 dU.tagMap.push_back( DamselUtil::tinfo( tagh, 0, MB_TAG_DENSE ) );
279
280 if( !strncmp( ( *tit ).name, "mbdmsl_", 7 ) )
281 {
282
283 if( !strcmp( ( *tit ).name, "mbdmsl_XCOORDS" ) )
284 dU.xcoordsTag = dU.tagMap.back();
285 else if( !strcmp( ( *tit ).name, "mbdmsl_YCOORDS" ) )
286 {
287 dU.ycoordsTag = dU.tagMap.back();
288 }
289 else if( !strcmp( ( *tit ).name, "mbdmsl_ZCOORDS" ) )
290 {
291 dU.zcoordsTag = dU.tagMap.back();
292 }
293 else if( !strcmp( ( *tit ).name, "mbdmsl_COLL_FLAGS" ) )
294 {
295 dU.collFlagsTag = dU.tagMap.back();
296 }
297 else if( !strcmp( ( *tit ).name, "mbdmsl_PARENTS" ) )
298 {
299 dU.parentsTag = dU.tagMap.back();
300 }
301 else if( !strcmp( ( *tit ).name, "mbdmsl_CHILDREN" ) )
302 {
303 dU.childrenTag = dU.tagMap.back();
304 }
305 else
306 {
307 rval = MB_FAILURE;
308 continue;
309 }
310 }
311 }
312 }
313
314 return rval;
315 }
316
317 ErrorCode ReadDamsel::process_ent_info( const damsel_entity_buf_type& einfo )
318 {
319
320 EntityHandle *connect, start_handle;
321 ErrorCode rval;
322 damsel_err_t err;
323 damsel_container app_cont;
324 Range these_ents;
325
326
327 #ifndef NDEBUG
328 Range fside_handles;
329 rval = DamselUtil::container_to_range( dU.dmslModel, const_cast< damsel_container& >( einfo.entity_container ),
330 fside_handles );
331 if( MB_SUCCESS != rval || fside_handles.size() != einfo.count || fside_handles.psize() != 1 ) return MB_FAILURE;
332 #endif
333
334 if( einfo.entity_type != DAMSEL_ENTITY_TYPE_VERTEX )
335 {
336
337 rval = readMeshIface->get_element_connect( einfo.count, einfo.vertices_per_entity,
338 DamselUtil::dtom_entity_type[einfo.entity_type], 0, start_handle,
339 connect );MB_CHK_ERR( rval );
340 these_ents.insert( start_handle, start_handle + einfo.count - 1 );
341
342
343 app_cont = DMSLcontainer_create_sequence( dU.dmslModel, einfo.count, start_handle, 1 );
344 err = DMSLmodel_map_handles( app_cont, einfo.entity_container );
345 CHK_DMSL_ERR( err, "Error returned mapping entity handles" );
346
347
348 assert( DMSLcontainer_count( einfo.vertex_container ) == (int)( einfo.vertices_per_entity * einfo.count ) );
349 rval = get_contents( dU.dmslModel, einfo.vertex_container, connect );MB_CHK_SET_ERR( rval, "Error returned mapping connectivity" );
350 }
351 else
352 {
353
354 int num_ctags = 0;
355 damsel_handle xcoord_dtag = DMSLselect_tag_by_name( dU.dmslModel, "mbdmsl_XCOORDS" );
356 if( xcoord_dtag ) num_ctags++;
357 damsel_handle ycoord_dtag = DMSLselect_tag_by_name( dU.dmslModel, "mbdmsl_YCOORDS" );
358 if( ycoord_dtag ) num_ctags++;
359 damsel_handle zcoord_dtag = DMSLselect_tag_by_name( dU.dmslModel, "mbdmsl_ZCOORDS" );
360 if( zcoord_dtag ) num_ctags++;
361
362
363 assert( einfo.vertices_per_entity == 1 );
364 std::vector< double* > coord_arrays;
365 rval = readMeshIface->get_node_coords( num_ctags, einfo.count, 0, start_handle, coord_arrays );MB_CHK_ERR( rval );
366
367 these_ents.insert( start_handle, start_handle + einfo.count - 1 );
368
369
370 app_cont = DMSLcontainer_create_sequence( dU.dmslModel, start_handle, einfo.count, 1 );
371 err = DMSLmodel_map_handles( app_cont, einfo.entity_container );
372 CHK_DMSL_ERR( err, "Trouble mapping entity handles" );
373
374
375 if( xcoord_dtag != 0 )
376 {
377 err = DMSLmodel_map_tag( coord_arrays[0], app_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh );
378 CHK_DMSL_ERR( err, "Trouble mapping x coordinate tag" );
379 }
380 if( ycoord_dtag != 0 )
381 {
382 err = DMSLmodel_map_tag( coord_arrays[1], app_cont, (damsel_handle_ptr)&dU.ycoordsTag.mTagh );
383 CHK_DMSL_ERR( err, "Trouble mapping y coordinate tag" );
384 }
385 if( zcoord_dtag != 0 )
386 {
387 err = DMSLmodel_map_tag( coord_arrays[2], app_cont, (damsel_handle_ptr)&dU.zcoordsTag.mTagh );
388 CHK_DMSL_ERR( err, "Trouble mapping z coordinate tag" );
389 }
390 }
391
392
393 dmHandleRMap.insert( DMSLcontainer_handle_at_position( einfo.entity_container, 0 ), start_handle, einfo.count );
394
395 rval = process_entity_tags( einfo.tag_count, einfo.tag_handle_container, app_cont, these_ents );
396
397 return rval;
398 }
399
400 ErrorCode ReadDamsel::process_entity_tags( int count,
401 damsel_container tag_container,
402 damsel_container app_cont,
403 Range& these_ents )
404 {
405
406 ErrorCode rval = MB_SUCCESS;
407 for( int i = 0; i < count; i++ )
408 {
409 damsel_handle dtagh = DMSLcontainer_handle_at_position( tag_container, i );
410
411
412 std::vector< DamselUtil::tinfo >::iterator vit =
413 std::find_if( dU.tagMap.begin(), dU.tagMap.end(), DamselUtil::DtagP< DamselUtil::tinfo >( dtagh ) );
414
415 if( ( *vit ).tagType == MB_TAG_ANY )
416 continue;
417 else if( vit == dU.tagMap.end() )
418 MB_SET_ERR( MB_FAILURE, "Failed to find tag" );
419
420 Tag tagh = ( *vit ).mTagh;
421 assert( tagh );
422 void* tag_data;
423 int ecount = these_ents.size();
424 rval = mbImpl->tag_iterate( tagh, these_ents.begin(), these_ents.end(), ecount, tag_data );MB_CHK_SET_ERR( rval, "Problem getting tag iterator" );
425 assert( ecount == (int)these_ents.size() );
426 damsel_err_t err = DMSLmodel_map_tag( tag_data, app_cont, (damsel_handle_ptr)&tagh );
427 CHK_DMSL_ERR( err, "Problem calling DMSLmodel_map_tag" );
428 }
429
430 return rval;
431 }
432
433 ErrorCode ReadDamsel::get_contents( damsel_model m, damsel_container c, Range& ents )
434 {
435 EntityHandle eh;
436 if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_SEQUENCE )
437 {
438 damsel_handle start;
439 size_t count, stride;
440 damsel_err_t err = DMSLcontainer_sequence_get_contents( m, c, &start, &count, &stride );
441 CHK_DMSL_ERR( err, "DMSLcontainer_sequence_get_contents" );
442 if( stride == 1 )
443 {
444 while( count )
445 {
446
447 RangeMap< damsel_handle, EntityHandle, 0 >::iterator beg = dmHandleRMap.lower_bound( start );
448 if( beg == dmHandleRMap.end() ) return MB_SUCCESS;
449 unsigned long diff = std::max( ( *beg ).begin - start, (damsel_handle)0 );
450 unsigned long num = std::min( count - diff, (size_t)( *beg ).count );
451 ents.insert( ( *beg ).begin + diff, ( *beg ).begin + diff + num - 1 );
452 count -= ( diff + num );
453 ++beg;
454 }
455 }
456 else
457 {
458 for( int i = count - 1; i >= 0; i-- )
459 {
460 if( dmHandleRMap.find( start + i, eh ) ) ents.insert( eh );
461 }
462 }
463 }
464 else if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_VECTOR )
465 {
466 damsel_handle* handle_ptr;
467 size_t count;
468 damsel_err_t err = DMSLcontainer_vector_get_contents( m, c, &handle_ptr, &count );
469 CHK_DMSL_ERR( err, "Trouble getting vector contents" );
470 for( int i = count - 1; i >= 0; i-- )
471 {
472 if( dmHandleRMap.find( handle_ptr[i], eh ) ) ents.insert( eh );
473 }
474 }
475 else if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_TREE )
476 {
477 damsel_handle_ptr node_ptr = NULL;
478 damsel_container cont = NULL;
479 while( DMSLcontainer_tree_get_contents( m, c, &node_ptr, &cont ) == DMSL_OK && cont )
480 {
481 ErrorCode rval = get_contents( m, c, ents );
482 if( MB_SUCCESS != rval ) return rval;
483 }
484 }
485
486 return MB_SUCCESS;
487 }
488
489 ErrorCode ReadDamsel::get_contents( damsel_model m, damsel_container c, EntityHandle* ents )
490 {
491 EntityHandle eh;
492 int ind = 0;
493
494 if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_SEQUENCE )
495 {
496 damsel_handle start;
497 size_t count, stride;
498 damsel_err_t err = DMSLcontainer_sequence_get_contents( m, c, &start, &count, &stride );
499 CHK_DMSL_ERR( err, "Problem calling DMSLcontainer_sequence_get_contents" );
500 if( stride == 1 )
501 {
502 while( count )
503 {
504
505 RangeMap< damsel_handle, EntityHandle, 0 >::iterator beg = dmHandleRMap.lower_bound( start );
506 if( beg == dmHandleRMap.end() ) return MB_SUCCESS;
507 unsigned int diff = std::max( ( *beg ).begin - start, (damsel_handle)0 );
508 unsigned int num = std::min( count - diff, (size_t)( *beg ).count );
509 for( EntityHandle hdl = ( *beg ).begin + diff; hdl <= (int)( *beg ).begin + diff + num - 1; hdl++ )
510 ents[ind++] = hdl;
511 count -= ( diff + num );
512 ++beg;
513 }
514 }
515 else
516 {
517 for( int i = count - 1; i >= 0; i-- )
518 {
519 if( dmHandleRMap.find( start + i, eh ) ) ents[i] = eh;
520 }
521 }
522 }
523 else if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_VECTOR )
524 {
525 damsel_handle_ptr handle_ptr;
526 size_t count;
527 damsel_err_t err = DMSLcontainer_vector_get_contents( m, c, &handle_ptr, &count );
528 CHK_DMSL_ERR( err, "Failed to get vector contents" );
529 for( int i = count - 1; i >= 0; i-- )
530 {
531 if( dmHandleRMap.find( handle_ptr[i], eh ) ) ents[i] = eh;
532 }
533 }
534 else if( DMSLcontainer_get_type( c ) == DAMSEL_HANDLE_CONTAINER_TYPE_TREE )
535 {
536 damsel_handle_ptr node_ptr = NULL;
537 damsel_container cont = NULL;
538 while( DMSLcontainer_tree_get_contents( m, c, &node_ptr, &cont ) == DMSL_OK && cont )
539 {
540 ErrorCode rval = get_contents( m, cont, ents );
541 if( MB_SUCCESS != rval ) return rval;
542 unsigned int num = DMSLcontainer_count( cont );
543 ents += num;
544 }
545 }
546
547 return MB_SUCCESS;
548 }
549
550
609
610 }