moab
ReadCCMIO.cpp
Go to the documentation of this file.
00001 #include <stdlib.h> // For exit()
00002 #include <vector>
00003 #include <map>
00004 #include <iostream>
00005 #include <string>
00006 #include <algorithm>
00007 
00008 #include "moab/CN.hpp"
00009 #include "moab/Range.hpp"
00010 #include "moab/Interface.hpp"
00011 #include "MBTagConventions.hpp"
00012 #include "Internals.hpp"
00013 #include "moab/ReadUtilIface.hpp"
00014 #include "moab/FileOptions.hpp"
00015 #include "ReadCCMIO.hpp"
00016 #include "moab/MeshTopoUtil.hpp"
00017 
00018 #include "ccmio.h"
00019 
00020 /*
00021  * CCMIO file structure
00022  *
00023  * Root
00024  *   State(kCCMIOState)
00025  *     Processor*
00026  *       Vertices
00027  *         ->ReadVerticesx, ReadMap
00028  *       Topology
00029  *         Boundary faces*(kCCMIOBoundaryFaces)
00030  *            ->ReadFaces, ReadFaceCells, ReadMap
00031  *         Internal faces(kCCMIOInternalFaces)
00032  *         Cells (kCCMIOCells)
00033  *            ->ReadCells (mapID), ReadMap, ReadCells (cellTypes)
00034  *       Solution
00035  *         Phase
00036  *           Field
00037  *             FieldData
00038  *   Problem(kCCMIOProblemDescription)
00039  *     CellType* (kCCMIOCellType)
00040  *       Index (GetEntityIndex), MaterialId(ReadOpti), MaterialType(ReadOptstr),
00041  *         PorosityId(ReadOpti), SpinId(ReadOpti), GroupId(ReadOpti)
00042  *
00043  * MaterialType (CCMIOReadOptstr in readexample)
00044  * constants (see readexample)
00045  * lagrangian data (CCMIOReadLagrangianData)
00046  * vertices label (CCMIOEntityDescription)
00047  * restart info: char solver[], iteratoins, time, char timeUnits[], angle
00048  *      (CCMIOReadRestartInfo, kCCMIORestartData), reference data?
00049  * phase:
00050  *   field: char name[], dims, CCMIODataType datatype, char units[]
00051  *       dims = kCCMIOScalar (CCMIOReadFieldDataf), 
00052  *              kCCMIOVector (CCMIOReadMultiDimensionalFieldData),
00053  *              kCCMIOTensor
00054  * MonitoringSets: num, name (CellSet, VertexSet, BoundarySet, BlockSet, SplineSet, CoupleSet)
00055  *      CCMIOGetProstarSet, CCMIOReadOpt1i,
00056  */
00057 
00058 enum DataType { kScalar, kVector, kVertex, kCell, kInternalFace, kBoundaryFace,
00059                 kBoundaryData, kBoundaryFaceData, kCellType };
00060 
00061 namespace moab 
00062 {
00063     
00064 static int const kNValues = 10; // Number of values of each element to print
00065 static char const kDefaultState[] = "default";
00066 static char const kUnitsName[] = "Units";
00067 static int const kVertOffset = 2;
00068 static int const kCellInc = 4;
00069 
00070 #define CHKERR(a, b)                                 \
00071     {if (MB_SUCCESS != a) {if (b) readMeshIface->report_error(b); return a;}}
00072 
00073 #define CHKCCMERR(a, b) {if (kCCMIONoErr != a && kCCMIONoFileErr != a && kCCMIONoNodeErr != a) {if (b) readMeshIface->report_error(b); return MB_FAILURE;}}
00074 
00075 ReaderIface* ReadCCMIO::factory( Interface* iface )
00076 { return new ReadCCMIO( iface ); }
00077 
00078 ReadCCMIO::ReadCCMIO(Interface* impl)
00079         : mMaterialIdTag(0), mMaterialTypeTag(0),
00080           mRadiationTag(0), mPorosityIdTag(0), mSpinIdTag(0), mGroupIdTag(0), mColorIdxTag(0),
00081           mProcessorIdTag(0), mLightMaterialTag(0), mFreeSurfaceMaterialTag(0),
00082           mThicknessTag(0), mProstarRegionNumberTag(0), mCreatingProgramTag(0), mbImpl(impl)
00083 {
00084   assert(impl != NULL);
00085   
00086   impl->query_interface( readMeshIface );
00087 
00088   // initialize in case tag_get_handle fails below
00089   mMaterialSetTag  = 0;
00090   mDirichletSetTag = 0;
00091   mNeumannSetTag   = 0;
00092   mHasMidNodesTag  = 0;
00093   mGlobalIdTag     = 0;
00094 
00096   const int negone = -1;
00097   ErrorCode result = impl->tag_get_handle(MATERIAL_SET_TAG_NAME,  1, MB_TYPE_INTEGER,
00098                                           mMaterialSetTag, MB_TAG_CREAT|MB_TAG_SPARSE, &negone);
00099   assert(MB_SUCCESS == result);
00100   if (result) {}
00101   
00102   result = impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00103                                 mDirichletSetTag, MB_TAG_CREAT|MB_TAG_SPARSE, &negone);
00104   assert(MB_SUCCESS == result); 
00105   if (result) {}
00106   
00107   result = impl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER,
00108                                 mNeumannSetTag, MB_TAG_CREAT|MB_TAG_SPARSE, &negone);
00109 
00110   const int negonearr[] = {-1, -1, -1, -1};
00111   result = impl->tag_get_handle(HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER,
00112                                 mHasMidNodesTag, MB_TAG_CREAT|MB_TAG_SPARSE, negonearr);
00113   assert(MB_SUCCESS == result);
00114   if (result) {}
00115   
00116   const int zero = 0;
00117   result = impl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER,
00118                                 mGlobalIdTag, MB_TAG_CREAT|MB_TAG_SPARSE, &zero);
00119   assert(MB_SUCCESS == result);
00120   if (result) {}
00121 
00122   result = impl->tag_get_handle(NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE,
00123                                 mNameTag, MB_TAG_CREAT|MB_TAG_SPARSE);
00124   assert(MB_SUCCESS == result);
00125   if (result) {}
00126 }
00127 
00128 ReadCCMIO::~ReadCCMIO() 
00129 { 
00130   mbImpl->release_interface( readMeshIface );
00131 }
00132 
00133 ErrorCode ReadCCMIO::load_file(const char *file_name,
00134                                  const EntityHandle* file_set,
00135                                const FileOptions& /* opts */,
00136                                  const ReaderIface::SubsetList* subset_list,
00137                                const Tag* /* file_id_tag */)
00138 {
00139   CCMIOID rootID, problemID, stateID, processorID,
00140       verticesID, topologyID, solutionID;
00141   CCMIOError error = kCCMIONoErr;
00142 
00143   if (subset_list) {
00144     readMeshIface->report_error( "Reading subset of files not supported for CCMOI data." );
00145     return MB_UNSUPPORTED_OPERATION;
00146   }
00147 
00148   CCMIOOpenFile(&error, file_name, kCCMIORead, &rootID);
00149   CHKCCMERR(error, "Problem opening file.");
00150 
00151     // get the file state
00152   ErrorCode rval = get_state(rootID, problemID, stateID);
00153   CHKERR(rval,NULL);
00154 
00155     // get processors
00156   std::vector<CCMIOSize_t> procs;
00157   bool has_solution = false;
00158   rval = get_processors(stateID, processorID, verticesID, topologyID, solutionID, 
00159                         procs, has_solution);
00160   CHKERR(rval,NULL);
00161 
00162   std::vector<CCMIOSize_t>::iterator vit;
00163   Range new_ents, *new_ents_ptr = NULL;
00164   if (file_set) new_ents_ptr = &new_ents;
00165   
00166   for (vit = procs.begin(); vit != procs.end(); vit++) {
00167     rval = read_processor(stateID, problemID, processorID, verticesID, topologyID,
00168                           *vit, new_ents_ptr);
00169     CHKERR(rval,NULL);
00170   }
00171 
00172     // load some meta-data
00173   rval = load_metadata(rootID, problemID, stateID, processorID, file_set);
00174   CHKERR(rval,NULL);
00175 
00176     // now, put all this into the file set, if there is one
00177   if (file_set) {
00178     rval = mbImpl->add_entities(*file_set, new_ents);
00179     CHKERR(rval, "Failed to add new entities to file set.");
00180   }
00181   
00182   return rval;
00183 }
00184 
00185 ErrorCode ReadCCMIO::get_state(CCMIOID rootID, CCMIOID &problemID, CCMIOID &stateID) 
00186 {
00187   CCMIOError error = kCCMIONoErr;
00188   
00189     // first try default
00190   CCMIOGetState(&error, rootID, "default", &problemID, &stateID);
00191   if (kCCMIONoErr != error) {
00192     CCMIOSize_t i = CCMIOSIZEC(0);
00193     CCMIOError tmp_error = kCCMIONoErr;
00194     CCMIONextEntity(&tmp_error, rootID, kCCMIOState, &i, &stateID);
00195     if (kCCMIONoErr ==  tmp_error)
00196       CCMIONextEntity(&error, rootID, kCCMIOProblemDescription, 
00197                       &i, &problemID);
00198   }
00199   CHKCCMERR(error, "Couldn't find state.");
00200 
00201   return MB_SUCCESS;
00202 }
00203 
00204 ErrorCode ReadCCMIO::load_metadata(CCMIOID rootID, CCMIOID problemID,
00205                                    CCMIOID /* stateID */, CCMIOID processorID,
00206                                    const EntityHandle *file_set) 
00207 {
00208     // Read the simulation title.
00209   CCMIOError error = kCCMIONoErr;
00210   ErrorCode rval = MB_SUCCESS;
00211   CCMIONode rootNode;
00212   if (kCCMIONoErr == CCMIOGetEntityNode(&error, rootID, &rootNode)) {
00213     char *name = NULL;
00214     CCMIOGetTitle(&error, rootNode, &name);
00215 
00216     if (NULL != name && strlen(name) != 0) {
00217         // make a tag for it and tag the read set
00218       Tag simname;
00219       rval = mbImpl->tag_get_handle("Title", strlen(name), MB_TYPE_OPAQUE,
00220                                     simname, MB_TAG_CREAT|MB_TAG_SPARSE);
00221       CHKERR(rval, "Simulation name tag not found or created.");
00222       EntityHandle set = file_set ? *file_set : 0;
00223       rval = mbImpl->tag_set_data(simname, &set, 1, name);
00224       CHKERR(rval, "Problem setting simulation name tag.");
00225 
00226     }
00227     if (name) free(name);
00228   }
00229 
00230     // creating program
00231   EntityHandle dumh = (file_set ? *file_set : 0);
00232   rval = get_str_option("CreatingProgram", dumh, mCreatingProgramTag, processorID);
00233   CHKERR(rval, "Trouble getting CreatingProgram tag.");
00234 
00235   rval = load_matset_data(problemID);
00236   CHKERR(rval, "Failure loading matset data.");
00237   
00238   rval = load_neuset_data(problemID);
00239   CHKERR(rval, "Failure loading neuset data.");
00240   
00241   return rval;
00242 }
00243 
00244 ErrorCode ReadCCMIO::load_matset_data(CCMIOID problemID) 
00245 {
00246     // make sure there are matsets
00247   if (newMatsets.empty()) return MB_SUCCESS;
00248   
00249     // ... walk through each cell type
00250   CCMIOSize_t i = CCMIOSIZEC(0);
00251   CCMIOID next;
00252   std::string opt_string;
00253   CCMIOError error = kCCMIONoErr;
00254   
00255   while (CCMIONextEntity(NULL, problemID, kCCMIOCellType, &i, &next)
00256          == kCCMIONoErr) {
00257       // get index, corresponding set, and label with material set tag
00258     int mindex;
00259     CCMIOGetEntityIndex(&error, next, &mindex);
00260     std::map<int,EntityHandle>::iterator mit = newMatsets.find(mindex);
00261     if (mit == newMatsets.end()) 
00262         // no actual faces for this matset; continue to next
00263       continue;
00264     
00265     EntityHandle dum_ent = mit->second;
00266     ErrorCode rval = mbImpl->tag_set_data(mMaterialSetTag, &dum_ent, 1, &mindex);
00267     CHKERR(rval, "Trouble setting material set tag.");
00268 
00269       // set name
00270     CCMIOSize_t len;
00271     CCMIOEntityLabel(&error, next, &len, NULL);
00272     std::vector<char> opt_string2(GETINT32(len)+1, '\0');
00273     CCMIOEntityLabel(&error, next, NULL, &opt_string2[0]);
00274     if (opt_string2.size() >= NAME_TAG_SIZE) opt_string2[NAME_TAG_SIZE-1] = '\0';
00275     else (opt_string2.resize(NAME_TAG_SIZE, '\0'));
00276     rval = mbImpl->tag_set_data(mNameTag, &dum_ent, 1, &opt_string2[0]);
00277     CHKERR(rval, "Trouble setting name tag for material set.");
00278 
00279       // material id
00280     rval = get_int_option("MaterialId", dum_ent, mMaterialIdTag, next);
00281     CHKERR(rval, "Trouble getting MaterialId tag.");
00282     
00283     rval = get_str_option("MaterialType", dum_ent, mMaterialTypeTag, next);
00284     CHKERR(rval, "Trouble getting MaterialType tag.");
00285     
00286     rval = get_int_option("Radiation", dum_ent, mRadiationTag, next);
00287     CHKERR(rval, "Trouble getting Radiation option.");
00288 
00289     rval = get_int_option("PorosityId", dum_ent, mPorosityIdTag, next);
00290     CHKERR(rval, "Trouble getting PorosityId option.");
00291 
00292     rval = get_int_option("SpinId", dum_ent, mSpinIdTag, next);
00293     CHKERR(rval, "Trouble getting SpinId option.");
00294 
00295     rval = get_int_option("GroupId", dum_ent, mGroupIdTag, next);
00296     CHKERR(rval, "Trouble getting GroupId option.");
00297 
00298     rval = get_int_option("ColorIdx", dum_ent, mColorIdxTag, next);
00299     CHKERR(rval, "Trouble getting ColorIdx option.");
00300 
00301     rval = get_int_option("ProcessorId", dum_ent, mProcessorIdTag, next);
00302     CHKERR(rval, "Trouble getting ProcessorId option.");
00303 
00304     rval = get_int_option("LightMaterial", dum_ent, mLightMaterialTag, next);
00305     CHKERR(rval, "Trouble getting LightMaterial option.");
00306 
00307     rval = get_int_option("FreeSurfaceMaterial", dum_ent, mFreeSurfaceMaterialTag, next);
00308     CHKERR(rval, "Trouble getting FreeSurfaceMaterial option.");
00309 
00310     rval = get_dbl_option("Thickness", dum_ent, mThicknessTag, next);
00311     CHKERR(rval, "Trouble getting Thickness option.");
00312   }
00313 
00314   return MB_SUCCESS;
00315 }
00316 
00317 ErrorCode ReadCCMIO::get_int_option(const char *opt_str, EntityHandle seth,
00318                                     Tag &tag, CCMIOID node) 
00319 {
00320   int idum;
00321   ErrorCode rval;
00322   if (kCCMIONoErr == CCMIOReadOpti(NULL, node, opt_str, &idum)) {
00323     if (!tag) {
00324       rval = mbImpl->tag_get_handle(opt_str, 1, MB_TYPE_INTEGER, 
00325                                     tag, MB_TAG_SPARSE|MB_TAG_CREAT);
00326       CHKERR(rval, NULL);
00327     }
00328     
00329     rval = mbImpl->tag_set_data(tag, &seth, 1, &idum);
00330     CHKERR(rval, NULL);
00331   }
00332 
00333   return MB_SUCCESS;
00334 }
00335 
00336 ErrorCode ReadCCMIO::get_dbl_option(const char *opt_str, EntityHandle seth,
00337                                     Tag &tag, CCMIOID node) 
00338 {
00339   float fdum;
00340   if (kCCMIONoErr == CCMIOReadOptf(NULL, node, opt_str, &fdum)) {
00341     ErrorCode rval;
00342     if (!tag) {
00343       rval = mbImpl->tag_get_handle(opt_str, 1, MB_TYPE_DOUBLE, 
00344                                     tag, MB_TAG_SPARSE|MB_TAG_CREAT);
00345       CHKERR(rval, NULL);
00346     }
00347     
00348     double dum_dbl = fdum;
00349     rval = mbImpl->tag_set_data(tag, &seth, 1, &dum_dbl);
00350     CHKERR(rval, NULL);
00351   }
00352 
00353   return MB_SUCCESS;
00354 }
00355 
00356 ErrorCode ReadCCMIO::get_str_option(const char *opt_str, EntityHandle seth, Tag &tag, 
00357                                     CCMIOID node, const char *other_tag_name)
00358 {
00359   int len;
00360   CCMIOError error = kCCMIONoErr;
00361   std::vector<char> opt_string;
00362   if (kCCMIONoErr != CCMIOReadOptstr(NULL, node, opt_str, &len, NULL)) 
00363     return MB_SUCCESS;
00364     
00365   opt_string.resize(len);
00366   CCMIOReadOptstr(&error, node, opt_str, &len, &opt_string[0]);
00367   ErrorCode rval = MB_SUCCESS;
00368   if (!tag) {
00369     rval = mbImpl->tag_get_handle( other_tag_name ? other_tag_name : opt_str,
00370                                    NAME_TAG_SIZE, MB_TYPE_OPAQUE, tag,
00371                                    MB_TAG_SPARSE|MB_TAG_CREAT );
00372     CHKERR(rval, NULL);
00373   }
00374 
00375   if (opt_string.size() > NAME_TAG_SIZE) opt_string[NAME_TAG_SIZE-1] = '\0';
00376   else (opt_string.resize(NAME_TAG_SIZE, '\0'));
00377 
00378   rval = mbImpl->tag_set_data(tag, &seth, 1, &opt_string[0]);
00379   CHKERR(rval, NULL);
00380 
00381   return MB_SUCCESS;
00382 }
00383     
00384 ErrorCode ReadCCMIO::load_neuset_data(CCMIOID problemID) 
00385 {
00386   CCMIOSize_t i = CCMIOSIZEC(0);
00387   CCMIOID next;
00388 
00389     // make sure there are matsets
00390   if (newNeusets.empty()) return MB_SUCCESS;
00391   
00392   while (CCMIONextEntity(NULL, problemID, kCCMIOBoundaryRegion, &i, &next)
00393          == kCCMIONoErr) {
00394       // get index, corresponding set, and label with neumann set tag
00395     int mindex;
00396     CCMIOError error = kCCMIONoErr;
00397     CCMIOGetEntityIndex(&error, next, &mindex);
00398     std::map<int,EntityHandle>::iterator mit = newNeusets.find(mindex);
00399     if (mit == newNeusets.end()) 
00400         // no actual faces for this neuset; continue to next
00401       continue;
00402     
00403     EntityHandle dum_ent = mit->second;
00404     ErrorCode rval = mbImpl->tag_set_data(mNeumannSetTag, &dum_ent, 1, &mindex);
00405     CHKERR(rval, "Trouble setting neumann set tag.");
00406 
00407       // set name
00408     rval = get_str_option("BoundaryName", dum_ent, mNameTag, next, NAME_TAG_NAME);
00409     CHKERR(rval, "Trouble creating BoundaryName tag.");
00410     
00411       // BoundaryType
00412     rval = get_str_option("BoundaryType", dum_ent, mBoundaryTypeTag, next);
00413     CHKERR(rval, "Trouble creating BoundaryType tag.");
00414 
00415       // ProstarRegionNumber
00416     rval = get_int_option("ProstarRegionNumber", dum_ent, mProstarRegionNumberTag, next);
00417     CHKERR(rval, "Trouble creating ProstarRegionNumber tag.");
00418   }
00419 
00420   return MB_SUCCESS;
00421 }
00422 
00423 ErrorCode ReadCCMIO::read_processor(CCMIOID /* stateID */, CCMIOID problemID,
00424                                     CCMIOID processorID, CCMIOID verticesID, CCMIOID topologyID, 
00425                                     CCMIOSize_t proc, Range *new_ents) 
00426 {
00427   ErrorCode rval;
00428   
00429     // vert_map fields: s: none, i: gid, ul: vert handle, r: none
00430     //TupleList vert_map(0, 1, 1, 0, 0);
00431   TupleList vert_map;
00432   rval = read_vertices(proc, processorID, verticesID, topologyID, 
00433                        new_ents, vert_map);
00434   CHKERR(rval, NULL);
00435   
00436   rval = read_cells(proc, problemID, verticesID, topologyID, 
00437                     vert_map, new_ents);
00438   CHKERR(rval, NULL);
00439 
00440   return rval;
00441 }
00442 
00443 ErrorCode ReadCCMIO::read_cells(CCMIOSize_t /* proc */, CCMIOID problemID,
00444                                 CCMIOID /* verticesID */, CCMIOID topologyID,
00445                                   TupleList &vert_map, Range *new_ents) 
00446 {
00447 
00448     // read the faces.
00449     // face_map fields: s:forward/reverse, i: cell id, ul: face handle, r: none
00450   ErrorCode rval;
00451 #ifdef TUPLE_LIST
00452   TupleList face_map(1, 1, 1, 0, 0); 
00453 #else
00454   TupleList face_map;
00455   SenseList sense_map;
00456 #endif
00457   rval = read_all_faces(topologyID, vert_map, face_map
00458 #ifndef TUPLE_LIST
00459                         , sense_map
00460 #endif
00461                         , new_ents);
00462   CHKERR(rval, NULL);
00463 
00464     // read the cell topology types, if any exist in the file
00465   std::map<int,int> cell_topo_types;
00466   rval = read_topology_types(topologyID, cell_topo_types);
00467   CHKERR(rval, "Problem reading cell topo types.");
00468   
00469     // now construct the cells; sort the face map by cell ids first
00470 #ifdef TUPLE_LIST  
00471   rval = face_map.sort(1);
00472   CHKERR(rval, "Couldn't sort face map by cell id.");
00473 #endif
00474   std::vector<EntityHandle> new_cells;
00475   rval = construct_cells(face_map, 
00476 #ifndef TUPLE_LIST
00477                          sense_map,
00478 #endif
00479                          vert_map, cell_topo_types, new_cells);
00480   CHKERR(rval, NULL);
00481   if (new_ents) {
00482     Range::iterator rit = new_ents->end();
00483     std::vector<EntityHandle>::reverse_iterator vit;
00484     for (vit = new_cells.rbegin(); vit != new_cells.rend(); vit++)
00485       rit = new_ents->insert(rit, *vit);
00486   }
00487   
00488   rval = read_gids_and_types(problemID, topologyID, new_cells);
00489   CHKERR(rval, NULL);
00490   
00491   return MB_SUCCESS;
00492 }
00493 
00494 ErrorCode ReadCCMIO::read_topology_types(CCMIOID &topologyID, 
00495                                          std::map<int,int> &cell_topo_types) 
00496 {
00497   CCMIOError error = kCCMIONoErr;
00498   CCMIOID cellID, mapID;
00499   CCMIOSize_t ncells;
00500   CCMIOGetEntity(&error, topologyID, kCCMIOCells, 0, &cellID);
00501   CCMIOEntitySize(&error, cellID, &ncells, NULL);
00502   int num_cells = GETINT32(ncells);
00503 
00504     // first, do a dummy read to see if we even have topo types in this mesh
00505   int dum_int;
00506   CCMIOReadOpt1i(&error, cellID, "CellTopologyType", &dum_int,
00507                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOStart)+1);
00508   if (kCCMIONoErr != error) return MB_SUCCESS;
00509   
00510     // ok, we have topo types; first get the map node
00511   std::vector<int> dum_ints(num_cells);
00512   CCMIOReadCells(&error, cellID, &mapID, &dum_ints[0],
00513                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOStart)+1);
00514   CHKCCMERR(error, "Failed to get the map node.");
00515 
00516     // now read the map
00517   CCMIOReadMap(&error, mapID, &dum_ints[0],
00518                CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00519   CHKCCMERR(error, "Failed to get cell ids.");
00520   int i;
00521   for (i = 0; i < num_cells; i++) cell_topo_types[dum_ints[i]] = 0;
00522 
00523     // now read the cell topo types for real, reusing cell_topo_types
00524   std::vector<int> topo_types(num_cells);
00525   CCMIOReadOpt1i(&error, cellID, "CellTopologyType", &topo_types[0],
00526                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00527   CHKCCMERR(error, "Failed to get cell topo types.");
00528   std::map<int,int>::iterator mit;
00529   for (i = 0; i < num_cells; i++) 
00530     cell_topo_types[dum_ints[i]] = topo_types[i];
00531   
00532   return MB_SUCCESS;
00533 }
00534 
00535 ErrorCode ReadCCMIO::read_gids_and_types(CCMIOID /* problemID */,
00536                                            CCMIOID topologyID,
00537                                            std::vector<EntityHandle> &cells) 
00538 {
00539     // get the cells entity and number of cells
00540   CCMIOSize_t dum_cells;
00541   int num_cells;
00542   CCMIOError error = kCCMIONoErr;
00543   CCMIOID cellsID, mapID;
00544   CCMIOGetEntity(&error, topologyID, kCCMIOCells, 0, &cellsID);
00545   CCMIOEntitySize(&error, cellsID, &dum_cells, NULL);
00546   num_cells = GETINT32(dum_cells);
00547 
00548     // check the number of cells against how many are in the cell array
00549   if (num_cells != (int)cells.size())
00550     CHKERR(MB_FAILURE, "Number of cells doesn't agree.");
00551 
00552     // read the gid map and set global ids
00553   std::vector<int> cell_gids(num_cells);
00554   CCMIOReadCells(&error, cellsID, &mapID, NULL,
00555                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00556   CCMIOReadMap(&error, mapID, &cell_gids[0], 
00557                CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00558   CHKCCMERR(error, "Couldn't read cells or cell id map.");
00559 
00560   ErrorCode rval = mbImpl->tag_set_data(mGlobalIdTag, &cells[0], 
00561                                           cells.size(), &cell_gids[0]);
00562   CHKERR(rval, "Couldn't set gids tag.");
00563 
00564     // now read cell material types; reuse cell_gids
00565   CCMIOReadCells(&error, cellsID, NULL, &cell_gids[0],
00566                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00567   CHKCCMERR(error, "Trouble reading cell types.");
00568 
00569     // create the matsets
00570   std::map<int, Range> matset_ents;
00571   for (int i = 0; i < num_cells; i++)
00572     matset_ents[cell_gids[i]].insert(cells[i]);
00573 
00574   for (std::map<int, Range>::iterator mit = matset_ents.begin(); mit != matset_ents.end(); mit++) {
00575     EntityHandle matset;
00576     rval = mbImpl->create_meshset(MESHSET_SET, matset);
00577     CHKERR(rval, "Couldn't create material set.");
00578     newMatsets[mit->first] = matset;
00579     
00580     rval = mbImpl->add_entities(matset, mit->second);
00581     CHKERR(rval, "Couldn't add entities to material set.");
00582   }
00583   
00584   return MB_SUCCESS;
00585 }
00586 
00587 
00588 ErrorCode ReadCCMIO::construct_cells(TupleList &face_map, 
00589 #ifndef TUPLE_LIST
00590                                      SenseList &sense_map, 
00591 #endif
00592                                      TupleList & /* vert_map */,
00593                                      std::map<int,int> &cell_topo_types,
00594                                      std::vector<EntityHandle> &new_cells) 
00595 {
00596   std::vector<EntityHandle> facehs;
00597   std::vector<int> senses;
00598   EntityHandle cell;
00599   ErrorCode tmp_rval, rval = MB_SUCCESS;
00600   EntityType this_type = MBMAXTYPE;
00601   bool has_mid_nodes = false;
00602 #ifdef TUPLE_LIST
00603   unsigned int i = 0;
00604   while (i < face_map.n) {
00605       // pull out face handles bounding the same cell
00606     facehs.clear();
00607     int this_id = face_map.get_int(i);
00608     unsigned int inext = i;
00609     while (face_map.get_int(inext) == this_id && inext <= face_map.n) {
00610       inext++;
00611       EntityHandle face = face_map.get_ulong(inext);
00612       facehs.push_back(face);
00613       senses.push_back(face_map.get_short(inext));
00614     }
00615     this_type = MBMAXTYPE;
00616     has_mid_nodes = false;
00617 #else
00618       
00619   std::map<int,std::vector<EntityHandle> >::iterator fmit;
00620   std::map<int,std::vector<int> >::iterator smit;
00621   std::map<int,int>::iterator typeit;
00622   for (fmit = face_map.begin(), smit = sense_map.begin();
00623        fmit != face_map.end(); fmit++, smit++) {
00624       // pull out face handles bounding the same cell
00625     facehs.clear();
00626     int this_id = (*fmit).first;
00627     facehs = (*fmit).second;
00628     senses.clear();
00629     senses = (*smit).second;
00630     typeit = cell_topo_types.find(this_id);
00631     if (typeit != cell_topo_types.end()) {
00632       rval = ccmio_to_moab_type(typeit->second, this_type, has_mid_nodes);
00633     }
00634     else {
00635       this_type = MBMAXTYPE;
00636       has_mid_nodes = false;
00637     }
00638 #endif
00639     tmp_rval = create_cell_from_faces(facehs, senses, this_type, has_mid_nodes, cell);
00640     if (MB_SUCCESS != tmp_rval) rval = tmp_rval;
00641     else {
00642       new_cells.push_back(cell);
00643         // tag cell with global id
00644       tmp_rval = mbImpl->tag_set_data(mGlobalIdTag, &cell, 1, &this_id);
00645       if (MB_SUCCESS != tmp_rval) rval = tmp_rval;
00646     }
00647   }
00648     
00649   return rval;
00650 }
00651 
00652 ErrorCode ReadCCMIO::ccmio_to_moab_type(int ccm_type, EntityType &moab_type, bool &has_mid_nodes) 
00653 {
00654   switch (ccm_type) {
00655     case 1:
00656         moab_type = MBVERTEX;
00657         break;
00658     case 2:
00659     case 28:
00660         moab_type = MBEDGE;
00661         break;
00662     case 29:
00663         moab_type = MBMAXTYPE;
00664         break;
00665     case 3:
00666     case 4:
00667         moab_type = MBQUAD;
00668         break;
00669     case 11:
00670     case 21:
00671         moab_type = MBHEX;
00672         break;
00673     case 12:
00674     case 22:
00675         moab_type = MBPRISM;
00676         break;
00677     case 13:
00678     case 23:
00679         moab_type = MBTET;
00680         break;
00681     case 14:
00682     case 24:
00683         moab_type = MBPYRAMID;
00684         break;
00685     case 255:
00686         moab_type = MBPOLYHEDRON;
00687         break;
00688     default:
00689         moab_type = MBMAXTYPE;
00690   }
00691   
00692   switch (ccm_type) {
00693     case 28:
00694     case 4:
00695     case 21:
00696     case 22:
00697     case 23:
00698     case 24:
00699         has_mid_nodes = true;
00700         break;
00701     default:
00702         break;
00703   }
00704   
00705   return MB_SUCCESS;
00706 }
00707 
00708 ErrorCode ReadCCMIO::create_cell_from_faces(std::vector<EntityHandle> &facehs,
00709                                             std::vector<int> &senses,
00710                                             EntityType this_type,
00711                                             bool /* has_mid_nodes */,
00712                                             EntityHandle &cell) 
00713 {
00714   ErrorCode rval;
00715 
00716     // test up front to see if they're one type
00717   EntityType face_type = mbImpl->type_from_handle(facehs[0]);
00718   bool same_type = true;
00719   for (std::vector<EntityHandle>::iterator vit = facehs.begin(); vit != facehs.end(); vit++) {
00720     if (face_type != mbImpl->type_from_handle(*vit)) {
00721       same_type = false;
00722       break;
00723     }
00724   }
00725 
00726   std::vector<EntityHandle> verts;
00727   EntityType input_type = this_type;
00728   std::vector<EntityHandle> storage;
00729   MeshTopoUtil mtu(mbImpl);
00730   
00731     // preset this to maxtype, so we get an affirmative choice in loop
00732   this_type = MBMAXTYPE;
00733   
00734   if ((MBTET == input_type || MBMAXTYPE == input_type) && same_type &&
00735       face_type == MBTRI && facehs.size() == 4) {
00736       // try to get proper connectivity for tet
00737 
00738       // get connectivity of first face, and reverse it if sense is forward, since 
00739       // base face always points into entity
00740     rval = mbImpl->get_connectivity(&facehs[0], 1, verts);
00741     CHKERR(rval, "Couldn't get connectivity.");
00742     if (senses[0] > 0) std::reverse(verts.begin(), verts.end());
00743 
00744       // get the 4th vertex through the next tri
00745     const EntityHandle *conn; int conn_size;
00746     rval = mbImpl->get_connectivity(facehs[1], conn, conn_size, true, &storage);
00747     CHKERR(rval, "Couldn't get connectivity.");
00748     int i = 0;
00749     while (std::find(verts.begin(), verts.end(), conn[i]) != verts.end() && i < conn_size) i++;
00750 
00751       // if i is not at the end of the verts, found the apex; otherwise fall back to polyhedron
00752     if (conn_size != i) {
00753       this_type = MBTET;
00754       verts.push_back(conn[i]);
00755     }
00756   }
00757   else if ((MBHEX == input_type || MBMAXTYPE == input_type) && same_type &&
00758            MBQUAD == face_type && facehs.size() == 6) {
00759       // build hex from quads
00760       // algorithm:
00761       // - verts = vertices from 1st quad
00762       // - find quad q1 sharing verts[0] and verts[1]
00763       // - find quad q2 sharing other 2 verts in q1
00764       // - find v1 = opposite vert from verts[1] in q1 , v2 = opposite from verts[0]
00765       // - get i = offset of v1 in verts2 of q2, rotate verts2 by i
00766       // - if verts2[i+1%4] != v2, flip verts2 by switching verts2[1] and verts2[3]
00767       // - append verts2 to verts
00768 
00769 
00770       // get the other vertices for this hex; need to find the quad with no common vertices
00771     Range tmp_faces, tmp_verts;
00772       // get connectivity of first face, and reverse it if sense is forward, since 
00773       // base face always points into entity
00774     rval = mbImpl->get_connectivity(&facehs[0], 1, verts);
00775     CHKERR(rval, "Couldn't get connectivity.");
00776     if (senses[0] > 0) std::reverse(verts.begin(), verts.end());
00777 
00778 
00779       // get q1, which shares 2 vertices with q0
00780     std::copy(facehs.begin(), facehs.end(), range_inserter(tmp_faces));
00781     rval = mbImpl->get_adjacencies(&verts[0], 2, 2, false, tmp_faces);
00782     if (MB_SUCCESS != rval || tmp_faces.size() != 2)
00783       CHKERR(MB_FAILURE, "Couldn't get adj face.");
00784     tmp_faces.erase(facehs[0]);
00785     EntityHandle q1 = *tmp_faces.begin();
00786       // get other 2 verts of q1
00787     rval = mbImpl->get_connectivity(&q1, 1, tmp_verts);
00788     CHKERR(rval, "Couldn't get adj verts.");
00789     tmp_verts.erase(verts[0]); tmp_verts.erase(verts[1]);
00790       // get q2
00791     std::copy(facehs.begin(), facehs.end(), range_inserter(tmp_faces));
00792     rval = mbImpl->get_adjacencies(tmp_verts, 2, false, tmp_faces);
00793     if (MB_SUCCESS != rval || tmp_faces.size() != 2)
00794       CHKERR(MB_FAILURE, "Couldn't get adj face.");
00795     tmp_faces.erase(q1);
00796     EntityHandle q2 = *tmp_faces.begin();
00797       // get verts in q2
00798     rval = mbImpl->get_connectivity(&q2, 1, storage);
00799     CHKERR(rval, "Couldn't get adj vertices.");
00800 
00801       // get verts in q1 opposite from v[1] and v[0] in q0
00802     EntityHandle v0 = 0, v1 = 0;
00803     rval = mtu.opposite_entity(q1, verts[1], v0);
00804     rval = mtu.opposite_entity(q1, verts[0], v1);
00805     if (v0 && v1) {
00806 
00807         // offset of v0 in q2, then rotate and flip
00808       unsigned int ioff = std::find(storage.begin(), storage.end(), v0) - storage.begin();
00809       if (4 == ioff)
00810         CHKERR(MB_FAILURE, "Trouble finding offset.");
00811 
00812       if (storage[(ioff+1)%4] != v1) {
00813         std::reverse(storage.begin(), storage.end());
00814         ioff = std::find(storage.begin(), storage.end(), v0) - storage.begin();
00815       }
00816       if (0 != ioff)
00817         std::rotate(storage.begin(), storage.begin()+ioff, storage.end());
00818 
00819         // copy into verts, and make hex
00820       std::copy(storage.begin(), storage.end(), std::back_inserter(verts));
00821       this_type = MBHEX;
00822     }
00823   }
00824 
00825   if (MBMAXTYPE == this_type && facehs.size() == 5) {
00826       // some preliminaries
00827     std::vector<EntityHandle> tris, quads;
00828     for (unsigned int i = 0; i < 5; i++) {
00829       if (MBTRI == mbImpl->type_from_handle(facehs[i])) tris.push_back(facehs[i]);
00830       else if (MBQUAD == mbImpl->type_from_handle(facehs[i])) quads.push_back(facehs[i]);
00831     }
00832 
00833       // check for prisms
00834     if (2 == tris.size() && 3 == quads.size()) {
00835         // ok, we have the right number of tris and quads; try to find the proper verts
00836 
00837         // get connectivity of first tri, and reverse if necessary
00838       int index = std::find(facehs.begin(), facehs.end(), tris[0]) - facehs.begin();
00839       rval = mbImpl->get_connectivity(&tris[0], 1, verts);
00840       CHKERR(rval, "Couldn't get connectivity.");
00841       if (senses[index] > 0) std::reverse(verts.begin(), verts.end());
00842 
00843         // now align vertices of other tri, through a quad, similar to how we did hexes
00844         // get q1, which shares 2 vertices with t0
00845       Range tmp_faces, tmp_verts;
00846       std::copy(facehs.begin(), facehs.end(), range_inserter(tmp_faces));
00847       rval = mbImpl->get_adjacencies(&verts[0], 2, 2, false, tmp_faces);
00848       if (MB_SUCCESS != rval || tmp_faces.size() != 2)
00849       CHKERR(MB_FAILURE, "Couldn't get adj face.");
00850       tmp_faces.erase(tris[0]);
00851       EntityHandle q1 = *tmp_faces.begin();
00852         // get verts in q1
00853       rval = mbImpl->get_connectivity(&q1, 1, storage);
00854       CHKERR(rval, "Couldn't get adj vertices.");
00855 
00856         // get verts in q1 opposite from v[1] and v[0] in q0
00857       EntityHandle v0 = 0, v1 = 0;
00858       rval = mtu.opposite_entity(q1, verts[1], v0);
00859       rval = mtu.opposite_entity(q1, verts[0], v1);
00860       if (v0 && v1) {
00861           // offset of v0 in t2, then rotate and flip
00862         storage.clear();
00863         rval = mbImpl->get_connectivity(&tris[1], 1, storage);
00864         CHKERR(rval, "Couldn't get connectivity.");
00865     
00866         index = std::find(facehs.begin(), facehs.end(), tris[1]) - facehs.begin();
00867         if (senses[index] < 0) std::reverse(storage.begin(), storage.end());
00868         unsigned int ioff = std::find(storage.begin(), storage.end(), v0) - storage.begin();
00869         if (3 == ioff) CHKERR(MB_FAILURE, "Trouble finding offset.");
00870         for (unsigned int i = 0; i < 3; i++)
00871           verts.push_back(storage[(ioff+i)%3]);
00872 
00873         this_type = MBPRISM;
00874       }
00875     }
00876     else if (tris.size() == 4 && quads.size() == 1) {
00877         // check for pyramid
00878         // get connectivity of first tri, and reverse if necessary
00879       int index = std::find(facehs.begin(), facehs.end(), quads[0]) - facehs.begin();
00880       rval = mbImpl->get_connectivity(&quads[0], 1, verts);
00881       CHKERR(rval, "Couldn't get connectivity.");
00882       if (senses[index] > 0) std::reverse(verts.begin(), verts.end());
00883 
00884         // get apex node
00885       rval = mbImpl->get_connectivity(&tris[0], 1, storage);
00886       CHKERR(rval, "Couldn't get connectivity.");
00887       for (unsigned int i = 0; i < 3; i++) {
00888         if (std::find(verts.begin(), verts.end(), storage[i]) == verts.end()) {
00889           verts.push_back(storage[i]);
00890           break;
00891         }
00892       }
00893 
00894       if (5 == verts.size()) this_type = MBPYRAMID;
00895     }
00896     else {
00897         // dummy else clause to stop in debugger
00898       this_type = MBMAXTYPE;
00899     }
00900   }
00901 
00902   if (MBMAXTYPE != input_type && input_type != this_type && this_type != MBMAXTYPE)
00903     std::cerr << "Warning: types disagree (cell_topo_type = " << CN::EntityTypeName(input_type)
00904               << ", faces indicate type " << CN::EntityTypeName(this_type) << std::endl;
00905 
00906   if (MBMAXTYPE != input_type && this_type == MBMAXTYPE && input_type != MBPOLYHEDRON)
00907     std::cerr << "Warning: couldn't find proper connectivity for specified topo_type = " 
00908               << CN::EntityTypeName(input_type) << std::endl;
00909 
00910     // now make the element; if we fell back to polyhedron, use faces, otherwise use verts
00911   if (MBPOLYHEDRON == this_type || MBMAXTYPE == this_type) 
00912     rval = mbImpl->create_element(MBPOLYHEDRON, &facehs[0], facehs.size(), cell);
00913   else
00914     rval = mbImpl->create_element(this_type, &verts[0], verts.size(), cell);
00915   CHKERR(rval, "create_element failed.");
00916   
00917   return MB_SUCCESS;
00918 }
00919   
00920 ErrorCode ReadCCMIO::read_all_faces(CCMIOID topologyID, TupleList &vert_map, 
00921                                       TupleList &face_map
00922 #ifndef TUPLE_LIST
00923                                       ,SenseList &sense_map
00924 #endif
00925                                       , Range *new_faces) 
00926 {
00927   CCMIOSize_t index = CCMIOSIZEC(0);
00928   CCMIOID faceID;
00929   ErrorCode rval;
00930 
00931     // get total # internal/bdy faces, size the face map accordingly
00932   int nint_faces = 0, nbdy_faces = 0;
00933   CCMIOSize_t nf;
00934   CCMIOError error = kCCMIONoErr;
00935   while (kCCMIONoErr == CCMIONextEntity(NULL, topologyID, kCCMIOBoundaryFaces, &index, 
00936                                         &faceID))
00937   {
00938     CCMIOEntitySize(&error, faceID, &nf, NULL);
00939     nbdy_faces = nbdy_faces + nf;
00940   }
00941   CCMIOGetEntity(&error, topologyID, kCCMIOInternalFaces, 0, &faceID);
00942   CCMIOEntitySize(&error, faceID, &nf, NULL);
00943   nint_faces = nint_faces + nf;
00944 #ifdef TUPLE_LIST
00945   face_map.resize(2*nint_faces + nbdy_faces);
00946 #endif
00947   
00948     // get multiple blocks of bdy faces
00949   index = CCMIOSIZEC(0);
00950   while (kCCMIONoErr == CCMIONextEntity(NULL, topologyID, kCCMIOBoundaryFaces, &index, 
00951                                         &faceID))
00952   {
00953     rval = read_faces(faceID, kCCMIOBoundaryFaces, vert_map, face_map
00954 #ifndef TUPLE_LIST
00955                       , sense_map
00956 #endif
00957                       , new_faces);
00958     CHKERR(rval, "Trouble reading boundary faces.");
00959   }
00960   
00961     // now get internal faces
00962   CCMIOGetEntity(&error, topologyID, kCCMIOInternalFaces, 0, &faceID);
00963 
00964   rval = read_faces(faceID, kCCMIOInternalFaces, vert_map,face_map
00965 #ifndef TUPLE_LIST
00966                     , sense_map
00967 #endif
00968                     , new_faces);
00969   CHKERR(rval, "Trouble reading internal faces.");
00970 
00971   return rval;
00972 }
00973 
00974 ErrorCode ReadCCMIO::read_faces(CCMIOID faceID, 
00975                                 CCMIOEntity bdy_or_int,
00976                                 TupleList &vert_map,
00977                                 TupleList &face_map
00978 #ifndef TUPLE_LIST
00979                                   ,SenseList &sense_map
00980 #endif
00981                                   , Range *new_faces)
00982 {
00983   if (kCCMIOInternalFaces != bdy_or_int && kCCMIOBoundaryFaces != bdy_or_int)
00984     CHKERR(MB_FAILURE, "Face type isn't boundary or internal.");
00985 
00986   CCMIOSize_t dum_faces;
00987   CCMIOError error = kCCMIONoErr;
00988   CCMIOEntitySize(&error, faceID, &dum_faces, NULL);
00989   int num_faces = GETINT32(dum_faces);
00990   
00991     // get the size of the face connectivity array (not really a straight connect
00992     // array, has n, connect(n), ...)
00993   CCMIOSize_t farray_size = CCMIOSIZEC(0);
00994   CCMIOReadFaces(&error, faceID, bdy_or_int, NULL, &farray_size, NULL,
00995                  CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
00996   CHKCCMERR(error, "Trouble reading face connectivity length.");
00997     
00998 
00999     // allocate vectors for holding farray and cells for each face; use new for finer
01000     // control of de-allocation
01001   int num_sides = (kCCMIOInternalFaces == bdy_or_int ? 2 : 1);
01002   int *farray = new int[GETINT32(farray_size)];
01003 
01004     // read farray and make the faces
01005   CCMIOID mapID;
01006   CCMIOReadFaces(&error, faceID, bdy_or_int, &mapID, NULL,
01007                  farray, CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
01008   CHKCCMERR(error, "Trouble reading face connectivity.");
01009 
01010   std::vector<EntityHandle> face_handles;
01011   ErrorCode rval = make_faces(farray, vert_map, face_handles, num_faces);
01012   CHKERR(rval, NULL);
01013 
01014     // read face cells and make tuples
01015   int *face_cells;
01016   if (num_sides*num_faces < farray_size) face_cells = new int[num_sides*num_faces];
01017   else face_cells = farray;
01018   CCMIOReadFaceCells(&error, faceID, bdy_or_int, face_cells,
01019                      CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
01020   CHKCCMERR(error, "Trouble reading face cells.");
01021 
01022   int *tmp_ptr = face_cells;
01023   for (unsigned int i = 0; i < face_handles.size(); i++) {
01024 #ifdef TUPLE_LIST
01025     short forward = 1, reverse = -1;
01026     face_map.push_back(&forward, tmp_ptr++, &face_handles[i], NULL);
01027     if (2 == num_sides)
01028       face_map.push_back(&reverse, tmp_ptr++, &face_handles[i], NULL);
01029 #else
01030     face_map[*tmp_ptr].push_back(face_handles[i]);
01031     sense_map[*tmp_ptr++].push_back(1);
01032     if (2 == num_sides) {
01033       face_map[*tmp_ptr].push_back(face_handles[i]);
01034       sense_map[*tmp_ptr++].push_back(-1);
01035     }
01036 #endif
01037   }
01038 
01039     // now read & set face gids, reuse face_cells 'cuz we know it's big enough
01040   CCMIOReadMap(&error, mapID, face_cells, CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
01041   CHKCCMERR(error, "Trouble reading face gids.");
01042 
01043   rval = mbImpl->tag_set_data(mGlobalIdTag, &face_handles[0], face_handles.size(), face_cells);
01044   CHKERR(rval, "Couldn't set face global ids.");
01045 
01046     // make a neumann set for these faces if they're all in a boundary face set
01047   if (kCCMIOBoundaryFaces == bdy_or_int) {
01048     EntityHandle neuset;
01049     rval = mbImpl->create_meshset(MESHSET_SET, neuset);
01050     CHKERR(rval, "Failed to create neumann set.");
01051 
01052       // don't trust entity index passed in
01053     int index;
01054     CCMIOGetEntityIndex(&error, faceID, &index);
01055     newNeusets[index] = neuset;
01056 
01057     rval = mbImpl->add_entities(neuset, &face_handles[0], face_handles.size());
01058     CHKERR(rval, "Failed to add faces to neumann set.");
01059 
01060       // now tag as neumann set; will add id later
01061     int dum_val = 0;
01062     rval = mbImpl->tag_set_data(mNeumannSetTag, &neuset, 1, &dum_val);
01063     CHKERR(rval, "Failed to tag neumann set.");
01064   }
01065 
01066   if (new_faces) {
01067     std::sort(face_handles.begin(), face_handles.end());
01068     std::copy(face_handles.rbegin(), face_handles.rend(), range_inserter(*new_faces));
01069   }
01070   
01071   return MB_SUCCESS;
01072 }
01073   
01074 
01075 ErrorCode ReadCCMIO::make_faces(int *farray, 
01076                                 TupleList &vert_map,
01077                                 std::vector<EntityHandle> &new_faces, int num_faces) 
01078 {
01079   std::vector<EntityHandle> verts;
01080   ErrorCode tmp_rval = MB_SUCCESS, rval = MB_SUCCESS;
01081   
01082   for (int i = 0; i < num_faces; i++) {
01083     int num_verts = *farray++;
01084     verts.resize(num_verts);
01085 
01086       // fill in connectivity by looking up by gid in vert tuple_list
01087     for (int j = 0; j < num_verts; j++) {
01088 #ifdef TUPLE_LIST
01089       int tindex = vert_map.find(1, farray[j]);
01090       if (-1 == tindex) {
01091         tmp_rval = MB_FAILURE;
01092         break;
01093       }
01094       verts[j] = vert_map.get_ulong(tindex, 0);
01095 #else
01096       verts[j] = (vert_map[farray[j]])[0];
01097 #endif      
01098     }
01099     farray += num_verts;
01100 
01101     if (MB_SUCCESS == tmp_rval) {
01102     
01103         // make face
01104       EntityType ftype = (3 == num_verts ? MBTRI :
01105                             (4 == num_verts ? MBQUAD : MBPOLYGON));
01106       EntityHandle faceh;
01107       tmp_rval = mbImpl->create_element(ftype, &verts[0], num_verts, faceh);
01108       if (faceh) new_faces.push_back(faceh);
01109     }
01110     
01111     if (MB_SUCCESS != tmp_rval) rval = tmp_rval;
01112   }
01113   
01114   return rval;
01115 }
01116 
01117 ErrorCode ReadCCMIO::read_vertices(CCMIOSize_t /* proc */, CCMIOID /* processorID */, CCMIOID verticesID,
01118                                    CCMIOID /* topologyID */, 
01119                                    Range *verts, TupleList &vert_map) 
01120 {
01121   CCMIOError error = kCCMIONoErr;
01122   
01123     // pre-read the number of vertices, so we can pre-allocate & read directly in
01124   CCMIOSize_t nverts = CCMIOSIZEC(0);
01125   CCMIOEntitySize(&error, verticesID, &nverts, NULL);
01126   CHKCCMERR(error, "Couldn't get number of vertices.");
01127 
01128     // get # dimensions
01129   CCMIOSize_t dims;
01130   float scale;
01131   CCMIOReadVerticesf(&error, verticesID, &dims, NULL, NULL, NULL, CCMIOINDEXC(0), CCMIOINDEXC(1));
01132   CHKCCMERR(error, "Couldn't get number of dimensions.");
01133 
01134     // allocate vertex space
01135   EntityHandle node_handle = 0;
01136   std::vector<double*> arrays;
01137   readMeshIface->get_node_coords(3, GETINT32(nverts), MB_START_ID, node_handle, arrays);
01138 
01139     // read vertex coords
01140   CCMIOID mapID;
01141   std::vector<double> tmp_coords(GETINT32(dims)*GETINT32(nverts));
01142   CCMIOReadVerticesd(&error, verticesID, &dims, &scale, &mapID, &tmp_coords[0], 
01143                      CCMIOINDEXC(0), CCMIOINDEXC(0+nverts));
01144   CHKCCMERR(error, "Trouble reading vertex coordinates.");
01145 
01146     // copy interleaved coords into moab blocked coordinate space
01147   int i = 0, threei = 0;
01148   for (; i < nverts; i++) {
01149     arrays[0][i] = tmp_coords[threei++];
01150     arrays[1][i] = tmp_coords[threei++];
01151     if (3 == GETINT32(dims)) arrays[2][i] = tmp_coords[threei++];
01152     else arrays[2][i] = 0.0;
01153   }
01154 
01155     // scale, if necessary
01156   if (1.0 != scale) {
01157     for(i = 0; i < nverts; i++) {
01158       arrays[0][i] *= scale;
01159       arrays[1][i] *= scale;
01160       if (3 == GETINT32(dims)) arrays[2][i] *= scale;
01161     }
01162   }
01163 
01164     // read gids for vertices
01165   std::vector<int> gids(GETINT32(nverts));
01166   CCMIOReadMap(&error, mapID, &gids[0], CCMIOINDEXC(kCCMIOStart), CCMIOINDEXC(kCCMIOEnd));
01167   CHKCCMERR(error, "Trouble reading vertex global ids.");
01168 
01169     // put new vertex handles into range, and set gids for them
01170   Range new_verts(node_handle, node_handle+nverts-1);
01171   ErrorCode rval = mbImpl->tag_set_data(mGlobalIdTag, new_verts, &gids[0]);
01172   CHKERR(rval, "Couldn't set gids on vertices.");
01173   
01174     // pack vert_map with global ids and handles for these vertices
01175 #ifdef TUPLE_LIST
01176   vert_map.resize(GETINT32(nverts));
01177   for (i = 0; i < GETINT32(nverts); i++) {
01178     vert_map.push_back(NULL, &gids[i], &node_handle, NULL);
01179 #else
01180   for (i = 0; i < GETINT32(nverts); i++) {
01181     (vert_map[gids[i]]).push_back(node_handle);
01182 #endif
01183     node_handle += 1;
01184   }
01185   
01186   if (verts) verts->merge(new_verts);
01187 
01188   return MB_SUCCESS;
01189 }
01190   
01191 ErrorCode ReadCCMIO::get_processors(CCMIOID stateID, 
01192                                     CCMIOID &processorID, CCMIOID &verticesID,
01193                                     CCMIOID &topologyID, CCMIOID &solutionID,
01194                                     std::vector<CCMIOSize_t> &procs,
01195                                     bool & /* has_solution */) 
01196 {
01197   CCMIOSize_t proc = CCMIOSIZEC(0);
01198   CCMIOError error = kCCMIONoErr;
01199   
01200   CCMIONextEntity(&error, stateID, kCCMIOProcessor, &proc, &processorID);
01201   CHKCCMERR(error, NULL);
01202   if (CCMIOReadProcessor(NULL, processorID, &verticesID, 
01203                          &topologyID, NULL, &solutionID) != kCCMIONoErr) {
01204       // Maybe no solution;  try again
01205     CCMIOReadProcessor(&error, processorID, &verticesID, 
01206                        &topologyID, NULL, NULL);
01207     hasSolution = false;
01208   }
01209   CHKCCMERR(error, NULL);
01210   
01211   procs.push_back(proc);
01212   
01213   return MB_SUCCESS;
01214 }
01215 
01216 ErrorCode ReadCCMIO::read_tag_values( const char* ,
01217                                       const char* ,
01218                                       const FileOptions& ,
01219                                       std::vector<int>& ,
01220                                       const SubsetList* ) 
01221 {
01222   return MB_FAILURE;
01223 }
01224 
01225 } // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines