Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
moab::ReadNASTRAN Class Reference

#include <ReadNASTRAN.hpp>

+ Inheritance diagram for moab::ReadNASTRAN:
+ Collaboration diagram for moab::ReadNASTRAN:

Public Member Functions

ErrorCode load_file (const char *file_name, const EntityHandle *file_set, const FileOptions &opts, const SubsetList *subset_list=0, const Tag *file_id_tag=0)
 Load mesh from a file. More...
 
 ReadNASTRAN (Interface *impl=NULL)
 
virtual ~ReadNASTRAN ()
 
ErrorCode read_tag_values (const char *file_name, const char *tag_name, const FileOptions &opts, std::vector< int > &tag_values_out, const SubsetList *subset_list=0)
 Read tag values from a file. More...
 
- Public Member Functions inherited from moab::ReaderIface
virtual ~ReaderIface ()
 

Static Public Member Functions

static ReaderIfacefactory (Interface *)
 

Private Types

enum  line_format { SMALL_FIELD , LARGE_FIELD , FREE_FIELD }
 

Private Member Functions

ErrorCode determine_line_format (const std::string &line, line_format &format)
 
ErrorCode tokenize_line (const std::string &line, const line_format format, std::vector< std::string > &tokens)
 
ErrorCode determine_entity_type (const std::string &token, EntityType &type)
 
ErrorCode get_real (const std::string &, double &real)
 
ErrorCode read_node (const std::vector< std::string > &tokens, const bool debug, double *coord_arrays[3], int &node_id)
 
ErrorCode read_element (const std::vector< std::string > &tokens, std::vector< Range > &materials, const EntityType element_type, const bool debug)
 
ErrorCode create_materials (const std::vector< Range > &materials)
 
ErrorCode assign_ids (const Tag *file_id_tag)
 

Private Attributes

ReadUtilIfacereadMeshIface
 
InterfaceMBI
 
RangeMap< int, EntityHandlenodeIdMap
 
RangeMap< int, EntityHandleelemIdMap
 

Detailed Description

Definition at line 49 of file ReadNASTRAN.hpp.

Member Enumeration Documentation

◆ line_format

Enumerator
SMALL_FIELD 
LARGE_FIELD 
FREE_FIELD 

Definition at line 83 of file ReadNASTRAN.hpp.

84  {
88  };

Constructor & Destructor Documentation

◆ ReadNASTRAN()

moab::ReadNASTRAN::ReadNASTRAN ( Interface impl = NULL)

Definition at line 44 of file ReadNASTRAN.cpp.

44  : MBI( impl )
45 {
46  assert( NULL != impl );
48  assert( NULL != readMeshIface );
49 }

References MBI, moab::Interface::query_interface(), and readMeshIface.

Referenced by factory().

◆ ~ReadNASTRAN()

moab::ReadNASTRAN::~ReadNASTRAN ( )
virtual

Definition at line 52 of file ReadNASTRAN.cpp.

53 {
54  if( readMeshIface )
55  {
57  readMeshIface = 0;
58  }
59 }

References MBI, readMeshIface, and moab::Interface::release_interface().

Member Function Documentation

◆ assign_ids()

ErrorCode moab::ReadNASTRAN::assign_ids ( const Tag file_id_tag)
private

Definition at line 460 of file ReadNASTRAN.cpp.

461 {
462  // Create tag
463  ErrorCode result;
464  Tag id_tag = MBI->globalId_tag();
465 
467  for( int t = 0; t < 2; ++t )
468  {
470  for( i = fileIdMap.begin(); i != fileIdMap.end(); ++i )
471  {
472  Range range( i->value, i->value + i->count - 1 );
473 
474  result = readMeshIface->assign_ids( id_tag, range, i->begin );
475  if( MB_SUCCESS != result ) return result;
476 
477  if( file_id_tag && *file_id_tag != id_tag )
478  {
479  result = readMeshIface->assign_ids( *file_id_tag, range, i->begin );
480  if( MB_SUCCESS != result ) return result;
481  }
482  }
483  }
484 
485  return MB_SUCCESS;
486 }

References moab::ReadUtilIface::assign_ids(), moab::RangeMap< KeyType, ValType, NullVal >::begin(), elemIdMap, moab::RangeMap< KeyType, ValType, NullVal >::end(), ErrorCode, moab::Interface::globalId_tag(), MB_SUCCESS, MBI, nodeIdMap, readMeshIface, and t.

Referenced by load_file().

◆ create_materials()

ErrorCode moab::ReadNASTRAN::create_materials ( const std::vector< Range > &  materials)
private

