MOAB: Mesh Oriented datABase  (version 5.3.1)
WriteDamsel.cpp
Go to the documentation of this file.
00001 /* WriteDamsel.cpp
00002  * The Damsel library provides mesh-aware parallel I/O; see
00003  * http://cucis.ece.northwestern.edu/projects/DAMSEL/ for details, though for now that site is
00004  * restricted to project participants.  Damsel uses a data model that's very similar to that used in
00005  * MOAB and ITAPS.  It uses the same basic data model concepts of entities, sets, tags, and
00006  * interface. In theory, we should be able to completely save/restore to/from Damsel any data that
00007  * can be saved/restored to/from our native HDF5-based reader/writer.
00008  *
00009  * Mapping between MOAB-Damsel data models
00010  * =======================================
00011  * Basic data model entities, MOAB <--> Damsel:
00012  *        Entity <--> Entity
00013  *     EntitySet <--> Collection
00014  *           Tag <--> Tag
00015  * API/data strutures:
00016  *          Range (n1) <--> Sequence container
00017  *         std::vector <--> Vector container
00018  *          Range (n2) <--> Tree container
00019  *
00020  * n1: single contiguous subrange
00021  * n2: multiple subranges
00022  *
00023  * Conventions
00024  * ===========
00025  * There are parts of MOAB data structures that need to be stored to Damsel that aren't represented
00026  * in the Damsel data model, e.g. dense vs. sparse storage type, set tracking flags.
00027  * - We need to store these as tags in Damsel.
00028  * - Since Damsel tags need to have a MOAB counterpart, we have to create those as tag data in MOAB
00029  * too (duplicating the data in the data structures, bummer).
00030  * - Because we may want to use these tags for multiple Damsel writes/models, we create the
00031  * MOAB-side tags in the WriteDamsel constructor, not in the init_tags function that's called for
00032  * every write
00033  * - Conventional tags have names prefixed with mbdmsl_ to avoid name conflicts with other MOAB
00034  * tags. Here we list the conventional tags used by MOAB's Damsel reader/writer.
00035  *
00036  * Tag name                   Tag char's (storage type, data type, length, def val)       Values,
00037  * used for what
00038  * --------                   -----------------------------------------------------
00039  * -------------------- mbdmsl_XCOORDS             dense; double[1]; 0.0 MOAB vertex x coordinate
00040  * mbdmsl_YCOORDS             dense; double[1]; 0.0                                       MOAB
00041  * vertex y coordinate mbdmsl_ZCOORDS             dense; double[1]; 0.0 MOAB vertex z coordinate
00042  * mbdmsl_COLL_FLAGS          sparse; char; 1; 0x0                                        bit 0:
00043  * 0=set-type, 1=vector-type 1: 1=tracking, 0=not tracking mbdmsl_PARENTS      sparse; handle; var;
00044  * (list of parent sets) mbdmsl_CHILDS       sparse; handle; var; (list of child sets)
00045  *
00046  *
00047  *
00048  */
00049 
00050 #include "WriteDamsel.hpp"
00051 
00052 #include "DamselUtil.hpp"
00053 #include "damsel.h"
00054 #include <cassert>
00055 #include "moab/Interface.hpp"
00056 #include "moab/Core.hpp"
00057 #include "moab/Range.hpp"
00058 #include "moab/Error.hpp"
00059 #include "moab/WriteUtilIface.hpp"
00060 #include "MBTagConventions.hpp"
00061 #include "EntitySequence.hpp"
00062 #include "Internals.hpp"
00063 #include "DenseTag.hpp"
00064 #include "SparseTag.hpp"
00065 
00066 namespace moab
00067 {
00068 
00069 WriterIface* WriteDamsel::factory( Interface* iface )
00070 {
00071     return new WriteDamsel( iface );
00072 }
00073 
00074 WriteDamsel::WriteDamsel( Interface* impl )
00075     : mbImpl( impl ), mWriteIface( NULL ), sequenceManager( NULL ), dU(), DAMSEL_FLAGS( DAMSEL_IS_TRACKING )
00076 {
00077     assert( impl != NULL );
00078 
00079     impl->query_interface( mWriteIface );
00080     assert( mWriteIface );
00081 
00082     sequenceManager = dynamic_cast< Core* >( impl )->sequence_manager();
00083     assert( sequenceManager );
00084 
00085     ErrorCode rval =
00086         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" );
00087     dU.xcoordsTag.tagType = MB_TAG_ANY;
00088     dU.tagMap.push_back( dU.xcoordsTag );
00089     rval =
00090         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" );
00091     dU.ycoordsTag.tagType = MB_TAG_ANY;
00092     dU.tagMap.push_back( dU.ycoordsTag );
00093 
00094     rval =
00095         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" );
00096     dU.zcoordsTag.tagType = MB_TAG_ANY;
00097     dU.tagMap.push_back( dU.zcoordsTag );
00098 
00099     rval = mbImpl->tag_get_handle( "mbdmsl_COLL_FLAGS", 1, MB_TYPE_INTEGER, dU.collFlagsTag.mTagh,
00100                                    MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR_CONT( rval, "Failed to create_tag mbdmsl_COLL_FLAGS" );
00101     dU.collFlagsTag.tagType = MB_TAG_ANY;
00102     dU.tagMap.push_back( dU.collFlagsTag );
00103 
00104     /*
00105       rval = mbImpl->tag_get_handle("mbdmsl_PARENTS", 1, MB_TYPE_HANDLE,
00106                                    dU.parentsTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT |
00107       MB_TAG_VARLEN);MB_CHK_SET_ERR_CONT(rval, "Failed to create_tag mbdmsl_PARENTS");
00108       dU.parentsTag.tagType = MB_TAG_DENSE;
00109       dU.tagMap.push_back(dU.parentsTag);
00110 
00111       rval = mbImpl->tag_get_handle("mbdmsl_CHILDREN", 1, MB_TYPE_HANDLE,
00112                                    dU.childrenTag.mTagh, MB_TAG_DENSE | MB_TAG_CREAT |
00113       MB_TAG_VARLEN);MB_CHK_SET_ERR_CONT(rval, "Failed to create_tag mbdmsl_CHILDREN");
00114       dU.childrenTag.tagType = MB_TAG_DENSE;
00115       dU.tagMap.push_back(dU.childrenTag);
00116     */
00117 
00118     dU.moabHandleType = ( sizeof( EntityHandle ) == 64 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 );
00119 }
00120 
00121 WriteDamsel::~WriteDamsel()
00122 {
00123     if( mWriteIface ) mbImpl->release_interface( mWriteIface );
00124 }
00125 
00126 ErrorCode WriteDamsel::write_file( const char* file_name, const bool /* overwrite */, const FileOptions& opts,
00127                                    const EntityHandle* meshset_list, const int num_sets,
00128                                    const std::vector< std::string >& /* qa_records */, const Tag* /* tag_list */,
00129                                    int /* num_tags */, int /* requested_output_dimension */ )
00130 {
00131     // Gather all entities into one big range
00132     Range all_ents;
00133     ErrorCode rval;
00134     damsel_err_t err;
00135 
00136     dU.dmslLib = DMSLlib_init();
00137 
00138     // Create a damsel model
00139     dU.dmslModel =
00140         DMSLmodel_create( sizeof( EntityHandle ) == 8 ? DAMSEL_HANDLE_TYPE_HANDLE64 : DAMSEL_HANDLE_TYPE_HANDLE32 );
00141 
00142     // Attach to a file, since we need it for creating containers
00143     MPI_Comm comm = MPI_COMM_WORLD;
00144     unlink( file_name );
00145     err = DMSLmodel_attach( dU.dmslModel, file_name, comm, NULL );
00146     CHK_DMSL_ERR( err, "DMSLmodel_attach failed" );
00147 
00148     rval = mWriteIface->gather_entities( all_ents, meshset_list, num_sets );MB_CHK_SET_ERR( rval, "Gather entities failed in WriteDamsel" );
00149 
00150     if( all_ents.empty() ) return MB_SUCCESS;
00151 
00152     // Create damsel tags for MOAB dense, sparse, and conventional tags
00153     rval = init_tag_info();MB_CHK_ERR( rval );
00154 
00155     // Iterate through the groups of contiguous sequences of handles
00156     RangeSeqIntersectIter rsi( sequenceManager );
00157     rval = rsi.init( all_ents.begin(), all_ents.end() );
00158 
00159     while( MB_SUCCESS == rval )
00160     {
00161         // Write subrange of things to damsel: map handles, map entity definition data
00162         // (connectivity/coords/set contents), map dense tags
00163         rval = write_subrange( rsi );MB_CHK_SET_ERR( rval, "Failed to write subrange" );
00164 
00165         rval = rsi.step();
00166         while( MB_ENTITY_NOT_FOUND == rval )
00167             rval = rsi.step();
00168     }
00169 
00170     // Write sparse tags
00171     rval = map_sparse_tags();MB_CHK_SET_ERR( rval, "Failed to write sparse tags" );
00172 
00173     // damsel_request_t request;
00174     // err = DMSLmodel_transfer_async(dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE, &request);
00175     err = DMSLmodel_transfer_sync( dU.dmslModel, DAMSEL_TRANSFER_TYPE_WRITE );
00176     CHK_DMSL_ERR( err, "DMSLmodel_transfer_asynch failed" );
00177 
00178     // damsel_status_t status;
00179     // err = DMSLmodel_wait(request, &status);CHK_DMSL_ERR(err, "DMSLmodel_wait failed");
00180 
00181     DMSLmodel_close( dU.dmslModel );
00182 
00183     DMSLlib_finalize( dU.dmslLib );
00184 
00185     // We should be done
00186     return MB_SUCCESS;
00187 }
00188 
00189 ErrorCode WriteDamsel::init_tag_info()
00190 {
00191     // Initialize allTags and tagIndices
00192     std::vector< Tag > tmp_mtags;
00193     ErrorCode rval = mbImpl->tag_get_tags( tmp_mtags );MB_CHK_SET_ERR( rval, "Failed to get all tag handles." );
00194     int dum_size;
00195     damsel_err_t err;
00196 
00197     // Define damsel tag handles for all dense/sparse tags
00198     for( std::vector< Tag >::iterator vit = tmp_mtags.begin(); vit != tmp_mtags.end(); ++vit )
00199     {
00200         if( ( ( *vit )->get_storage_type() != MB_TAG_DENSE && ( *vit )->get_storage_type() != MB_TAG_SPARSE ) ||
00201             mbImpl->tag_get_length( *vit, dum_size ) == MB_VARIABLE_DATA_LENGTH || dum_size != 1 )
00202         {
00203             std::cerr << "Warning: tag " << ( *vit )->get_name()
00204                       << "is not of type dense or sparse, and is not currently supported by the "
00205                          "damsel writer."
00206                       << std::endl;
00207             continue;
00208         }
00209 
00210         std::vector< DamselUtil::tinfo >::iterator vit2 =
00211             std::find_if( dU.tagMap.begin(), dU.tagMap.end(), DamselUtil::MtagP< DamselUtil::tinfo >( *vit ) );
00212 
00213         if( vit2 != dU.tagMap.end() && ( *vit2 ).tagType == MB_TAG_ANY )
00214             // Conventional tag - skip
00215             continue;
00216 
00217         else if( vit2 == dU.tagMap.end() )
00218         {
00219             // Create a damsel counterpart for this tag
00220             Tag thandle = *vit;
00221             err         = DMSLtag_define( dU.dmslModel, (damsel_handle_ptr)&thandle,
00222                                   DamselUtil::mtod_data_type[( *vit )->get_data_type()], ( *vit )->get_name().c_str() );
00223             CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
00224             dU.tagMap.push_back( DamselUtil::tinfo( thandle, 0, ( *vit )->get_storage_type() ) );
00225         }
00226         else
00227         {
00228             // Assert there's a corresponding moab tag handle
00229             assert( ( *vit2 ).mTagh );
00230         }
00231     }
00232 
00233     // Do the same for conventional tags:
00234     // XCOORDS
00235     err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.xcoordsTag.mTagh ),
00236                           DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.xcoordsTag.mTagh->get_name().c_str() );
00237     dU.tagMap.push_back( dU.xcoordsTag );
00238     CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
00239 
00240     // YCOORDS
00241     err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.ycoordsTag.mTagh ),
00242                           DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.ycoordsTag.mTagh->get_name().c_str() );
00243     dU.tagMap.push_back( dU.ycoordsTag );
00244     CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
00245 
00246     // ZCOORDS
00247     err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.zcoordsTag.mTagh ),
00248                           DamselUtil::mtod_data_type[MB_TYPE_DOUBLE], dU.zcoordsTag.mTagh->get_name().c_str() );
00249     dU.tagMap.push_back( dU.zcoordsTag );
00250     CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
00251 
00252     // COLL_FLAGS
00253     err = DMSLtag_define( dU.dmslModel, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ),
00254                           DamselUtil::mtod_data_type[MB_TYPE_INTEGER], dU.collFlagsTag.mTagh->get_name().c_str() );
00255     dU.tagMap.push_back( dU.collFlagsTag );
00256     CHK_DMSL_ERR( err, "Failure to get Damsel tag for MOAB tag" );
00257 
00258     /*
00259       SKIP PARENTS/CHILDREN FOR NOW, UNTIL WE HAVE VAR LENGTH TAGS IN DAMSEL
00260 
00261       // PARENTS
00262       dU.parentsTagPair.second = DMSLtag_define(dU.dmslModel,
00263       (damsel_handle_ptr)&(dU.collFlagsTagPair.first),
00264                                                DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()],
00265                                                (dU.parentsTagPair.first)->get_name().c_str());
00266       if (DAMSEL_TAG_INVALID == dtag)
00267         MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " <<
00268       (dU.parentsTagPair.first)->get_name());
00269 
00270       // CHILDREN
00271       dU.childrenTagPair.second = DMSLtag_define(dU.dmslModel,
00272       (damsel_handle_ptr)&(dU.collFlagsTagPair.first),
00273                                                DamselUtil::mtod_data_type[(dU.collFlagsTagPair.first)->get_data_type()],
00274                                                (dU.childrenTagPair.first)->get_name().c_str());
00275       if (DAMSEL_TAG_INVALID == dtag)
00276         MB_SET_ERR(MB_FAILURE, "Failure to get Damsel tag for MOAB tag " <<
00277       (dU.childrenTagPair.first)->get_name());
00278     */
00279 
00280     // Map the tag handles in one big call
00281     int num_tags = dU.tagMap.size();
00282     std::vector< Tag > moab_taghs;
00283     moab_taghs.reserve( num_tags );
00284     for( std::vector< DamselUtil::tinfo >::iterator vit = dU.tagMap.begin(); vit != dU.tagMap.end(); ++vit )
00285     {
00286         moab_taghs.push_back( ( *vit ).mTagh );
00287     }
00288 
00289     damsel_container mtags =
00290         DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&moab_taghs[0], moab_taghs.size() );
00291     std::cerr << "MOAB: created model container: mtags = " << mtags << std::endl;
00292 
00293     err = DMSLmodel_map_handles_inventing_file_handles( mtags );
00294     CHK_DMSL_ERR( err, "Failed to map tag handles" );
00295 
00296     err = DMSLcontainer_release( mtags );
00297     CHK_DMSL_ERR( err, "Problem releasing tag handle container" );
00298 
00299     return MB_SUCCESS;
00300 }
00301 
00302 ErrorCode WriteDamsel::write_vertices( RangeSeqIntersectIter& rsi )
00303 {
00304     // Write the vertices; these vertices will be in the same sequence and will be contiguous,
00305     // guaranteed
00306     EntityHandle start_vert = rsi.get_start_handle(), end_vert = rsi.get_end_handle();
00307 
00308     // Create a damsel container for these vertex handles
00309     damsel_container vertex_cont =
00310         DMSLcontainer_create_sequence( dU.dmslModel, start_vert, (int)( end_vert - start_vert + 1 ), 1 );
00311     std::cerr << "MOAB: created model container: vertex_cont = " << vertex_cont << std::endl;
00312     if( DAMSEL_CONTAINER_INVALID == vertex_cont )
00313         MB_SET_ERR( MB_FAILURE,
00314                     "Failed to create vertex sequence for vertices starting with handle " << rsi.get_start_handle() );
00315 
00316     damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( vertex_cont );
00317     CHK_DMSL_ERR( err, "Failed to map handles" );
00318 
00319     // Define the entities to damsel
00320     err = DMSLentity_define( vertex_cont, DAMSEL_ENTITY_TYPE_VERTEX, 1, vertex_cont );
00321     CHK_DMSL_ERR( err, "Failure in DMSLentity_define for vertices starting with handle " << rsi.get_start_handle() );
00322 
00323     // Get the vertex coordinates storage locations and pass to damsel
00324     Range vert_range( start_vert, end_vert );
00325     double *xcoords = NULL, *ycoords = NULL, *zcoords = NULL;
00326     int count;
00327     ErrorCode rval = mbImpl->coords_iterate( vert_range.begin(), vert_range.end(), xcoords, ycoords, zcoords, count );MB_CHK_SET_ERR( rval,
00328                     "Failed to get coordinate iterator for vertices starting with handle " << rsi.get_start_handle() );
00329     if( count != (int)vert_range.size() )
00330     {
00331         MB_SET_ERR( MB_FAILURE, "Vertex subrange not in the same sequence for vertices starting with handle "
00332                                     << rsi.get_start_handle() );
00333     }
00334 
00335     if( xcoords && !ycoords && !zcoords )
00336     {
00337         // Interleaved
00338 
00339         // Map the data to damsel
00340         err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh );
00341         CHK_DMSL_ERR( err, "Failed to assign vertex coordinates tag for vertices starting with handle "
00342                                << rsi.get_start_handle() );
00343     }
00344     else
00345     {
00346         // Map the data to damsel
00347         err = DMSLmodel_map_tag( xcoords, vertex_cont, (damsel_handle_ptr)&dU.xcoordsTag.mTagh );
00348         CHK_DMSL_ERR( err, "Failed to assign vertex x coordinates tag for vertices starting with handle "
00349                                << rsi.get_start_handle() );
00350         err = DMSLmodel_map_tag( ycoords, vertex_cont, (damsel_handle_ptr)&dU.ycoordsTag.mTagh );
00351         CHK_DMSL_ERR( err, "Failed to assign vertex y coordinates tag for vertices starting with handle "
00352                                << rsi.get_start_handle() );
00353         err = DMSLmodel_map_tag( zcoords, vertex_cont, (damsel_handle_ptr)&dU.zcoordsTag.mTagh );
00354         CHK_DMSL_ERR( err, "Failed to assign vertex z coordinates tag for vertices starting with handle "
00355                                << rsi.get_start_handle() );
00356     }
00357 
00358     // Write/map dense tags
00359     rval = map_dense_tags( rsi, vertex_cont );MB_CHK_ERR( rval );
00360 
00361     err = DMSLcontainer_release( vertex_cont );
00362     CHK_DMSL_ERR( err, "Problem releasing vertex handle container" );
00363 
00364     return MB_SUCCESS;
00365 }
00366 
00367 ErrorCode WriteDamsel::write_entities( RangeSeqIntersectIter& rsi )
00368 {
00369     // Write the entities; these entities will be in the same sequence and will be contiguous,
00370     // guaranteed
00371     EntityHandle start_ent = rsi.get_start_handle(), end_ent = rsi.get_end_handle();
00372 
00373     // Create a damsel container for these entity handles
00374     damsel_container ent_cont;
00375     ent_cont = DMSLcontainer_create_sequence( dU.dmslModel, start_ent, (int)( end_ent - start_ent + 1 ), 1 );
00376     std::cerr << "MOAB: created model container: ent_cont = " << ent_cont << std::endl;
00377     if( DAMSEL_CONTAINER_INVALID == ent_cont ) MB_SET_ERR( MB_FAILURE, "Bad sequence returned by Damsel" );
00378 
00379     damsel_err_t err = DMSLmodel_map_handles_inventing_file_handles( ent_cont );
00380     CHK_DMSL_ERR( err, "Failed to map handles" );
00381 
00382     // Get # verts per entity and entity type
00383     EntityType etype = mbImpl->type_from_handle( start_ent );
00384     assert( MBMAXTYPE != etype );
00385     int num_connect = rsi.get_sequence()->values_per_entity();
00386     assert( 0 < num_connect );
00387 
00388     // Get the connectivity storage location and pass to damsel
00389     Range ent_range( start_ent, end_ent );
00390     int count;
00391     EntityHandle* connect;
00392     int verts_per_ent;
00393     ErrorCode rval = mbImpl->connect_iterate( ent_range.begin(), ent_range.end(), connect, verts_per_ent, count );MB_CHK_SET_ERR( rval,
00394                     "Failed to get connect iterator for entities starting with handle " << rsi.get_start_handle() );
00395     if( count != (int)ent_range.size() )
00396         MB_SET_ERR( MB_FAILURE, "Entity subrange not in the same sequence for entities starting with handle "
00397                                     << rsi.get_start_handle() );
00398 
00399     // Define the entities to damsel
00400     err = DMSLentity_define_fast( ent_cont, DamselUtil::mtod_entity_type[etype], num_connect, (damsel_handle*)connect );
00401     CHK_DMSL_ERR( err, "DMSLentity_define failed for entities starting with handle " << rsi.get_start_handle() );
00402 
00403     // Write dense tags
00404     rval = map_dense_tags( rsi, ent_cont );MB_CHK_ERR( rval );
00405 
00406     err = DMSLcontainer_release( ent_cont );
00407     CHK_DMSL_ERR( err, "Problem releasing entity handle container" );
00408 
00409     return MB_SUCCESS;
00410 }
00411 
00412 ErrorCode WriteDamsel::map_dense_tags( RangeSeqIntersectIter& rsi, damsel_container& ent_cont )
00413 {
00414     // All dense_tags have been initialized before this, so here we just go through
00415     // them and map data if there is any
00416     const unsigned char* val_ptr;
00417     ErrorCode rval = MB_SUCCESS;
00418     std::vector< DamselUtil::tinfo >::iterator tagit;
00419     damsel_err_t err;
00420     for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit )
00421     {
00422         if( ( *tagit ).tagType != MB_TAG_DENSE ) continue;
00423 
00424         // Get a ptr to memory for this tag/sequence
00425         DenseTag* dtag = dynamic_cast< DenseTag* >( ( *tagit ).mTagh );
00426         assert( dtag );
00427         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 "
00428                                   << rsi.get_start_handle() );
00429 
00430         // If ptr is NULL, no data for this tag in this sequence
00431         if( !val_ptr ) continue;
00432 
00433         // Else, register with damsel
00434         err = DMSLmodel_map_tag( (void*)val_ptr, ent_cont, (damsel_handle_ptr)&dtag );
00435         CHK_DMSL_ERR( err,
00436                       "Failed to write coordinates tag for vertices starting with handle " << rsi.get_start_handle() );
00437     }
00438 
00439     return rval;
00440 }
00441 
00442 ErrorCode WriteDamsel::map_sparse_tags()
00443 {
00444     // All sparse_tags have been initialized before this, so here we just go through
00445     // them and map data if there is any
00446     ErrorCode rval = MB_SUCCESS;
00447     damsel_err_t err;
00448     std::vector< DamselUtil::tinfo >::iterator tagit;
00449     std::vector< unsigned char > tag_values;
00450     std::vector< EntityHandle > tagged_ents;
00451     damsel_container ent_cont;
00452     for( tagit = dU.tagMap.begin(); tagit != dU.tagMap.end(); ++tagit )
00453     {
00454         if( ( *tagit ).tagType != MB_TAG_SPARSE ) continue;
00455         // Get a ptr to memory for this tag/sequence
00456         SparseTag* stag = dynamic_cast< SparseTag* >( ( *tagit ).mTagh );
00457         assert( stag );
00458         Range output_ents;
00459         rval = stag->get_tagged_entities( sequenceManager, output_ents );MB_CHK_SET_ERR( rval, "Trouble getting tagged entities for tag " << stag->get_name() );
00460 
00461         // If no entities have this tag set, don't map it
00462         if( output_ents.empty() ) continue;
00463 
00464         // Else, register with damsel
00465         // Allocate space for and get values
00466         tag_values.resize( stag->get_size() * output_ents.size() );
00467         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() );
00468 
00469         // Build a vector of entity handles from the range, and a container from that
00470         tagged_ents.resize( output_ents.size() );
00471         std::copy( output_ents.begin(), output_ents.end(), tagged_ents.begin() );
00472         ent_cont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle_ptr)&tagged_ents[0], tagged_ents.size() );
00473         std::cerr << "MOAB: created model container: sparse_tag_ent_cont = " << ent_cont << std::endl;
00474         if( DAMSEL_CONTAINER_INVALID == ent_cont )
00475             MB_SET_ERR( MB_FAILURE, "Trouble creating entity handle container for tag " << stag->get_name() );
00476 
00477         // Now map it
00478         err = DMSLmodel_map_tag( (void*)&tag_values[0], ent_cont, (damsel_handle_ptr)&stag );
00479         CHK_DMSL_ERR( err, "Failed to write tag " << stag->get_name() );
00480 
00481         err = DMSLcontainer_release( ent_cont );
00482         CHK_DMSL_ERR( err, "Problem releasing entity handle container" );
00483     }
00484 
00485     return rval;
00486 }
00487 
00488 ErrorCode WriteDamsel::write_sets( RangeSeqIntersectIter& rsi )
00489 {
00490     // Write the sets
00491     ErrorCode rval = MB_SUCCESS;
00492     std::vector< EntityHandle > ents;
00493     damsel_container mcont;
00494     damsel_err_t err;
00495     unsigned int i, num_sets = rsi.get_end_handle() - rsi.get_start_handle() + 1;
00496     std::vector< unsigned int > set_flags( num_sets, 0 );
00497     EntityHandle seth;
00498     for( seth = rsi.get_start_handle(), i = 0; seth <= rsi.get_end_handle(); seth++, i++ )
00499     {
00500         // Get all the entities in the set
00501         ents.clear();
00502         rval = mbImpl->get_entities_by_handle( seth, ents );MB_CHK_SET_ERR( rval, "get_entities_by_handle failed for set " << seth );
00503         if( !ents.empty() )
00504         {
00505             mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)&ents[0], ents.size() );
00506         }
00507         else
00508         {
00509             mcont = DMSLcontainer_create_vector( dU.dmslModel, (damsel_handle*)NULL, 0 );
00510         }
00511         std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl;
00512 
00513         // Get the set type (range or set)
00514         unsigned int opts;
00515         rval = mbImpl->get_meshset_options( seth, opts );MB_CHK_SET_ERR( rval, "Failed to get options for meshset " << seth );
00516         damsel_collection_type coll_type =
00517             ( opts & MESHSET_SET ? DAMSEL_HANDLE_COLLECTION_TYPE_SET : DAMSEL_HANDLE_COLLECTION_TYPE_VECTOR );
00518 
00519         // Parents/children...
00520 
00521         // Set flags
00522         if( opts & MESHSET_TRACK_OWNER )
00523             set_flags[i] |= MESHSET_TRACK_OWNER;
00524         else
00525             set_flags[i] &= !MESHSET_TRACK_OWNER;
00526 
00527         // Create the collection
00528         DMSLcoll_create( dU.dmslModel, (damsel_handle_ptr)&seth, mcont, coll_type );
00529 
00530         // Release the container
00531         err = DMSLcontainer_release( mcont );
00532         CHK_DMSL_ERR( err, "Problem releasing set entity handle container" );
00533     }
00534 
00535     // Set the COLL_FLAGS tag, using assign (direct)
00536     // Make a container of set handles...
00537     mcont = DMSLcontainer_create_sequence( dU.dmslModel, rsi.get_start_handle(), num_sets, 1 );
00538     std::cerr << "MOAB: created model container: sets_cont = " << mcont << std::endl;
00539 
00540     // Assign the tags on them
00541     err = DMSLmodel_map_tag( &set_flags[0], mcont, ( damsel_handle_ptr ) & ( dU.collFlagsTag.mTagh ) );
00542     CHK_DMSL_ERR( err, "Failed to assign COLL_FLAGS tag for sets" );
00543 
00544     // Map set handles
00545     err = DMSLmodel_map_handles_inventing_file_handles( mcont );
00546     CHK_DMSL_ERR( err, "Failed to map set handles" );
00547 
00548     // Map other dense tags
00549     rval = map_dense_tags( rsi, mcont );MB_CHK_SET_ERR( rval, "Failed to map dense tags for sets" );
00550 
00551     return rval;
00552 }
00553 
00554 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines