MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 /** 00017 * \class ReadRTT 00018 * \brief ReadRTT based on ReadNASTRAN 00019 * 00020 * See: 00021 * 00022 * \author Andrew Davis 00023 */ 00024 00025 #include "ReadRTT.hpp" 00026 00027 #include <iostream> 00028 #include <sstream> 00029 #include <fstream> 00030 #include <vector> 00031 #include <cstdlib> 00032 #include <map> 00033 #include <assert.h> 00034 #include <cmath> 00035 00036 #include "moab/Interface.hpp" 00037 #include "moab/ReadUtilIface.hpp" 00038 #include "Internals.hpp" // for MB_START_ID 00039 #include "moab/Range.hpp" 00040 #include "moab/FileOptions.hpp" 00041 #include "FileTokenizer.hpp" 00042 #include "MBTagConventions.hpp" 00043 #include "moab/CN.hpp" 00044 #include "moab/ErrorHandler.hpp" 00045 #include "moab/GeomTopoTool.hpp" 00046 00047 namespace moab 00048 { 00049 00050 ReaderIface* ReadRTT::factory( Interface* iface ) 00051 { 00052 return new ReadRTT( iface ); 00053 } 00054 00055 // constructor 00056 ReadRTT::ReadRTT( Interface* impl ) 00057 : MBI( impl ), geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 ) 00058 { 00059 assert( NULL != impl ); 00060 myGeomTool = new GeomTopoTool( impl ); 00061 MBI->query_interface( readMeshIface ); 00062 assert( NULL != readMeshIface ); 00063 00064 // this section copied from ReadCGM initalisation 00065 int negone = -1; 00066 double zero = 0.; 00067 ErrorCode rval; 00068 rval = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT, 00069 &negone ); 00070 assert( !rval ); 00071 id_tag = MBI->globalId_tag(); 00072 rval = MBI->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 00073 assert( !rval ); 00074 rval = MBI->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag, 00075 MB_TAG_SPARSE | MB_TAG_CREAT ); 00076 assert( !rval ); 00077 rval = 00078 MBI->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag, MB_TAG_SPARSE | MB_TAG_CREAT, &zero ); 00079 assert( !rval ); 00080 #ifdef NDEBUG 00081 if( !rval ) {}; // Line to avoid compiler warning about variable set but not used 00082 #endif 00083 } 00084 00085 // destructor 00086 ReadRTT::~ReadRTT() 00087 { 00088 if( readMeshIface ) 00089 { 00090 MBI->release_interface( readMeshIface ); 00091 readMeshIface = 0; 00092 } 00093 00094 delete myGeomTool; 00095 } 00096 00097 ErrorCode ReadRTT::read_tag_values( const char* /*file_name*/, const char* /*tag_name*/, const FileOptions& /*opts*/, 00098 std::vector< int >& /*tag_values_out*/, const SubsetList* /*subset_list*/ ) 00099 { 00100 return MB_NOT_IMPLEMENTED; 00101 } 00102 00103 // load the file as called by the Interface function 00104 ErrorCode ReadRTT::load_file( const char* filename, const EntityHandle*, const FileOptions&, 00105 const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/ ) 00106 { 00107 ErrorCode rval; 00108 00109 // at this time there is no support for reading a subset of the file 00110 if( subset_list ) 00111 { 00112 std::cout << "Subset reading not supported for RTT meshes" << std::endl; 00113 return MB_UNSUPPORTED_OPERATION; 00114 } 00115 00116 // test to see if file exists 00117 FILE* file = NULL; 00118 file = fopen( filename, "r" ); 00119 if( file == NULL ) return MB_FILE_DOES_NOT_EXIST; 00120 // otherwise close the file 00121 fclose( file ); 00122 00123 // read the header 00124 rval = ReadRTT::read_header( filename ); 00125 if( rval != MB_SUCCESS ) return rval; 00126 00127 // read the side_flag data 00128 std::vector< side > side_data; 00129 rval = ReadRTT::read_sides( filename, side_data ); 00130 if( rval != MB_SUCCESS ) return rval; 00131 00132 // read the cell data 00133 std::vector< cell > cell_data; 00134 rval = ReadRTT::read_cells( filename, cell_data ); 00135 if( rval != MB_SUCCESS ) return rval; 00136 00137 // read the node data 00138 std::vector< node > node_data; 00139 rval = ReadRTT::read_nodes( filename, node_data ); 00140 if( rval != MB_SUCCESS ) return rval; 00141 00142 // read the facet data 00143 std::vector< facet > facet_data; 00144 rval = ReadRTT::read_facets( filename, facet_data ); 00145 if( rval != MB_SUCCESS ) return rval; 00146 00147 // read the tetrahedra data 00148 std::vector< tet > tet_data; 00149 rval = ReadRTT::read_tets( filename, tet_data ); 00150 if( rval != MB_SUCCESS ) return rval; 00151 00152 // make the map of surface number in the rttmesh to the surface meshset 00153 std::map< int, EntityHandle > surface_map; // corrsespondance of surface number to entity handle 00154 rval = ReadRTT::generate_topology( side_data, cell_data, surface_map ); 00155 if( rval != MB_SUCCESS ) return rval; 00156 00157 // generate the rest of the database, triangles to surface meshsets etc 00158 rval = ReadRTT::build_moab( node_data, facet_data, tet_data, surface_map ); 00159 if( rval != MB_SUCCESS ) return rval; 00160 00161 return MB_SUCCESS; 00162 } 00163 00164 /* 00165 * builds the topology of the problem 00166 */ 00167 ErrorCode ReadRTT::generate_topology( std::vector< side > side_data, std::vector< cell > cell_data, 00168 std::map< int, EntityHandle >& surface_map ) 00169 { 00170 00171 ErrorCode rval; 00172 std::vector< EntityHandle > entmap[4]; 00173 int num_ents[4]; // number of entities in each dimension 00174 00175 const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" }; 00176 00177 std::vector< int > surface_numbers; // the surface numbers in the problem 00178 00179 // corresponds to number of cad like surfaces and cad like volumes 00180 num_ents[2] = side_data.size(); 00181 num_ents[3] = cell_data.size(); 00182 00183 // loop over surfaces & volumes 00184 for( int dim = 2; dim <= 3; dim++ ) 00185 { 00186 for( int i = 0; i != num_ents[dim]; i++ ) 00187 { 00188 EntityHandle handle; 00189 // create a meshset for each entity surface/volume 00190 rval = MBI->create_meshset( dim == 1 ? MESHSET_ORDERED : MESHSET_SET, handle ); 00191 // if failure 00192 if( rval != MB_SUCCESS ) return rval; 00193 00194 // collect the entity handles into an 00195 entmap[dim].push_back( handle ); 00196 00197 // set the dimension tag 00198 rval = MBI->tag_set_data( geom_tag, &handle, 1, &dim ); 00199 // if fail 00200 if( MB_SUCCESS != rval ) return rval; 00201 // if we are a surface 00202 if( dim == 2 ) 00203 { 00204 // tag the id onto the surface meshset 00205 rval = MBI->tag_set_data( id_tag, &handle, 1, &side_data[i].id ); 00206 // inesert entity into the map 00207 surface_map[side_data[i].id] = handle; 00208 } 00209 else 00210 { 00211 // otherwise we set the volume tag data, loop is only 2 & 3 dim 00212 rval = MBI->tag_set_data( id_tag, &handle, 1, &cell_data[i].id ); 00213 } 00214 // if fail 00215 if( MB_SUCCESS != rval ) return rval; 00216 // set the category tag 00217 rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[dim] ); 00218 if( MB_SUCCESS != rval ) return rval; 00219 } 00220 } 00221 00222 // generate parent child links 00223 // best to loop over the surfaces and assign them to volumes, we can then assign facets to 00224 // to each surface 00225 generate_parent_child_links( num_ents, entmap, side_data, cell_data ); 00226 00227 // set the surface senses 00228 set_surface_senses( num_ents, entmap, side_data, cell_data ); 00229 00230 // set the group data 00231 rval = setup_group_data( entmap ); 00232 00233 return MB_SUCCESS; 00234 } 00235 00236 /* 00237 * builds the moab representation of the mesh 00238 */ 00239 ErrorCode ReadRTT::build_moab( std::vector< node > node_data, std::vector< facet > facet_data, 00240 std::vector< tet > tet_data, std::map< int, EntityHandle > surface_map ) 00241 { 00242 00243 ErrorCode rval; // reusable return value 00244 EntityHandle file_set; // the file handle 00245 // create the file set 00246 rval = MBI->create_meshset( MESHSET_SET, file_set ); 00247 if( MB_SUCCESS != rval ) return rval; 00248 00249 // create the vertices 00250 EntityHandle handle; 00251 std::vector< node >::iterator it; // iterate over the nodes 00252 Range mb_coords; // range of coordinates 00253 for( it = node_data.begin(); it != node_data.end(); ++it ) 00254 { 00255 node tmp = *it; 00256 double coords[3] = { tmp.x, tmp.y, tmp.z }; 00257 rval = MBI->create_vertex( coords, handle ); 00258 if( MB_SUCCESS != rval ) return rval; 00259 mb_coords.insert( handle ); // inesert handle into the coordinate range 00260 } 00261 00262 // add verts to set 00263 rval = MBI->add_entities( file_set, mb_coords ); 00264 00265 // create sense tag 00266 Tag side_id_tag, surface_number_tag; 00267 // int zero = 0; 00268 rval = MBI->tag_get_handle( "SIDEID_TAG", 1, MB_TYPE_INTEGER, side_id_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 00269 rval = 00270 MBI->tag_get_handle( "SURFACE_NUMBER", 1, MB_TYPE_INTEGER, surface_number_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 00271 00272 // create the facets 00273 EntityHandle triangle; 00274 std::vector< facet >::iterator it_f; 00275 // range of triangles 00276 Range mb_tris; 00277 // loop over the facet data 00278 for( it_f = facet_data.begin(); it_f != facet_data.end(); ++it_f ) 00279 { 00280 facet tmp = *it_f; 00281 // get the nodes for the triangle 00282 EntityHandle tri_nodes[3] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1], 00283 mb_coords[tmp.connectivity[2] - 1] }; 00284 // create a triangle element 00285 rval = MBI->create_element( MBTRI, tri_nodes, 3, triangle ); 00286 // tag in side id on the triangle 00287 rval = MBI->tag_set_data( side_id_tag, &triangle, 1, &tmp.side_id ); 00288 // tag the surface number on the triangle 00289 rval = MBI->tag_set_data( surface_number_tag, &triangle, 1, &tmp.surface_number ); 00290 // insert vertices and triangles into the appropriate surface meshset 00291 EntityHandle meshset_handle = surface_map[tmp.surface_number]; 00292 // also set surface tag 00293 rval = MBI->tag_set_data( side_id_tag, &meshset_handle, 1, &tmp.side_id ); 00294 rval = MBI->tag_set_data( surface_number_tag, &meshset_handle, 1, &tmp.surface_number ); 00295 // add vertices to the mesh 00296 rval = MBI->add_entities( meshset_handle, &( *tri_nodes ), 3 ); 00297 // add triangles to the meshset 00298 rval = MBI->add_entities( meshset_handle, &triangle, 1 ); 00299 // ineter triangles into large run 00300 mb_tris.insert( triangle ); 00301 } 00302 // add tris to set to fileset 00303 rval = MBI->add_entities( file_set, mb_tris ); 00304 00305 // create material number tag 00306 Tag mat_num_tag; 00307 // int zero = 0; 00308 rval = MBI->tag_get_handle( "MATERIAL_NUMBER", 1, MB_TYPE_INTEGER, mat_num_tag, MB_TAG_SPARSE | MB_TAG_CREAT ); 00309 00310 // create the tets 00311 EntityHandle tetra; // handle for a specific tet 00312 std::vector< tet >::iterator it_t; 00313 Range mb_tets; 00314 // loop over all tets 00315 for( it_t = tet_data.begin(); it_t != tet_data.end(); ++it_t ) 00316 { 00317 tet tmp = *it_t; 00318 // get the handles for the tet 00319 EntityHandle tet_nodes[4] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1], 00320 mb_coords[tmp.connectivity[2] - 1], mb_coords[tmp.connectivity[3] - 1] }; 00321 // create the tet 00322 rval = MBI->create_element( MBTET, tet_nodes, 4, tetra ); 00323 int mat_number = tmp.material_number; 00324 // tag the tet with the material number 00325 rval = MBI->tag_set_data( mat_num_tag, &tetra, 1, &mat_number ); 00326 // set the tag data 00327 mb_tets.insert( tetra ); 00328 } 00329 // add tris to set 00330 rval = MBI->add_entities( file_set, mb_tets ); 00331 00332 return MB_SUCCESS; 00333 } 00334 00335 /* 00336 * read the header data from the filename pointed to 00337 */ 00338 ErrorCode ReadRTT::read_header( const char* filename ) 00339 { 00340 std::ifstream input_file( filename ); // filename for rtt file 00341 // file ok? 00342 if( !input_file.good() ) 00343 { 00344 std::cout << "Problems reading file = " << filename << std::endl; 00345 return MB_FAILURE; 00346 } 00347 00348 // if it works 00349 std::string line; 00350 moab::ErrorCode rval = MB_FAILURE; 00351 if( input_file.is_open() ) 00352 { 00353 while( std::getline( input_file, line ) ) 00354 { 00355 if( line.compare( "header" ) == 0 ) { rval = get_header_data( input_file ); } 00356 } 00357 input_file.close(); 00358 } 00359 return rval; 00360 } 00361 00362 /* 00363 * reads the side data from the filename pointed to 00364 */ 00365 ErrorCode ReadRTT::read_sides( const char* filename, std::vector< side >& side_data ) 00366 { 00367 std::string line; // the current line being read 00368 std::ifstream input_file( filename ); // filestream for rttfile 00369 // file ok? 00370 if( !input_file.good() ) 00371 { 00372 std::cout << "Problems reading file = " << filename << std::endl; 00373 return MB_FAILURE; 00374 } 00375 // if it works 00376 if( input_file.is_open() ) 00377 { 00378 while( std::getline( input_file, line ) ) 00379 { 00380 if( line.compare( " 2 FACES\0" ) == 0 ) 00381 { 00382 // read lines until find end nodes 00383 while( std::getline( input_file, line ) ) 00384 { 00385 if( line.compare( "end_side_flags\0" ) == 0 ) break; 00386 side data = ReadRTT::get_side_data( line ); 00387 side_data.push_back( data ); 00388 } 00389 } 00390 } 00391 input_file.close(); 00392 } 00393 if( side_data.size() == 0 ) return MB_FAILURE; 00394 return MB_SUCCESS; 00395 } 00396 00397 /* 00398 * reads the cell data from the filename pointed to 00399 */ 00400 ErrorCode ReadRTT::read_cells( const char* filename, std::vector< cell >& cell_data ) 00401 { 00402 std::string line; // the current line being read 00403 std::ifstream input_file( filename ); // filestream for rttfile 00404 // file ok? 00405 if( !input_file.good() ) 00406 { 00407 std::cout << "Problems reading file = " << filename << std::endl; 00408 return MB_FAILURE; 00409 } 00410 // if it works 00411 if( input_file.is_open() ) 00412 { 00413 while( std::getline( input_file, line ) ) 00414 { 00415 if( line.compare( " 1 REGIONS\0" ) == 0 ) 00416 { 00417 // read lines until find end nodes 00418 while( std::getline( input_file, line ) ) 00419 { 00420 if( line.compare( "end_cell_flags\0" ) == 0 ) break; 00421 cell data = ReadRTT::get_cell_data( line ); 00422 cell_data.push_back( data ); 00423 } 00424 } 00425 } 00426 input_file.close(); 00427 } 00428 if( cell_data.size() == 0 ) return MB_FAILURE; 00429 return MB_SUCCESS; 00430 } 00431 00432 /* 00433 * Reads the node data fromt the filename pointed to 00434 */ 00435 ErrorCode ReadRTT::read_nodes( const char* filename, std::vector< node >& node_data ) 00436 { 00437 std::string line; // the current line being read 00438 std::ifstream input_file( filename ); // filestream for rttfile 00439 // file ok? 00440 if( !input_file.good() ) 00441 { 00442 std::cout << "Problems reading file = " << filename << std::endl; 00443 return MB_FAILURE; 00444 } 00445 00446 // if it works 00447 if( input_file.is_open() ) 00448 { 00449 while( std::getline( input_file, line ) ) 00450 { 00451 if( line.compare( "nodes\0" ) == 0 ) 00452 { 00453 // read lines until find end nodes 00454 while( std::getline( input_file, line ) ) 00455 { 00456 if( line.compare( "end_nodes\0" ) == 0 ) break; 00457 node data = ReadRTT::get_node_data( line ); 00458 node_data.push_back( data ); 00459 } 00460 } 00461 } 00462 input_file.close(); 00463 } 00464 if( node_data.size() == 0 ) return MB_FAILURE; 00465 return MB_SUCCESS; 00466 } 00467 00468 /* 00469 * Reads the facet data fromt the filename pointed to 00470 */ 00471 ErrorCode ReadRTT::read_facets( const char* filename, std::vector< facet >& facet_data ) 00472 { 00473 std::string line; // the current line being read 00474 std::ifstream input_file( filename ); // filestream for rttfile 00475 // file ok? 00476 if( !input_file.good() ) 00477 { 00478 std::cout << "Problems reading file = " << filename << std::endl; 00479 return MB_FAILURE; 00480 } 00481 00482 // if it works 00483 if( input_file.is_open() ) 00484 { 00485 while( std::getline( input_file, line ) ) 00486 { 00487 if( line.compare( "sides\0" ) == 0 ) 00488 { 00489 // read lines until find end nodes 00490 while( std::getline( input_file, line ) ) 00491 { 00492 if( line.compare( "end_sides\0" ) == 0 ) break; 00493 facet data = ReadRTT::get_facet_data( line ); 00494 facet_data.push_back( data ); 00495 } 00496 } 00497 } 00498 input_file.close(); 00499 } 00500 if( facet_data.size() == 0 ) return MB_FAILURE; 00501 return MB_SUCCESS; 00502 } 00503 00504 /* 00505 * Reads the facet data fromt the filename pointed to 00506 */ 00507 ErrorCode ReadRTT::read_tets( const char* filename, std::vector< tet >& tet_data ) 00508 { 00509 std::string line; // the current line being read 00510 std::ifstream input_file( filename ); // filestream for rttfile 00511 // file ok? 00512 if( !input_file.good() ) 00513 { 00514 std::cout << "Problems reading file = " << filename << std::endl; 00515 return MB_FAILURE; 00516 } 00517 // if it works 00518 if( input_file.is_open() ) 00519 { 00520 while( std::getline( input_file, line ) ) 00521 { 00522 if( line.compare( "cells\0" ) == 0 ) 00523 { 00524 // read lines until find end nodes 00525 while( std::getline( input_file, line ) ) 00526 { 00527 if( line.compare( "end_cells\0" ) == 0 ) break; 00528 tet data = ReadRTT::get_tet_data( line ); 00529 tet_data.push_back( data ); 00530 } 00531 } 00532 } 00533 input_file.close(); 00534 } 00535 if( tet_data.size() == 0 ) return MB_FAILURE; 00536 return MB_SUCCESS; 00537 } 00538 00539 /* 00540 * given the open file handle read until we find 00541 */ 00542 ErrorCode ReadRTT::get_header_data( std::ifstream& input_file ) 00543 { 00544 std::string line; 00545 while( std::getline( input_file, line ) ) 00546 { 00547 00548 // tokenize the line 00549 std::istringstream iss( line ); 00550 std::vector< std::string > split_string; 00551 do 00552 { 00553 std::string sub_string; 00554 iss >> sub_string; 00555 split_string.push_back( sub_string ); 00556 } while( iss ); 00557 00558 // if we find version 00559 if( line.find( "version" ) != std::string::npos ) 00560 { 00561 if( split_string[1].find( "v" ) != std::string::npos && 00562 split_string[0].find( "version" ) != std::string::npos ) 00563 { header_data.version = split_string[1]; } 00564 } 00565 00566 if( line.find( "title" ) != std::string::npos ) { header_data.title = split_string[1]; } 00567 if( line.find( "date" ) != std::string::npos ) { header_data.date = split_string[1]; } 00568 if( line.find( "end_header" ) != std::string::npos ) { return MB_SUCCESS; } 00569 } 00570 00571 // otherwise we never found the end_header keyword 00572 return MB_FAILURE; 00573 } 00574 00575 /* 00576 * given the string sidedata, get the id number, senses and names of the sides 00577 */ 00578 ReadRTT::side ReadRTT::get_side_data( std::string sidedata ) 00579 { 00580 side new_side; 00581 std::vector< std::string > tokens; 00582 tokens = ReadRTT::split_string( sidedata, ' ' ); 00583 00584 std::vector< std::string >::iterator it; 00585 // set the side id 00586 if( tokens.size() != 2 ) { MB_SET_ERR_RET_VAL( "Error, too many tokens found from side_data", new_side ); } 00587 // create the new side 00588 new_side.id = std::atoi( tokens[0].c_str() ); 00589 00590 std::vector< std::string > cell_names = ReadRTT::split_string( tokens[1], '/' ); 00591 // get the boundary 00592 boundary new_bnd = ReadRTT::split_name( cell_names[0] ); 00593 // set the surface sense and name 00594 new_side.senses[0] = new_bnd.sense; 00595 new_side.names[0] = new_bnd.name; 00596 // 00597 if( cell_names.size() > 1 ) 00598 { 00599 boundary bnd = ReadRTT::split_name( cell_names[1] ); 00600 new_side.senses[1] = bnd.sense; 00601 new_side.names[1] = bnd.name; 00602 } 00603 else 00604 { 00605 new_side.senses[1] = 0; 00606 new_side.names[1] = "\0"; 00607 } 00608 00609 return new_side; 00610 } 00611 00612 /* 00613 * given the string celldata, get the id number and name of each cell 00614 */ 00615 ReadRTT::cell ReadRTT::get_cell_data( std::string celldata ) 00616 { 00617 cell new_cell; 00618 std::vector< std::string > tokens; 00619 tokens = ReadRTT::split_string( celldata, ' ' ); 00620 00621 std::vector< std::string >::iterator it; 00622 00623 // set the side id 00624 if( tokens.size() != 2 ) { MB_SET_ERR_RET_VAL( "Error, too many tokens found from cell_data", new_cell ); } 00625 // create the new side 00626 new_cell.id = std::atoi( tokens[0].c_str() ); 00627 new_cell.name = tokens[1]; 00628 00629 return new_cell; 00630 } 00631 00632 /* 00633 * given the string nodedata, get the id number and coordinates of the node 00634 */ 00635 ReadRTT::node ReadRTT::get_node_data( std::string nodedata ) 00636 { 00637 node new_node; 00638 std::vector< std::string > tokens; 00639 tokens = ReadRTT::split_string( nodedata, ' ' ); 00640 00641 // set the side id 00642 if( tokens.size() != 5 ) { MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_node_data", new_node ); } 00643 std::vector< std::string >::iterator it; 00644 new_node.id = std::atoi( tokens[0].c_str() ); 00645 new_node.x = std::atof( tokens[1].c_str() ); 00646 new_node.y = std::atof( tokens[2].c_str() ); 00647 new_node.z = std::atof( tokens[3].c_str() ); 00648 return new_node; 00649 } 00650 00651 /* 00652 * given the string nodedata, get the id number, connectivity and sense data 00653 */ 00654 ReadRTT::facet ReadRTT::get_facet_data( std::string facetdata ) 00655 { 00656 facet new_facet; 00657 std::vector< std::string > tokens; 00658 tokens = ReadRTT::split_string( facetdata, ' ' ); 00659 00660 // set the side id 00661 if( tokens.size() != 7 ) { MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_facet_data", new_facet ); } 00662 00663 new_facet.id = std::atoi( tokens[0].c_str() ); 00664 // branch on the rtt version number 00665 if( header_data.version == "v1.0.0" ) 00666 { 00667 new_facet.connectivity[0] = std::atoi( tokens[1].c_str() ); 00668 new_facet.connectivity[1] = std::atoi( tokens[2].c_str() ); 00669 new_facet.connectivity[2] = std::atoi( tokens[3].c_str() ); 00670 new_facet.side_id = std::atoi( tokens[4].c_str() ); 00671 new_facet.surface_number = std::atoi( tokens[5].c_str() ); 00672 } 00673 else if( header_data.version == "v1.0.1" ) 00674 { 00675 new_facet.connectivity[0] = std::atoi( tokens[2].c_str() ); 00676 new_facet.connectivity[1] = std::atoi( tokens[3].c_str() ); 00677 new_facet.connectivity[2] = std::atoi( tokens[4].c_str() ); 00678 new_facet.side_id = std::atoi( tokens[5].c_str() ); 00679 new_facet.surface_number = std::atoi( tokens[6].c_str() ); 00680 } 00681 else 00682 { 00683 MB_SET_ERR_RET_VAL( "Error, version number not understood", new_facet ); 00684 } 00685 00686 return new_facet; 00687 } 00688 00689 /* 00690 * given the string tetdata, get the id number, connectivity and mat num of the tet 00691 */ 00692 ReadRTT::tet ReadRTT::get_tet_data( std::string tetdata ) 00693 { 00694 tet new_tet; 00695 std::vector< std::string > tokens; 00696 tokens = ReadRTT::split_string( tetdata, ' ' ); 00697 00698 // set the side id 00699 if( tokens.size() != 7 ) { MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_tet_data", new_tet ); } 00700 new_tet.id = std::atoi( tokens[0].c_str() ); 00701 // branch on the version number 00702 if( header_data.version == "v1.0.0" ) 00703 { 00704 new_tet.connectivity[0] = std::atoi( tokens[1].c_str() ); 00705 new_tet.connectivity[1] = std::atoi( tokens[2].c_str() ); 00706 new_tet.connectivity[2] = std::atoi( tokens[3].c_str() ); 00707 new_tet.connectivity[3] = std::atoi( tokens[4].c_str() ); 00708 new_tet.material_number = std::atoi( tokens[5].c_str() ); 00709 } 00710 else if( header_data.version == "v1.0.1" ) 00711 { 00712 new_tet.connectivity[0] = std::atoi( tokens[2].c_str() ); 00713 new_tet.connectivity[1] = std::atoi( tokens[3].c_str() ); 00714 new_tet.connectivity[2] = std::atoi( tokens[4].c_str() ); 00715 new_tet.connectivity[3] = std::atoi( tokens[5].c_str() ); 00716 new_tet.material_number = std::atoi( tokens[6].c_str() ); 00717 } 00718 else 00719 { 00720 MB_SET_ERR_RET_VAL( "Error, version number not supported", new_tet ); 00721 } 00722 00723 return new_tet; 00724 } 00725 00726 /* 00727 * splits string into sense and name, to later facilitate the building 00728 * of sense data, strips off the tailing @ if it exists 00729 */ 00730 ReadRTT::boundary ReadRTT::split_name( std::string atilla_cellname ) 00731 { 00732 boundary new_boundary; 00733 // default initialisation 00734 new_boundary.sense = 0; 00735 new_boundary.name = "\0"; 00736 // +ve sense 00737 if( atilla_cellname.find( "+" ) != std::string::npos ) 00738 { 00739 new_boundary.sense = 1; 00740 // look for the @# we do not want it 00741 std::size_t found = atilla_cellname.find( "@" ); 00742 if( found != std::string::npos ) 00743 new_boundary.name = atilla_cellname.substr( 3, found ); 00744 else 00745 new_boundary.name = atilla_cellname.substr( 3, atilla_cellname.length() ); 00746 } 00747 else if( atilla_cellname.find( "-" ) != std::string::npos ) 00748 { 00749 // negative sense 00750 new_boundary.sense = -1; 00751 new_boundary.name = atilla_cellname.substr( 3, atilla_cellname.length() ); 00752 } 00753 return new_boundary; 00754 } 00755 00756 /* 00757 * splits a string in a vector of strings split by spaces 00758 */ 00759 std::vector< std::string > ReadRTT::split_string( std::string string_to_split, char split_char ) 00760 { 00761 std::istringstream ss( string_to_split ); 00762 std::vector< std::string > tokens; 00763 while( !ss.eof() ) 00764 { 00765 std::string x; // here's a nice, empty string 00766 std::getline( ss, x, split_char ); // try to read the next field into it 00767 tokens.push_back( x ); 00768 } 00769 00770 // remove empty tokens 00771 std::vector< std::string >::iterator it; 00772 for( it = tokens.begin(); it != tokens.end(); ) 00773 { 00774 std::string string = *it; 00775 if( string.compare( "\0" ) == 0 ) 00776 it = tokens.erase( it ); 00777 else 00778 ++it; 00779 } 00780 return tokens; 00781 } 00782 00783 /* 00784 * Generate the parent-child links bwetween the cell and surface meshsets 00785 */ 00786 void ReadRTT::generate_parent_child_links( int num_ents[4], std::vector< EntityHandle > entity_map[4], 00787 std::vector< side > side_data, std::vector< cell > cell_data ) 00788 { 00789 ErrorCode rval; // return value 00790 // loop over the number of surfaces 00791 for( int i = 0; i < num_ents[2]; i++ ) 00792 { 00793 // get the surface handle 00794 EntityHandle surf_handle = entity_map[2][i]; 00795 // there are volumes that share this face 00796 for( unsigned int shared = 0; shared <= 1; shared++ ) 00797 { 00798 std::string parent_name = side_data[i].names[shared]; 00799 // find the @ sign 00800 unsigned pos = parent_name.find( "@" ); 00801 parent_name = parent_name.substr( 0, pos ); 00802 00803 // loop over tets looking for matching name 00804 for( int j = 0; j < num_ents[3]; j++ ) 00805 { 00806 // if match found 00807 if( cell_data[j].name.compare( parent_name ) == 0 ) 00808 { 00809 EntityHandle cell_handle = entity_map[3][j]; 00810 // parent 00811 rval = MBI->add_parent_child( cell_handle, surf_handle ); 00812 if( rval != MB_SUCCESS ) { std::cerr << "Failed to add parent child relationship" << std::endl; } 00813 } 00814 } 00815 } 00816 } 00817 return; 00818 } 00819 00820 /* 00821 * sets the sense of the surfaces wrt to volumes using geom topo tool 00822 */ 00823 void ReadRTT::set_surface_senses( int num_ents[4], std::vector< EntityHandle > entity_map[4], 00824 std::vector< side > side_data, std::vector< cell > cell_data ) 00825 { 00826 00827 ErrorCode rval; // return value 00828 // loop over the number of surfaces 00829 for( int i = 0; i < num_ents[2]; i++ ) 00830 { 00831 EntityHandle surf_handle = entity_map[2][i]; 00832 // there are 2 volumes that share this face 00833 for( unsigned int shared = 0; shared <= 1; shared++ ) 00834 { 00835 std::string parent_name = side_data[i].names[shared]; 00836 unsigned pos = parent_name.find( "@" ); 00837 parent_name = parent_name.substr( 0, pos ); 00838 // loop over tets looking for matching name 00839 for( int j = 0; j < num_ents[3]; j++ ) 00840 { 00841 // if match found 00842 if( cell_data[j].name.compare( parent_name ) == 0 ) 00843 { 00844 EntityHandle cell_handle = entity_map[3][j]; 00845 // in rtt mesh +represents the inside and -represents outside 00846 // in moab reverse is outside and forward is inside 00847 if( side_data[i].senses[shared] == 1 ) 00848 rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_FORWARD ); 00849 else if( side_data[i].senses[shared] == -1 ) 00850 rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_REVERSE ); 00851 else 00852 rval = myGeomTool->set_sense( surf_handle, 0, SENSE_REVERSE ); 00853 00854 if( rval != MB_SUCCESS ) { std::cerr << "Failed to set sense appropriately" << std::endl; } 00855 } 00856 } 00857 } 00858 } 00859 return; 00860 } 00861 00862 /* 00863 * Add all entities that are to be part of the graveyard 00864 */ 00865 ErrorCode ReadRTT::setup_group_data( std::vector< EntityHandle > entity_map[4] ) 00866 { 00867 ErrorCode rval; // error codes 00868 EntityHandle handle; 00869 handle = create_group( "graveyard_comp", 1 ); 00870 00871 // add any volume to group graveyard, it is ignored by dag 00872 EntityHandle vol_handle = entity_map[3][0]; 00873 rval = MBI->add_entities( handle, &vol_handle, 1 ); 00874 return rval; 00875 } 00876 00877 /* 00878 * create a new group of with the name group name and id 00879 */ 00880 EntityHandle ReadRTT::create_group( std::string group_name, int id ) 00881 { 00882 ErrorCode rval; 00883 // category tags 00884 const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" }; 00885 00886 EntityHandle handle; 00887 rval = MBI->create_meshset( MESHSET_SET, handle ); 00888 if( MB_SUCCESS != rval ) return rval; 00889 00890 rval = MBI->tag_set_data( name_tag, &handle, 1, group_name.c_str() ); 00891 if( MB_SUCCESS != rval ) return MB_FAILURE; 00892 00893 rval = MBI->tag_set_data( id_tag, &handle, 1, &id ); 00894 if( MB_SUCCESS != rval ) return MB_FAILURE; 00895 00896 rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[4] ); 00897 if( MB_SUCCESS != rval ) return MB_FAILURE; 00898 00899 return handle; 00900 } 00901 00902 } // namespace moab