Definition at line 428 of file ReadNASTRAN.cpp.

429 {
430  ErrorCode result;
431  Tag material_tag;
432  int negone = -1;
434  &negone );
435  if( MB_SUCCESS != result ) return result;
436 
437  for( size_t i = 0; i < materials.size(); ++i )
438  {
439  if( materials[i].empty() ) continue;
440 
441  // Merge with existing or create new? Original code effectively
442  // created new by only merging with existing in current file set,
443  // so do the same here. - j.kraftcheck
444 
445  EntityHandle handle;
446  result = MBI->create_meshset( MESHSET_SET, handle );
447  if( MB_SUCCESS != result ) return result;
448 
449  result = MBI->add_entities( handle, materials[i] );
450  if( MB_SUCCESS != result ) return result;
451 
452  int id = i;
453  result = MBI->tag_set_data( material_tag, &handle, 1, &id );
454  if( MB_SUCCESS != result ) return result;
455  }
456 
457  return MB_SUCCESS;
458 }

References moab::Interface::add_entities(), moab::Interface::create_meshset(), ErrorCode, MATERIAL_SET_TAG_NAME, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBI, MESHSET_SET, moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by load_file().

◆ determine_entity_type()

ErrorCode moab::ReadNASTRAN::determine_entity_type ( const std::string &  token,
EntityType &  type 
)
private

Definition at line 252 of file ReadNASTRAN.cpp.

253 {
254  if( 0 == first_token.compare( "GRID " ) )
255  type = MBVERTEX;
256  else if( 0 == first_token.compare( "CTETRA " ) )
257  type = MBTET;
258  else if( 0 == first_token.compare( "CPENTA " ) )
259  type = MBPRISM;
260  else if( 0 == first_token.compare( "CHEXA " ) )
261  type = MBHEX;
262  else
263  return MB_NOT_IMPLEMENTED;
264 
265  return MB_SUCCESS;
266 }

References MB_NOT_IMPLEMENTED, MB_SUCCESS, MBHEX, MBPRISM, MBTET, and MBVERTEX.

Referenced by load_file().

◆ determine_line_format()

ErrorCode moab::ReadNASTRAN::determine_line_format ( const std::string &  line,
line_format format 
)
private

Definition at line 198 of file ReadNASTRAN.cpp.

199 {
200  std::string::size_type found_asterisk = line.find( "*" );
201  if( std::string::npos != found_asterisk )
202  {
203  format = LARGE_FIELD;
204  return MB_SUCCESS;
205  }
206  else
207  {
208  std::string::size_type found_comma = line.find( "," );
209  if( std::string::npos != found_comma )
210  {
211  format = FREE_FIELD;
212  return MB_SUCCESS;
213  }
214  else
215  {
216  format = SMALL_FIELD;
217  return MB_SUCCESS;
218  }
219  }
220 }

References FREE_FIELD, LARGE_FIELD, MB_SUCCESS, and SMALL_FIELD.

Referenced by load_file().

◆ factory()

ReaderIface * moab::ReadNASTRAN::factory ( Interface iface)
static

Definition at line 38 of file ReadNASTRAN.cpp.

39 {
40  return new ReadNASTRAN( iface );
41 }

References iface, and ReadNASTRAN().

Referenced by moab::ReaderWriterSet::ReaderWriterSet().

◆ get_real()

ErrorCode moab::ReadNASTRAN::get_real ( const std::string &  token,
double &  real 
)
private

Definition at line 283 of file ReadNASTRAN.cpp.

