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