Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
ReadRTT.cpp
Go to the documentation of this file.
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 /**
17  * \class ReadRTT
18  * \brief ReadRTT based on ReadNASTRAN
19  *
20  * See:
21  *
22  * \author Andrew Davis
23  */
24 
25 #include "ReadRTT.hpp"
26 
27 #include <iostream>
28 #include <sstream>
29 #include <fstream>
30 #include <vector>
31 #include <cstdlib>
32 #include <map>
33 #include <cassert>
34 #include <cmath>
35 
36 #include "moab/Interface.hpp"
37 #include "moab/ReadUtilIface.hpp"
38 #include "Internals.hpp" // for MB_START_ID
39 #include "moab/Range.hpp"
40 #include "moab/FileOptions.hpp"
41 #include "FileTokenizer.hpp"
42 #include "MBTagConventions.hpp"
43 #include "moab/CN.hpp"
44 #include "moab/ErrorHandler.hpp"
45 #include "moab/GeomTopoTool.hpp"
46 
47 namespace moab
48 {
49 
51 {
52  return new ReadRTT( iface );
53 }
54 
55 // constructor
57  : MBI( impl ), geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 )
58 {
59  assert( NULL != impl );
60  myGeomTool = new GeomTopoTool( impl );
62  assert( NULL != readMeshIface );
63 
64  // this section copied from ReadCGM initalisation
65  int negone = -1;
66  double zero = 0.;
67  ErrorCode rval;
69  &negone );
70  assert( !rval );
71  id_tag = MBI->globalId_tag();
73  assert( !rval );
76  assert( !rval );
77  rval =
79  assert( !rval );
80 #ifdef NDEBUG
81  if( !rval )
82  {
83  }; // Line to avoid compiler warning about variable set but not used
84 #endif
85 }
86 
87 // destructor
89 {
90  if( readMeshIface )
91  {
93  readMeshIface = 0;
94  }
95 
96  delete myGeomTool;
97 }
98 
99 ErrorCode ReadRTT::read_tag_values( const char* /*file_name*/,
100  const char* /*tag_name*/,
101  const FileOptions& /*opts*/,
102  std::vector< int >& /*tag_values_out*/,
103  const SubsetList* /*subset_list*/ )
104 {
105  return MB_NOT_IMPLEMENTED;
106 }
107 
108 // load the file as called by the Interface function
109 ErrorCode ReadRTT::load_file( const char* filename,
110  const EntityHandle*,
111  const FileOptions&,
112  const ReaderIface::SubsetList* subset_list,
113  const Tag* /*file_id_tag*/ )
114 {
115  ErrorCode rval;
116 
117  // at this time there is no support for reading a subset of the file
118  if( subset_list )
119  {
120  std::cout << "Subset reading not supported for RTT meshes" << std::endl;
122  }
123 
124  // test to see if file exists
125  FILE* file = NULL;
126  file = fopen( filename, "r" );
127  if( file == NULL ) return MB_FILE_DOES_NOT_EXIST;
128  // otherwise close the file
129  fclose( file );
130 
131  // read the header
132  rval = ReadRTT::read_header( filename );
133  if( rval != MB_SUCCESS ) return rval;
134 
135  // read the side_flag data
136  std::vector< side > side_data;
137  rval = ReadRTT::read_sides( filename, side_data );
138  if( rval != MB_SUCCESS ) return rval;
139 
140  // read the cell data
141  std::vector< cell > cell_data;
142  rval = ReadRTT::read_cells( filename, cell_data );
143  if( rval != MB_SUCCESS ) return rval;
144 
145  // read the node data
146  std::vector< node > node_data;
147  rval = ReadRTT::read_nodes( filename, node_data );
148  if( rval != MB_SUCCESS ) return rval;
149 
150  // read the facet data
151  std::vector< facet > facet_data;
152  rval = ReadRTT::read_facets( filename, facet_data );
153  if( rval != MB_SUCCESS ) return rval;
154 
155  // read the tetrahedra data
156  std::vector< tet > tet_data;
157  rval = ReadRTT::read_tets( filename, tet_data );
158  if( rval != MB_SUCCESS ) return rval;
159 
160  // make the map of surface number in the rttmesh to the surface meshset
161  std::map< int, EntityHandle > surface_map; // corrsespondance of surface number to entity handle
162  rval = ReadRTT::generate_topology( side_data, cell_data, surface_map );
163  if( rval != MB_SUCCESS ) return rval;
164 
165  // generate the rest of the database, triangles to surface meshsets etc
166  rval = ReadRTT::build_moab( node_data, facet_data, tet_data, surface_map );
167  if( rval != MB_SUCCESS ) return rval;
168 
169  return MB_SUCCESS;
170 }
171 
172 /*
173  * builds the topology of the problem
174  */
175 ErrorCode ReadRTT::generate_topology( std::vector< side > side_data,
176  std::vector< cell > cell_data,
177  std::map< int, EntityHandle >& surface_map )
178 {
179 
180  ErrorCode rval;
181  std::vector< EntityHandle > entmap[4];
182  int num_ents[4]; // number of entities in each dimension
183 
184  const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
185 
186  std::vector< int > surface_numbers; // the surface numbers in the problem
187 
188  // corresponds to number of cad like surfaces and cad like volumes
189  num_ents[2] = side_data.size();
190  num_ents[3] = cell_data.size();
191 
192  // loop over surfaces & volumes
193  for( int dim = 2; dim <= 3; dim++ )
194  {
195  for( int i = 0; i != num_ents[dim]; i++ )
196  {
197  EntityHandle handle;
198  // create a meshset for each entity surface/volume
199  rval = MBI->create_meshset( dim == 1 ? MESHSET_ORDERED : MESHSET_SET, handle );
200  // if failure
201  if( rval != MB_SUCCESS ) return rval;
202 
203  // collect the entity handles into an
204  entmap[dim].push_back( handle );
205 
206  // set the dimension tag
207  rval = MBI->tag_set_data( geom_tag, &handle, 1, &dim );
208  // if fail
209  if( MB_SUCCESS != rval ) return rval;
210  // if we are a surface
211  if( dim == 2 )
212  {
213  // tag the id onto the surface meshset
214  rval = MBI->tag_set_data( id_tag, &handle, 1, &side_data[i].id );
215  // inesert entity into the map
216  surface_map[side_data[i].id] = handle;
217  }
218  else
219  {
220  // otherwise we set the volume tag data, loop is only 2 & 3 dim
221  rval = MBI->tag_set_data( id_tag, &handle, 1, &cell_data[i].id );
222  }
223  // if fail
224  if( MB_SUCCESS != rval ) return rval;
225  // set the category tag
226  rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[dim] );
227  if( MB_SUCCESS != rval ) return rval;
228  }
229  }
230 
231  // generate parent child links
232  // best to loop over the surfaces and assign them to volumes, we can then assign facets to
233  // to each surface
234  generate_parent_child_links( num_ents, entmap, side_data, cell_data );
235 
236  // set the surface senses
237  set_surface_senses( num_ents, entmap, side_data, cell_data );
238 
239  // set the group data
240  rval = setup_group_data( entmap );
241 
242  return MB_SUCCESS;
243 }
244 
245 /*
246  * builds the moab representation of the mesh
247  */
248 ErrorCode ReadRTT::build_moab( std::vector< node > node_data,
249  std::vector< facet > facet_data,
250  std::vector< tet > tet_data,
251  std::map< int, EntityHandle > surface_map )
252 {
253 
254  ErrorCode rval; // reusable return value
255  EntityHandle file_set; // the file handle
256  // create the file set
257  rval = MBI->create_meshset( MESHSET_SET, file_set );
258  if( MB_SUCCESS != rval ) return rval;
259 
260  // create the vertices
261  EntityHandle handle;
262  std::vector< node >::iterator it; // iterate over the nodes
263  Range mb_coords; // range of coordinates
264  for( it = node_data.begin(); it != node_data.end(); ++it )
265  {
266  node tmp = *it;
267  double coords[3] = { tmp.x, tmp.y, tmp.z };
268  rval = MBI->create_vertex( coords, handle );
269  if( MB_SUCCESS != rval ) return rval;
270  mb_coords.insert( handle ); // inesert handle into the coordinate range
271  }
272 
273  // add verts to set
274  rval = MBI->add_entities( file_set, mb_coords );
275 
276  // create sense tag
277  Tag side_id_tag, surface_number_tag;
278  // int zero = 0;
279  rval = MBI->tag_get_handle( "SIDEID_TAG", 1, MB_TYPE_INTEGER, side_id_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
280  rval =
281  MBI->tag_get_handle( "SURFACE_NUMBER", 1, MB_TYPE_INTEGER, surface_number_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
282 
283  // create the facets
284  EntityHandle triangle;
285  std::vector< facet >::iterator it_f;
286  // range of triangles
287  Range mb_tris;
288  // loop over the facet data
289  for( it_f = facet_data.begin(); it_f != facet_data.end(); ++it_f )
290  {
291  facet tmp = *it_f;
292  // get the nodes for the triangle
293  EntityHandle tri_nodes[3] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1],
294  mb_coords[tmp.connectivity[2] - 1] };
295  // create a triangle element
296  rval = MBI->create_element( MBTRI, tri_nodes, 3, triangle );
297  // tag in side id on the triangle
298  rval = MBI->tag_set_data( side_id_tag, &triangle, 1, &tmp.side_id );
299  // tag the surface number on the triangle
300  rval = MBI->tag_set_data( surface_number_tag, &triangle, 1, &tmp.surface_number );
301  // insert vertices and triangles into the appropriate surface meshset
302  EntityHandle meshset_handle = surface_map[tmp.surface_number];
303  // also set surface tag
304  rval = MBI->tag_set_data( side_id_tag, &meshset_handle, 1, &tmp.side_id );
305  rval = MBI->tag_set_data( surface_number_tag, &meshset_handle, 1, &tmp.surface_number );
306  // add vertices to the mesh
307  rval = MBI->add_entities( meshset_handle, &( *tri_nodes ), 3 );
308  // add triangles to the meshset
309  rval = MBI->add_entities( meshset_handle, &triangle, 1 );
310  // ineter triangles into large run
311  mb_tris.insert( triangle );
312  }
313  // add tris to set to fileset
314  rval = MBI->add_entities( file_set, mb_tris );
315 
316  // create material number tag
317  Tag mat_num_tag;
318  // int zero = 0;
319  rval = MBI->tag_get_handle( "MATERIAL_NUMBER", 1, MB_TYPE_INTEGER, mat_num_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
320 
321  // create the tets
322  EntityHandle tetra; // handle for a specific tet
323  std::vector< tet >::iterator it_t;
324  Range mb_tets;
325  // loop over all tets
326  for( it_t = tet_data.begin(); it_t != tet_data.end(); ++it_t )
327  {
328  tet tmp = *it_t;
329  // get the handles for the tet
330  EntityHandle tet_nodes[4] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1],
331  mb_coords[tmp.connectivity[2] - 1], mb_coords[tmp.connectivity[3] - 1] };
332  // create the tet
333  rval = MBI->create_element( MBTET, tet_nodes, 4, tetra );
334  int mat_number = tmp.material_number;
335  // tag the tet with the material number
336  rval = MBI->tag_set_data( mat_num_tag, &tetra, 1, &mat_number );
337  // set the tag data
338  mb_tets.insert( tetra );
339  }
340  // add tris to set
341  rval = MBI->add_entities( file_set, mb_tets );
342 
343  return MB_SUCCESS;
344 }
345 
346 /*
347  * read the header data from the filename pointed to
348  */
349 ErrorCode ReadRTT::read_header( const char* filename )
350 {
351  std::ifstream input_file( filename ); // filename for rtt file
352  // file ok?
353  if( !input_file.good() )
354  {
355  std::cout << "Problems reading file = " << filename << std::endl;
356  return MB_FAILURE;
357  }
358 
359  // if it works
360  std::string line;
361  moab::ErrorCode rval = MB_FAILURE;
362  if( input_file.is_open() )
363  {
364  while( std::getline( input_file, line ) )
365  {
366  if( line.compare( "header" ) == 0 )
367  {
368  rval = get_header_data( input_file );
369  }
370  }
371  input_file.close();
372  }
373  return rval;
374 }
375 
376 /*
377  * reads the side data from the filename pointed to
378  */
379 ErrorCode ReadRTT::read_sides( const char* filename, std::vector< side >& side_data )
380 {
381  std::string line; // the current line being read
382  std::ifstream input_file( filename ); // filestream for rttfile
383  // file ok?
384  if( !input_file.good() )
385  {
386  std::cout << "Problems reading file = " << filename << std::endl;
387  return MB_FAILURE;
388  }
389  // if it works
390  if( input_file.is_open() )
391  {
392  while( std::getline( input_file, line ) )
393  {
394  if( line.compare( " 2 FACES\0" ) == 0 )
395  {
396  // read lines until find end nodes
397  while( std::getline( input_file, line ) )
398  {
399  if( line.compare( "end_side_flags\0" ) == 0 ) break;
400  side data = ReadRTT::get_side_data( line );
401  side_data.push_back( data );
402  }
403  }
404  }
405  input_file.close();
406  }
407  if( side_data.size() == 0 ) return MB_FAILURE;
408  return MB_SUCCESS;
409 }
410 
411 /*
412  * reads the cell data from the filename pointed to
413  */
414 ErrorCode ReadRTT::read_cells( const char* filename, std::vector< cell >& cell_data )
415 {
416  std::string line; // the current line being read
417  std::ifstream input_file( filename ); // filestream for rttfile
418  // file ok?
419  if( !input_file.good() )
420  {
421  std::cout << "Problems reading file = " << filename << std::endl;
422  return MB_FAILURE;
423  }
424  // if it works
425  if( input_file.is_open() )
426  {
427  while( std::getline( input_file, line ) )
428  {
429  if( line.compare( " 1 REGIONS\0" ) == 0 )
430  {
431  // read lines until find end nodes
432  while( std::getline( input_file, line ) )
433  {
434  if( line.compare( "end_cell_flags\0" ) == 0 ) break;
435  cell data = ReadRTT::get_cell_data( line );
436  cell_data.push_back( data );
437  }
438  }
439  }
440  input_file.close();
441  }
442  if( cell_data.size() == 0 ) return MB_FAILURE;
443  return MB_SUCCESS;
444 }
445 
446 /*
447  * Reads the node data fromt the filename pointed to
448  */
449 ErrorCode ReadRTT::read_nodes( const char* filename, std::vector< node >& node_data )
450 {
451  std::string line; // the current line being read
452  std::ifstream input_file( filename ); // filestream for rttfile
453  // file ok?
454  if( !input_file.good() )
455  {
456  std::cout << "Problems reading file = " << filename << std::endl;
457  return MB_FAILURE;
458  }
459 
460  // if it works
461  if( input_file.is_open() )
462  {
463  while( std::getline( input_file, line ) )
464  {
465  if( line.compare( "nodes\0" ) == 0 )
466  {
467  // read lines until find end nodes
468  while( std::getline( input_file, line ) )
469  {
470  if( line.compare( "end_nodes\0" ) == 0 ) break;
471  node data = ReadRTT::get_node_data( line );
472  node_data.push_back( data );
473  }
474  }
475  }
476  input_file.close();
477  }
478  if( node_data.size() == 0 ) return MB_FAILURE;
479  return MB_SUCCESS;
480 }
481 
482 /*
483  * Reads the facet data fromt the filename pointed to
484  */
485 ErrorCode ReadRTT::read_facets( const char* filename, std::vector< facet >& facet_data )
486 {
487  std::string line; // the current line being read
488  std::ifstream input_file( filename ); // filestream for rttfile
489  // file ok?
490  if( !input_file.good() )
491  {
492  std::cout << "Problems reading file = " << filename << std::endl;
493  return MB_FAILURE;
494  }
495 
496  // if it works
497  if( input_file.is_open() )
498  {
499  while( std::getline( input_file, line ) )
500  {
501  if( line.compare( "sides\0" ) == 0 )
502  {
503  // read lines until find end nodes
504  while( std::getline( input_file, line ) )
505  {
506  if( line.compare( "end_sides\0" ) == 0 ) break;
507  facet data = ReadRTT::get_facet_data( line );
508  facet_data.push_back( data );
509  }
510  }
511  }
512  input_file.close();
513  }
514  if( facet_data.size() == 0 ) return MB_FAILURE;
515  return MB_SUCCESS;
516 }
517 
518 /*
519  * Reads the facet data fromt the filename pointed to
520  */
521 ErrorCode ReadRTT::read_tets( const char* filename, std::vector< tet >& tet_data )
522 {
523  std::string line; // the current line being read
524  std::ifstream input_file( filename ); // filestream for rttfile
525  // file ok?
526  if( !input_file.good() )
527  {
528  std::cout << "Problems reading file = " << filename << std::endl;
529  return MB_FAILURE;
530  }
531  // if it works
532  if( input_file.is_open() )
533  {
534  while( std::getline( input_file, line ) )
535  {
536  if( line.compare( "cells\0" ) == 0 )
537  {
538  // read lines until find end nodes
539  while( std::getline( input_file, line ) )
540  {
541  if( line.compare( "end_cells\0" ) == 0 ) break;
542  tet data = ReadRTT::get_tet_data( line );
543  tet_data.push_back( data );
544  }
545  }
546  }
547  input_file.close();
548  }
549  if( tet_data.size() == 0 ) return MB_FAILURE;
550  return MB_SUCCESS;
551 }
552 
553 /*
554  * given the open file handle read until we find
555  */
557 {
558  std::string line;
559  while( std::getline( input_file, line ) )
560  {
561 
562  // tokenize the line
563  std::istringstream iss( line );
564  std::vector< std::string > split_string;
565  do
566  {
567  std::string sub_string;
568  iss >> sub_string;
569  split_string.push_back( sub_string );
570  } while( iss );
571 
572  // if we find version
573  if( line.find( "version" ) != std::string::npos )
574  {
575  if( split_string[1].find( "v" ) != std::string::npos &&
576  split_string[0].find( "version" ) != std::string::npos )
577  {
579  }
580  }
581 
582  if( line.find( "title" ) != std::string::npos )
583  {
585  }
586  if( line.find( "date" ) != std::string::npos )
587  {
589  }
590  if( line.find( "end_header" ) != std::string::npos )
591  {
592  return MB_SUCCESS;
593  }
594  }
595 
596  // otherwise we never found the end_header keyword
597  return MB_FAILURE;
598 }
599 
600 /*
601  * given the string sidedata, get the id number, senses and names of the sides
602  */
603 ReadRTT::side ReadRTT::get_side_data( std::string sidedata )
604 {
605  side new_side;
606  std::vector< std::string > tokens;
607  tokens = ReadRTT::split_string( sidedata, ' ' );
608 
609  // set the side id
610  if( tokens.size() != 2 )
611  {
612  MB_SET_ERR_RET_VAL( "Error, too many tokens found from side_data", new_side );
613  }
614  // create the new side
615  new_side.id = std::atoi( tokens[0].c_str() );
616 
617  std::vector< std::string > cell_names = ReadRTT::split_string( tokens[1], '/' );
618  // get the boundary
619  boundary new_bnd = ReadRTT::split_name( cell_names[0] );
620  // set the surface sense and name
621  new_side.senses[0] = new_bnd.sense;
622  new_side.names[0] = new_bnd.name;
623  //
624  if( cell_names.size() > 1 )
625  {
626  boundary bnd = ReadRTT::split_name( cell_names[1] );
627  new_side.senses[1] = bnd.sense;
628  new_side.names[1] = bnd.name;
629  }
630  else
631  {
632  new_side.senses[1] = 0;
633  new_side.names[1] = "\0";
634  }
635 
636  return new_side;
637 }
638 
639 /*
640  * given the string celldata, get the id number and name of each cell
641  */
642 ReadRTT::cell ReadRTT::get_cell_data( std::string celldata )
643 {
644  cell new_cell;
645  std::vector< std::string > tokens;
646  tokens = ReadRTT::split_string( celldata, ' ' );
647 
648  // set the side id
649  if( tokens.size() != 2 )
650  {
651  MB_SET_ERR_RET_VAL( "Error, too many tokens found from cell_data", new_cell );
652  }
653  // create the new side
654  new_cell.id = std::atoi( tokens[0].c_str() );
655  new_cell.name = tokens[1];
656 
657  return new_cell;
658 }
659 
660 /*
661  * given the string nodedata, get the id number and coordinates of the node
662  */
663 ReadRTT::node ReadRTT::get_node_data( std::string nodedata )
664 {
665  node new_node;
666  std::vector< std::string > tokens;
667  tokens = ReadRTT::split_string( nodedata, ' ' );
668 
669  // set the side id
670  if( tokens.size() != 5 )
671  {
672  MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_node_data", new_node );
673  }
674  new_node.id = std::atoi( tokens[0].c_str() );
675  new_node.x = std::atof( tokens[1].c_str() );
676  new_node.y = std::atof( tokens[2].c_str() );
677  new_node.z = std::atof( tokens[3].c_str() );
678  return new_node;
679 }
680 
681 /*
682  * given the string nodedata, get the id number, connectivity and sense data
683  */
684 ReadRTT::facet ReadRTT::get_facet_data( std::string facetdata )
685 {
686  facet new_facet;
687  std::vector< std::string > tokens;
688  tokens = ReadRTT::split_string( facetdata, ' ' );
689 
690  // set the side id
691  if( tokens.size() != 7 )
692  {
693  MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_facet_data", new_facet );
694  }
695 
696  new_facet.id = std::atoi( tokens[0].c_str() );
697  // branch on the rtt version number
698  if( header_data.version == "v1.0.0" )
699  {
700  new_facet.connectivity[0] = std::atoi( tokens[1].c_str() );
701  new_facet.connectivity[1] = std::atoi( tokens[2].c_str() );
702  new_facet.connectivity[2] = std::atoi( tokens[3].c_str() );
703  new_facet.side_id = std::atoi( tokens[4].c_str() );
704  new_facet.surface_number = std::atoi( tokens[5].c_str() );
705  }
706  else if( header_data.version == "v1.0.1" )
707  {
708  new_facet.connectivity[0] = std::atoi( tokens[2].c_str() );
709  new_facet.connectivity[1] = std::atoi( tokens[3].c_str() );
710  new_facet.connectivity[2] = std::atoi( tokens[4].c_str() );
711  new_facet.side_id = std::atoi( tokens[5].c_str() );
712  new_facet.surface_number = std::atoi( tokens[6].c_str() );
713  }
714  else
715  {
716  MB_SET_ERR_RET_VAL( "Error, version number not understood", new_facet );
717  }
718 
719  return new_facet;
720 }
721 
722 /*
723  * given the string tetdata, get the id number, connectivity and mat num of the tet
724  */
725 ReadRTT::tet ReadRTT::get_tet_data( std::string tetdata )
726 {
727  tet new_tet;
728  std::vector< std::string > tokens;
729  tokens = ReadRTT::split_string( tetdata, ' ' );
730 
731  // set the side id
732  if( tokens.size() != 7 )
733  {
734  MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_tet_data", new_tet );
735  }
736  new_tet.id = std::atoi( tokens[0].c_str() );
737  // branch on the version number
738  if( header_data.version == "v1.0.0" )
739  {
740  new_tet.connectivity[0] = std::atoi( tokens[1].c_str() );
741  new_tet.connectivity[1] = std::atoi( tokens[2].c_str() );
742  new_tet.connectivity[2] = std::atoi( tokens[3].c_str() );
743  new_tet.connectivity[3] = std::atoi( tokens[4].c_str() );
744  new_tet.material_number = std::atoi( tokens[5].c_str() );
745  }
746  else if( header_data.version == "v1.0.1" )
747  {
748  new_tet.connectivity[0] = std::atoi( tokens[2].c_str() );
749  new_tet.connectivity[1] = std::atoi( tokens[3].c_str() );
750  new_tet.connectivity[2] = std::atoi( tokens[4].c_str() );
751  new_tet.connectivity[3] = std::atoi( tokens[5].c_str() );
752  new_tet.material_number = std::atoi( tokens[6].c_str() );
753  }
754  else
755  {
756  MB_SET_ERR_RET_VAL( "Error, version number not supported", new_tet );
757  }
758 
759  return new_tet;
760 }
761 
762 /*
763  * splits string into sense and name, to later facilitate the building
764  * of sense data, strips off the tailing @ if it exists
765  */
766 ReadRTT::boundary ReadRTT::split_name( std::string atilla_cellname )
767 {
768  boundary new_boundary;
769  // default initialisation
770  new_boundary.sense = 0;
771  new_boundary.name = "\0";
772  // +ve sense
773  if( atilla_cellname.find( "+" ) != std::string::npos )
774  {
775  new_boundary.sense = 1;
776  // look for the @# we do not want it
777  std::size_t found = atilla_cellname.find( "@" );
778  if( found != std::string::npos )
779  new_boundary.name = atilla_cellname.substr( 3, found );
780  else
781  new_boundary.name = atilla_cellname.substr( 3, atilla_cellname.length() );
782  }
783  else if( atilla_cellname.find( "-" ) != std::string::npos )
784  {
785  // negative sense
786  new_boundary.sense = -1;
787  new_boundary.name = atilla_cellname.substr( 3, atilla_cellname.length() );
788  }
789  return new_boundary;
790 }
791 
792 /*
793  * splits a string in a vector of strings split by spaces
794  */
795 std::vector< std::string > ReadRTT::split_string( std::string string_to_split, char split_char )
796 {
797  std::istringstream ss( string_to_split );
798  std::vector< std::string > tokens;
799  while( !ss.eof() )
800  {
801  std::string x; // here's a nice, empty string
802  std::getline( ss, x, split_char ); // try to read the next field into it
803  tokens.push_back( x );
804  }
805 
806  // remove empty tokens
807  std::vector< std::string >::iterator it;
808  for( it = tokens.begin(); it != tokens.end(); )
809  {
810  std::string string = *it;
811  if( string.compare( "\0" ) == 0 )
812  it = tokens.erase( it );
813  else
814  ++it;
815  }
816  return tokens;
817 }
818 
819 /*
820  * Generate the parent-child links bwetween the cell and surface meshsets
821  */
823  std::vector< EntityHandle > entity_map[4],
824  std::vector< side > side_data,
825  std::vector< cell > cell_data )
826 {
827  ErrorCode rval; // return value
828  // loop over the number of surfaces
829  for( int i = 0; i < num_ents[2]; i++ )
830  {
831  // get the surface handle
832  EntityHandle surf_handle = entity_map[2][i];
833  // there are volumes that share this face
834  for( unsigned int shared = 0; shared <= 1; shared++ )
835  {
836  std::string parent_name = side_data[i].names[shared];
837  // find the @ sign
838  unsigned pos = parent_name.find( "@" );
839  parent_name = parent_name.substr( 0, pos );
840 
841  // loop over tets looking for matching name
842  for( int j = 0; j < num_ents[3]; j++ )
843  {
844  // if match found
845  if( cell_data[j].name.compare( parent_name ) == 0 )
846  {
847  EntityHandle cell_handle = entity_map[3][j];
848  // parent
849  rval = MBI->add_parent_child( cell_handle, surf_handle );
850  if( rval != MB_SUCCESS )
851  {
852  std::cerr << "Failed to add parent child relationship" << std::endl;
853  }
854  }
855  }
856  }
857  }
858  return;
859 }
860 
861 /*
862  * sets the sense of the surfaces wrt to volumes using geom topo tool
863  */
864 void ReadRTT::set_surface_senses( int num_ents[4],
865  std::vector< EntityHandle > entity_map[4],
866  std::vector< side > side_data,
867  std::vector< cell > cell_data )
868 {
869 
870  ErrorCode rval; // return value
871  // loop over the number of surfaces
872  for( int i = 0; i < num_ents[2]; i++ )
873  {
874  EntityHandle surf_handle = entity_map[2][i];
875  // there are 2 volumes that share this face
876  for( unsigned int shared = 0; shared <= 1; shared++ )
877  {
878  std::string parent_name = side_data[i].names[shared];
879  unsigned pos = parent_name.find( "@" );
880  parent_name = parent_name.substr( 0, pos );
881  // loop over tets looking for matching name
882  for( int j = 0; j < num_ents[3]; j++ )
883  {
884  // if match found
885  if( cell_data[j].name.compare( parent_name ) == 0 )
886  {
887  EntityHandle cell_handle = entity_map[3][j];
888  // in rtt mesh +represents the inside and -represents outside
889  // in moab reverse is outside and forward is inside
890  if( side_data[i].senses[shared] == 1 )
891  rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_FORWARD );
892  else if( side_data[i].senses[shared] == -1 )
893  rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_REVERSE );
894  else
895  rval = myGeomTool->set_sense( surf_handle, 0, SENSE_REVERSE );
896 
897  if( rval != MB_SUCCESS )
898  {
899  std::cerr << "Failed to set sense appropriately" << std::endl;
900  }
901  }
902  }
903  }
904  }
905  return;
906 }
907 
908 /*
909  * Add all entities that are to be part of the graveyard
910  */
911 ErrorCode ReadRTT::setup_group_data( std::vector< EntityHandle > entity_map[4] )
912 {
913  ErrorCode rval; // error codes
914  EntityHandle handle;
915  handle = create_group( "graveyard_comp", 1 );
916 
917  // add any volume to group graveyard, it is ignored by dag
918  EntityHandle vol_handle = entity_map[3][0];
919  rval = MBI->add_entities( handle, &vol_handle, 1 );
920  return rval;
921 }
922 
923 /*
924  * create a new group of with the name group name and id
925  */
926 EntityHandle ReadRTT::create_group( std::string group_name, int id )
927 {
928  ErrorCode rval;
929  // category tags
930  const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
931 
932  EntityHandle handle;
933  rval = MBI->create_meshset( MESHSET_SET, handle );
934  if( MB_SUCCESS != rval ) return rval;
935 
936  rval = MBI->tag_set_data( name_tag, &handle, 1, group_name.c_str() );
937  if( MB_SUCCESS != rval ) return MB_FAILURE;
938 
939  rval = MBI->tag_set_data( id_tag, &handle, 1, &id );
940  if( MB_SUCCESS != rval ) return MB_FAILURE;
941 
942  rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[4] );
943  if( MB_SUCCESS != rval ) return MB_FAILURE;
944 
945  return handle;
946 }
947 
948 } // namespace moab