284 {
285  std::string significand = token;
286  std::string exponent = "0";
287 
288  // Cut off the first digit because a "-" could be here indicating a negative
289  // number. Instead we are looking for a negative exponent.
290  std::string back_token = token.substr( 1 );
291 
292  // A minus that is not the first digit is always a negative exponent
293  std::string::size_type found_minus = back_token.find( "-" );
294  if( std::string::npos != found_minus )
295  {
296  // separate the significand from the exponent at the "-"
297  exponent = token.substr( found_minus + 1 );
298  significand = token.substr( 0, found_minus + 1 );
299 
300  // If the significand has an "E", remove it
301  if( std::string::npos != significand.find( "E" ) )
302  // Assume the "E" is at the end of the significand.
303  significand = significand.substr( 1, significand.size() - 2 );
304 
305  // If a minus does not exist past the 1st digit, but an "E" or "+" does, then
306  // it is a positive exponent. First look for an "E",
307  }
308  else
309  {
310  std::string::size_type found_E = token.find( "E" );
311  if( std::string::npos != found_E )
312  {
313  significand = token.substr( 0, found_E - 1 );
314  exponent = token.substr( found_E + 1 );
315  // If there is a "+" on the exponent, cut it off
316  std::size_t found_plus = exponent.find( "+" );
317  if( std::string::npos != found_plus )
318  {
319  exponent = exponent.substr( found_plus + 1 );
320  }
321  }
322  else
323  {
324  // If there is a "+" on the exponent, cut it off
325  std::size_t found_plus = token.find( "+" );
326  if( std::string::npos != found_plus )
327  {
328  significand = token.substr( 0, found_plus - 1 );
329  exponent = token.substr( found_plus + 1 );
330  }
331  }
332  }
333 
334  // Now assemble the real number
335  double signi = atof( significand.c_str() );
336  double expon = atof( exponent.c_str() );
337 
338  if( HUGE_VAL == signi || HUGE_VAL == expon ) return MB_FAILURE;
339 
340  real = signi * pow( 10, expon );
341 
342  return MB_SUCCESS;
343 }

References MB_SUCCESS.

Referenced by read_node().

◆ load_file()

ErrorCode moab::ReadNASTRAN::load_file ( const char *  file_name,
const EntityHandle file_set,
const FileOptions opts,
const SubsetList subset_list = 0,
const Tag file_id_tag = 0 
)
virtual

Load mesh from a file.

Method all readers must provide to import a mesh.

Parameters
file_nameThe file to read.
file_setOptional pointer to entity set representing file. If this is not NULL, reader may optionally tag the pointed-to set with format-specific meta-data.
subset_listAn optional struct pointer specifying the tags identifying entity sets to be read.
file_id_tagIf specified, reader should store for each entity it reads, a unique integer ID for this tag.
Author
Jason Kraftcheck

Implements moab::ReaderIface.

Definition at line 71 of file ReadNASTRAN.cpp.

76 {
77  // At this time there is no support for reading a subset of the file
78  if( subset_list )
79  {
80  MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for NASTRAN" );
81  }
82 
83  nodeIdMap.clear();
84  elemIdMap.clear();
85 
86  bool debug = false;
87  if( debug ) std::cout << "begin ReadNASTRAN::load_file" << std::endl;
88  ErrorCode result;
89 
90  // Count the entities of each type in the file. This is used to allocate the node array.
91  int entity_count[MBMAXTYPE];
92  for( int i = 0; i < MBMAXTYPE; i++ )
93  entity_count[i] = 0;
94 
95  /* Determine the line_format of the first line. Assume that the entire file
96  has the same format. */
97  std::string line;
98  std::ifstream file( filename );
99  if( !getline( file, line ) ) return MB_FILE_DOES_NOT_EXIST;
100  line_format format;
101  result = determine_line_format( line, format );
102  if( MB_SUCCESS != result ) return result;
103 
104  /* Count the number of each entity in the file. This allows one to allocate
105  a sequential array of vertex handles. */
106  while( !file.eof() )
107  {
108  // Cut the line into fields as determined by the line format.
109  // Use a vector to allow for an unknown number of tokens (continue lines).
110  // Continue lines are not implemented.
111  std::vector< std::string > tokens;
112  tokens.reserve( 10 ); // assume 10 fields to avoid extra vector resizing
113  result = tokenize_line( line, format, tokens );
114  if( MB_SUCCESS != result ) return result;
115 
116  // Process the tokens of the line. The first token describes the entity type.
117  EntityType type;
118  result = determine_entity_type( ( tokens.empty() ) ? "" : tokens.front(), type );
119  if( MB_SUCCESS != result ) return result;
120  entity_count[type]++;
121  getline( file, line );
122  }
123 
124  if( debug )
125  {
126  for( int i = 0; i < MBMAXTYPE; i++ )
127  {
128  std::cout << "entity_count[" << i << "]=" << entity_count[i] << std::endl;
129  }
130  }
131 
132  // Keep list of material sets
133  std::vector< Range > materials;
134 
135  // Now that the number of vertices is known, create the vertices.
136  EntityHandle start_vert = 0;
137  std::vector< double* > coord_arrays( 3 );
138  result = readMeshIface->get_node_coords( 3, entity_count[0], MB_START_ID, start_vert, coord_arrays );
139  if( MB_SUCCESS != result ) return result;
140  if( 0 == start_vert ) return MB_FAILURE; // check for NULL
141  int id, vert_index = 0;
142  if( debug ) std::cout << "allocated coord arrays" << std::endl;
143 
144  // Read the file again to create the entities.
145  file.clear(); // Clear eof state from object
146  file.seekg( 0 ); // Rewind file
147  while( !file.eof() )
148  {
149  getline( file, line );
150 
151  // Cut the line into fields as determined by the line format.
152  // Use a vector to allow for an unknown number of tokens (continue lines).
153  // Continue lines are not implemented.
154  std::vector< std::string > tokens;
155  tokens.reserve( 10 ); // assume 10 fields to avoid extra vector resizing
156  result = tokenize_line( line, format, tokens );
157  if( MB_SUCCESS != result ) return result;
158 
159  // Process the tokens of the line. The first token describes the entity type.
160  EntityType type;
161  result = determine_entity_type( tokens.front(), type );
162  if( MB_SUCCESS != result ) return result;
163 
164  // Create the entity.
165  if( MBVERTEX == type )
166  {
167  double* coords[3] = { coord_arrays[0] + vert_index, coord_arrays[1] + vert_index,
168  coord_arrays[2] + vert_index };
169  result = read_node( tokens, debug, coords, id );
170  if( MB_SUCCESS != result ) return result;
171  if( !nodeIdMap.insert( id, start_vert + vert_index, 1 ).second ) return MB_FAILURE; // Duplicate IDs!
172  ++vert_index;
173  }
174  else
175  {
176  result = read_element( tokens, materials, type, debug );
177  if( MB_SUCCESS != result ) return result;
178  }
179  }
180 
181  result = create_materials( materials );
182  if( MB_SUCCESS != result ) return result;
183 
184  result = assign_ids( file_id_tag );
185  if( MB_SUCCESS != result ) return result;
186 
187  file.close();
188  nodeIdMap.clear();
189  elemIdMap.clear();
190  return MB_SUCCESS;
191 }

