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