Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ExoIIUtil.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 Corporation, 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 #include "ExoIIUtil.hpp" 17 #include "Internals.hpp" 18 #include "moab/Interface.hpp" 19 #include "moab/CN.hpp" 20 #include <cstring> 21  22 namespace moab 23 { 24  25 // 26 // definitions of ExoII-related static arrays 27 // 28  29 const EntityType ExoIIUtil::ExoIIElementMBEntity[] = { 30  MBVERTEX, // SPHERE, 31  MBEDGE, // SPRING, 32  MBEDGE, // BAR = 0, 33  MBEDGE, // BAR2, 34  MBEDGE, // BAR3, 35  MBEDGE, // BEAM, 36  MBEDGE, // BEAM2, 37  MBEDGE, // BEAM3, 38  MBEDGE, // TRUSS, 39  MBEDGE, // TRUSS2, 40  MBEDGE, // TRUSS3, 41  MBTRI, // TRI, 42  MBTRI, // TRI3, 43  MBTRI, // SHELL3, 44  MBTRI, // TRI6, 45  MBTRI, // TRI7, 46  MBQUAD, // QUAD, 47  MBQUAD, // QUAD4, 48  MBQUAD, // QUAD5, 49  MBQUAD, // QUAD8, 50  MBQUAD, // QUAD9, 51  MBQUAD, // SHELL, 52  MBQUAD, // SHELL4, 53  MBQUAD, // SHELL5, 54  MBQUAD, // SHELL8, 55  MBQUAD, // SHELL9, 56  MBTET, // TETRA, 57  MBTET, // TETRA4, 58  MBTET, // TET4 59  MBTET, // TETRA8, 60  MBTET, // TETRA10, 61  MBTET, // TETRA14, 62  MBPYRAMID, // PYRAMID, 63  MBPYRAMID, // PYRAMID5, 64  MBPYRAMID, // PYRAMID10, 65  MBPYRAMID, // PYRAMID13, 66  MBPYRAMID, // PYRAMID18, 67  MBPRISM, // WEDGE, 68  MBKNIFE, // KNIFE, 69  MBHEX, // HEX, 70  MBHEX, // HEX8, 71  MBHEX, // HEX9, 72  MBHEX, // HEX20, 73  MBHEX, // HEX27, 74  MBHEX, // HEXSHELL, 75  MBPOLYGON, // POLYGON 76  MBPOLYHEDRON, // POLYHEDRON 77  MBMAXTYPE // UNKNOWN 78 }; 79  80 const char* ExoIIUtil::ElementTypeNames[] = { "SPHERE", // 0 81  "SPRING", // 1 82  "BAR", // 2 83  "BAR2", // 3 84  "BAR3", // 4 85  "BEAM", // 5 86  "BEAM2", // 6 87  "BEAM3", // 7 88  "TRUSS", // 8 89  "TRUSS2", // 9 90  "TRUSS3", // 10 91  "TRI", // 11 92  "TRI3", // 12 93  "SHELL3", // 13 really the same as TRI3; for sure in 3d? 94  "TRI6", "TRI7", "QUAD", "QUAD4", "QUAD5", "QUAD8", 95  "QUAD9", "SHELL", "SHELL4", "SHELL5", "SHELL8", "SHELL9", 96  "TETRA", "TETRA4", "TET4", "TETRA8", "TETRA10", "TETRA14", 97  "PYRAMID", "PYRAMID5", "PYRAMID10", "PYRAMID13", "PYRAMID18", "WEDGE", 98  "KNIFE", "HEX", "HEX8", "HEX9", "HEX20", "HEX27", 99  "HEXSHELL", 100  "nsided", // polygons, described differently 101  "NFACED", // polyhedra, described in faconn%d attributes 102  "UNKNOWN" }; 103  104 const int ExoIIUtil::VerticesPerElement[] = { 105  1, // SPHERE 106  1, // SPRING 107  2, 2, 108  3, // BAR 109  2, 2, 110  3, // BEAM 111  2, 2, 112  3, // TRUSS 113  3, // TRI 114  3, // TRI3 115  3, // SHELL3 this is new 116  6, 117  7, // TRI 118  4, 4, 5, 8, 119  9, // QUAD 120  4, 4, 5, 8, 121  9, // SHELL 122  4, 4, 123  4, // TET4 124  8, 10, 125  14, // TETRA 126  5, 5, 10, 13, 127  18, // PYRAMID 128  6, // WEDGE 129  7, // KNIFE 130  8, 8, 9, 20, 131  27, // HEX 132  12, // HEXSHELL 133  0, // POLYGON 134  0, // POLYHEDRON 135  0 // UNKNOWN 136 }; 137  138 const int ExoIIUtil::HasMidNodes[][4] = { 139  { 0, 0, 0, 0 }, // SPHERE - no mid nodes 140  { 0, 0, 0, 0 }, // SPRING - no mid nodes 141  { 0, 0, 0, 0 }, // BAR - no mid nodes, same as BAR2 142  { 0, 0, 0, 0 }, // BAR2 - no mid nodes 143  { 0, 1, 0, 0 }, // BAR3 - mid nodes on edges 144  { 0, 0, 0, 0 }, // BEAM - no mid nodes 145  { 0, 0, 0, 0 }, // BEAM2 - no mid nodes 146  { 0, 1, 0, 0 }, // BEAM3 - mid nodes on edges 147  { 0, 0, 0, 0 }, // TRUSS - no mid nodes 148  { 0, 0, 0, 0 }, // TRUSS2 - no mid nodes 149  { 0, 1, 0, 0 }, // TRUSS3 - mid nodes on edges 150  { 0, 0, 0, 0 }, // TRI - no mid nodes 151  { 0, 0, 0, 0 }, // TRI3 - no mid nodes 152  { 0, 0, 0, 0 }, // SHELL3 - no mid nodes 153  { 0, 1, 0, 0 }, // TRI6 - mid nodes on edges 154  { 0, 1, 1, 0 }, // TRI7 - mid nodes on edges and faces 155  { 0, 0, 0, 0 }, // QUAD - no mid nodes 156  { 0, 0, 0, 0 }, // QUAD4 - no mid nodes 157  { 0, 0, 1, 0 }, // QUAD5 - mid node on faces 158  { 0, 1, 0, 0 }, // QUAD8 - mid nodes on edges 159  { 0, 1, 1, 0 }, // QUAD9 - mid nodes on edges and faces 160  { 0, 0, 0, 0 }, // SHELL - no mid nodes 161  { 0, 0, 0, 0 }, // SHELL4 - no mid nodes 162  { 0, 0, 1, 0 }, // SHELL5 - mid node on faces 163  { 0, 1, 0, 0 }, // SHELL8 - mid nodes on edges 164  { 0, 1, 1, 0 }, // SHELL9 - mid nodes on edges and faces 165  { 0, 0, 0, 0 }, // TETRA - no mid nodes 166  { 0, 0, 0, 0 }, // TETRA4 - no mid nodes 167  { 0, 0, 0, 0 }, // TET4 - no mid nodes 168  { 0, 0, 1, 0 }, // TETRA8 - mid nodes on faces 169  { 0, 1, 0, 0 }, // TETRA10 - mid nodes on edges 170  { 0, 1, 1, 0 }, // TETRA14 - mid nodes on edges and faces 171  { 0, 0, 0, 0 }, // PYRAMID - no mid nodes 172  { 0, 0, 0, 0 }, // PYRAMID5 - no mid nodes 173  { 0, 0, 1, 0 }, // PYRAMID10 - *** TODO - not sure if this is right... 174  { 0, 1, 0, 0 }, // PYRAMID13 - *** TODO - not sure if this is right... 175  { 0, 1, 1, 0 }, // PYRAMID18 - *** TODO - not sure if this is right... 176  { 0, 0, 0, 0 }, // WEDGE - no mid nodes 177  { 0, 0, 0, 0 }, // KNIFE - no mid nodes 178  { 0, 0, 0, 0 }, // HEX - no mid nodes 179  { 0, 0, 0, 0 }, // HEX8 - no mid nodes 180  { 0, 0, 0, 1 }, // HEX9 - mid node on element 181  { 0, 1, 0, 0 }, // HEX20 - mid nodes on edges 182  { 0, 1, 1, 1 }, // HEX27 - mid node on edges, faces and element 183  { 0, 0, 0, 0 }, // HEXSHELL - *** TODO - not sure if this is right... 184  { 0, 0, 0, 0 }, // POLYGON 185  { 0, 0, 0, 0 }, // POLYHEDRON 186  { 0, 0, 0, 0 } // UNKNOWN - no mid nodes 187 }; 188  189 const int ExoIIUtil::ElementGeometricDimension[] = { 190  3, // SPHERE 191  3, // SPRING 192  2, 2, 193  2, // BAR 194  3, 3, 195  3, // BEAM 196  3, 3, 197  3, // TRUSS 198  3, 3, 3, 3, 199  3, // TRI 200  2, 2, 2, 2, 201  2, // QUAD 202  3, 3, 3, 3, 203  3, // SHELL 204  3, 3, 3, 3, 205  3, // TETRA 206  3, 3, 3, 3, 3, 207  3, // PYRAMID 208  3, // WEDGE 209  3, // KNIFE 210  3, 3, 3, 3, 211  3, // HEX 212  3, // HEXSHELL 213  2, // POLYGON 214  3, // POLYHEDRON 215  0 // UNKNOWN 216 }; 217  218 ExoIIElementType ExoIIUtil::static_element_name_to_type( const char* name ) 219 { 220  int i; 221  for( i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 222  if( strcmp( ElementTypeNames[i], name ) == 0 ) return (ExoIIElementType)i; 223  224  return EXOII_MAX_ELEM_TYPE; 225 } 226  227 ExoIIElementType ExoIIUtil::static_get_element_type( Interface* mdbImpl, 228  const EntityHandle entity, 229  const Tag mid_nodes_tag, 230  const Tag geom_dimension_tag, 231  const EntityType indiv_entity_type ) 232 { 233  // branch based on what kind of entity we're looking at 234  EntityType handle_type = mdbImpl->type_from_handle( entity ); 235  236  if( handle_type == MBENTITYSET ) 237  { 238  239  // it's a meshset - assume it's a block (check this?) and work off the midnodes tag 240  241  // get the element type of the block; first, get the hasMidNodes tag, then convert to an exo 242  // element type 243  int has_mid_nodes[4]; 244  int dimension = -1; 245  if( mdbImpl->tag_get_data( mid_nodes_tag, &entity, 1, has_mid_nodes ) != MB_SUCCESS ) 246  { 247  // no mid nodes tag - look for indiv entity type, and if it was input, output the 248  // default number of vertices 249  if( MBMAXTYPE != indiv_entity_type ) 250  { 251  // get dimension 252  if( indiv_entity_type == MBQUAD || indiv_entity_type == MBTRI ) 253  dimension = 3; // want to ouput shells by default 254  else if( indiv_entity_type == MBEDGE ) 255  dimension = 2; 256  else 257  dimension = CN::Dimension( indiv_entity_type ); 258  259  return get_element_type_from_num_verts( CN::VerticesPerEntity( indiv_entity_type ), indiv_entity_type, 260  dimension ); 261  } 262  else 263  return EXOII_MAX_ELEM_TYPE; 264  } 265  else 266  { 267  // block meshset had midnodes tag - look for geometric dimension one too 268  mdbImpl->tag_get_data( geom_dimension_tag, &entity, 1, &dimension ); 269  } 270  271  for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 272  { 273  if( ( indiv_entity_type == MBMAXTYPE || indiv_entity_type == ExoIIElementMBEntity[i] ) && 274  has_mid_nodes[0] == HasMidNodes[i][0] && has_mid_nodes[1] == HasMidNodes[i][1] && 275  has_mid_nodes[2] == HasMidNodes[i][2] && has_mid_nodes[3] == HasMidNodes[i][3] && 276  ( -1 == dimension || ElementGeometricDimension[i] == dimension ) ) 277  return (ExoIIElementType)i; 278  } 279  280  return EXOII_MAX_ELEM_TYPE; 281  } 282  283  else if( handle_type == MBVERTEX ) 284  // only have one type of entity for vertices... 285  return EXOII_SPHERE; 286  287  else 288  { 289  std::vector< EntityHandle > tmp( 31 ); 290  291  mdbImpl->get_connectivity( &entity, 1, tmp, true ); 292  return get_element_type_from_num_verts( tmp.size(), indiv_entity_type ); 293  // it's a regular entity - look for a connectivity tag 294  } 295  296  // if we've gotten here, we failed 297  // return EXOII_MAX_ELEM_TYPE; 298 } 299  300 ExoIIElementType ExoIIUtil::get_element_type_from_num_verts( const int num_verts, 301  const EntityType entity_type, 302  const int dimension ) 303 { 304  if( MBPOLYGON == entity_type && 2 == dimension ) return EXOII_POLYGON; 305  if( MBPOLYHEDRON == entity_type && 3 == dimension ) return EXOII_POLYHEDRON; 306  for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 307  { 308  if( ( entity_type == MBMAXTYPE || entity_type == ExoIIElementMBEntity[i] ) && 309  VerticesPerElement[i] == num_verts && ElementGeometricDimension[i] >= dimension ) 310  return (ExoIIElementType)i; 311  } 312  313  return EXOII_MAX_ELEM_TYPE; 314 } 315  316 } // namespace moab