References assign_ids(), moab::RangeMap< KeyType, ValType, NullVal >::clear(), create_materials(), moab::debug, determine_entity_type(), determine_line_format(), elemIdMap, ErrorCode, moab::ReadUtilIface::get_node_coords(), moab::RangeMap< KeyType, ValType, NullVal >::insert(), MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, MB_START_ID, MB_SUCCESS, MB_UNSUPPORTED_OPERATION, MBMAXTYPE, MBVERTEX, nodeIdMap, read_element(), read_node(), readMeshIface, and tokenize_line().

◆ read_element()

ErrorCode moab::ReadNASTRAN::read_element ( const std::vector< std::string > &  tokens,
std::vector< Range > &  materials,
const EntityType  element_type,
const bool  debug 
)
private

Definition at line 379 of file ReadNASTRAN.cpp.

383 {
384  // Read the element's id (unique) and material set
385  ErrorCode result;
386  int id = atoi( tokens[1].c_str() );
387  int material = atoi( tokens[2].c_str() );
388 
389  // Resize materials list if necessary. This code is somewhat complicated
390  // so as to avoid copying of Ranges
391  if( material >= (int)materials.size() )
392  {
393  if( (int)materials.capacity() < material )
394  materials.resize( material + 1 );
395  else
396  {
397  std::vector< Range > new_mat( material + 1 );
398  for( size_t i = 0; i < materials.size(); ++i )
399  new_mat[i].swap( materials[i] );
400  materials.swap( new_mat );
401  }
402  }
403 
404  // The size of the connectivity array depends on the element type
405  int n_conn = CN::VerticesPerEntity( element_type );
406  EntityHandle conn_verts[27];
407  assert( n_conn <= (int)( sizeof( conn_verts ) / sizeof( EntityHandle ) ) );
408 
409  // Read the connected node ids from the file
410  for( int i = 0; i < n_conn; i++ )
411  {
412  int n = atoi( tokens[3 + i].c_str() );
413  conn_verts[i] = nodeIdMap.find( n );
414  if( !conn_verts[i] ) // invalid vertex id
415  return MB_FAILURE;
416  }
417 
418  // Create the element and set the global id from the NASTRAN file
419  EntityHandle element;
420  result = MBI->create_element( element_type, conn_verts, n_conn, element );
421  if( MB_SUCCESS != result ) return result;
422  elemIdMap.insert( id, element, 1 );
423 
424  materials[material].insert( element );
425  return MB_SUCCESS;
426 }

References moab::Interface::create_element(), elemIdMap, ErrorCode, moab::RangeMap< KeyType, ValType, NullVal >::find(), moab::RangeMap< KeyType, ValType, NullVal >::insert(), MB_SUCCESS, MBI, nodeIdMap, and moab::CN::VerticesPerEntity().

