moab
|
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