Referenced by load_file().

◆ read_node()

ErrorCode moab::ReadNASTRAN::read_node ( const std::vector< std::string > &  tokens,
const bool  debug,
double *  coord_arrays[3],
int &  node_id 
)
private

Definition at line 347 of file ReadNASTRAN.cpp.

351 {
352  // Read the node's id (unique)
353  ErrorCode result;
354  id = atoi( tokens[1].c_str() );
355 
356  // Read the node's coordinate system number
357  // "0" or blank refers to the basic coordinate system.
358  int coord_system = atoi( tokens[2].c_str() );
359  if( 0 != coord_system )
360  {
361  std::cerr << "ReadNASTRAN: alternative coordinate systems not implemented" << std::endl;
362  return MB_NOT_IMPLEMENTED;
363  }
364 
365  // Read the coordinates
366  for( unsigned int i = 0; i < 3; i++ )
367  {
368  result = get_real( tokens[i + 3], *coords[i] );
369  if( MB_SUCCESS != result ) return result;
370  if( debug ) std::cout << "read_node: coords[" << i << "]=" << coords[i] << std::endl;
371  }
372 
373  return MB_SUCCESS;
374 }

References moab::debug, ErrorCode, get_real(), MB_NOT_IMPLEMENTED, and MB_SUCCESS.

Referenced by load_file().

◆ read_tag_values()

ErrorCode moab::ReadNASTRAN::read_tag_values ( const char *  file_name,
const char *  tag_name,
const FileOptions opts,
std::vector< int > &  tag_values_out,
const SubsetList subset_list = 0 
)
virtual

Read tag values from a file.

Read the list if all integer tag values from the file for a tag that is a single integer value per entity.

Parameters
file_nameThe file to read.
tag_nameThe tag for which to read values
tag_values_outOutput: The list of tag values.
subset_listAn array of tag name and value sets specifying the subset of the file to read. If multiple tags are specified, the sets that match all tags (intersection) should be read.
subset_list_lengthThe length of the 'subset_list' array.

Implements moab::ReaderIface.

Definition at line 61 of file ReadNASTRAN.cpp.

66 {
67  return MB_NOT_IMPLEMENTED;
68 }

References MB_NOT_IMPLEMENTED.

◆ tokenize_line()

ErrorCode moab::ReadNASTRAN::tokenize_line ( const std::string &  line,
const line_format  format,
std::vector< std::string > &  tokens 
)
private

Definition at line 223 of file ReadNASTRAN.cpp.

226 {
227  size_t line_size = line.size();
228  switch( format )
229  {
230  case SMALL_FIELD: {
231  // Expect 10 fields of 8 characters.
232  // The sample file does not have all 10 fields in each line
233  const int field_length = 8;
234  unsigned int n_tokens = line_size / field_length;
235  for( unsigned int i = 0; i < n_tokens; i++ )
236  {
237  tokens.push_back( line.substr( i * field_length, field_length ) );
238  }
239  break;
240  }
241  case LARGE_FIELD:
242  return MB_NOT_IMPLEMENTED;
243  case FREE_FIELD:
244  return MB_NOT_IMPLEMENTED;
245  default:
246  return MB_FAILURE;
247  }
248 
249  return MB_SUCCESS;
250 }

References FREE_FIELD, LARGE_FIELD, MB_NOT_IMPLEMENTED, MB_SUCCESS, and SMALL_FIELD.

Referenced by load_file().

Member Data Documentation

◆ elemIdMap

RangeMap< int, EntityHandle > moab::ReadNASTRAN::elemIdMap
private

Definition at line 81 of file ReadNASTRAN.hpp.

Referenced by assign_ids(), load_file(), and read_element().

◆ MBI

Interface* moab::ReadNASTRAN::MBI
private

Definition at line 79 of file ReadNASTRAN.hpp.

Referenced by assign_ids(), create_materials(), read_element(), ReadNASTRAN(), and ~ReadNASTRAN().

◆ nodeIdMap

RangeMap< int, EntityHandle > moab::ReadNASTRAN::nodeIdMap
private

Definition at line 81 of file ReadNASTRAN.hpp.

Referenced by assign_ids(), load_file(), and read_element().

◆ readMeshIface

ReadUtilIface* moab::ReadNASTRAN::readMeshIface
private

Definition at line 76 of file ReadNASTRAN.hpp.

Referenced by assign_ids(), load_file(), ReadNASTRAN(), and ~ReadNASTRAN().


The documentation for this class was generated from the following files: