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 Corporation, 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 #include "ExoIIUtil.hpp" 00017 #include "Internals.hpp" 00018 #include "moab/Interface.hpp" 00019 #include "moab/CN.hpp" 00020 #include <cstring> 00021 00022 namespace moab 00023 { 00024 00025 // 00026 // definitions of ExoII-related static arrays 00027 // 00028 00029 const EntityType ExoIIUtil::ExoIIElementMBEntity[] = { 00030 MBVERTEX, // SPHERE, 00031 MBEDGE, // SPRING, 00032 MBEDGE, // BAR = 0, 00033 MBEDGE, // BAR2, 00034 MBEDGE, // BAR3, 00035 MBEDGE, // BEAM, 00036 MBEDGE, // BEAM2, 00037 MBEDGE, // BEAM3, 00038 MBEDGE, // TRUSS, 00039 MBEDGE, // TRUSS2, 00040 MBEDGE, // TRUSS3, 00041 MBTRI, // TRI, 00042 MBTRI, // TRI3, 00043 MBTRI, // SHELL3, 00044 MBTRI, // TRI6, 00045 MBTRI, // TRI7, 00046 MBQUAD, // QUAD, 00047 MBQUAD, // QUAD4, 00048 MBQUAD, // QUAD5, 00049 MBQUAD, // QUAD8, 00050 MBQUAD, // QUAD9, 00051 MBQUAD, // SHELL, 00052 MBQUAD, // SHELL4, 00053 MBQUAD, // SHELL5, 00054 MBQUAD, // SHELL8, 00055 MBQUAD, // SHELL9, 00056 MBTET, // TETRA, 00057 MBTET, // TETRA4, 00058 MBTET, // TET4 00059 MBTET, // TETRA8, 00060 MBTET, // TETRA10, 00061 MBTET, // TETRA14, 00062 MBPYRAMID, // PYRAMID, 00063 MBPYRAMID, // PYRAMID5, 00064 MBPYRAMID, // PYRAMID10, 00065 MBPYRAMID, // PYRAMID13, 00066 MBPYRAMID, // PYRAMID18, 00067 MBPRISM, // WEDGE, 00068 MBKNIFE, // KNIFE, 00069 MBHEX, // HEX, 00070 MBHEX, // HEX8, 00071 MBHEX, // HEX9, 00072 MBHEX, // HEX20, 00073 MBHEX, // HEX27, 00074 MBHEX, // HEXSHELL, 00075 MBPOLYGON, // POLYGON 00076 MBPOLYHEDRON, // POLYHEDRON 00077 MBMAXTYPE // UNKNOWN 00078 }; 00079 00080 const char* ExoIIUtil::ElementTypeNames[] = { "SPHERE", // 0 00081 "SPRING", // 1 00082 "BAR", // 2 00083 "BAR2", // 3 00084 "BAR3", // 4 00085 "BEAM", // 5 00086 "BEAM2", // 6 00087 "BEAM3", // 7 00088 "TRUSS", // 8 00089 "TRUSS2", // 9 00090 "TRUSS3", // 10 00091 "TRI", // 11 00092 "TRI3", // 12 00093 "SHELL3", // 13 really the same as TRI3; for sure in 3d? 00094 "TRI6", "TRI7", "QUAD", "QUAD4", "QUAD5", "QUAD8", 00095 "QUAD9", "SHELL", "SHELL4", "SHELL5", "SHELL8", "SHELL9", 00096 "TETRA", "TETRA4", "TET4", "TETRA8", "TETRA10", "TETRA14", 00097 "PYRAMID", "PYRAMID5", "PYRAMID10", "PYRAMID13", "PYRAMID18", "WEDGE", 00098 "KNIFE", "HEX", "HEX8", "HEX9", "HEX20", "HEX27", 00099 "HEXSHELL", 00100 "nsided", // polygons, described differently 00101 "NFACED", // polyhedra, described in faconn%d attributes 00102 "UNKNOWN" }; 00103 00104 const int ExoIIUtil::VerticesPerElement[] = { 00105 1, // SPHERE 00106 1, // SPRING 00107 2, 2, 00108 3, // BAR 00109 2, 2, 00110 3, // BEAM 00111 2, 2, 00112 3, // TRUSS 00113 3, // TRI 00114 3, // TRI3 00115 3, // SHELL3 this is new 00116 6, 00117 7, // TRI 00118 4, 4, 5, 8, 00119 9, // QUAD 00120 4, 4, 5, 8, 00121 9, // SHELL 00122 4, 4, 00123 4, // TET4 00124 8, 10, 00125 14, // TETRA 00126 5, 5, 10, 13, 00127 18, // PYRAMID 00128 6, // WEDGE 00129 7, // KNIFE 00130 8, 8, 9, 20, 00131 27, // HEX 00132 12, // HEXSHELL 00133 0, // POLYGON 00134 0, // POLYHEDRON 00135 0 // UNKNOWN 00136 }; 00137 00138 const int ExoIIUtil::HasMidNodes[][4] = { 00139 { 0, 0, 0, 0 }, // SPHERE - no mid nodes 00140 { 0, 0, 0, 0 }, // SPRING - no mid nodes 00141 { 0, 0, 0, 0 }, // BAR - no mid nodes, same as BAR2 00142 { 0, 0, 0, 0 }, // BAR2 - no mid nodes 00143 { 0, 1, 0, 0 }, // BAR3 - mid nodes on edges 00144 { 0, 0, 0, 0 }, // BEAM - no mid nodes 00145 { 0, 0, 0, 0 }, // BEAM2 - no mid nodes 00146 { 0, 1, 0, 0 }, // BEAM3 - mid nodes on edges 00147 { 0, 0, 0, 0 }, // TRUSS - no mid nodes 00148 { 0, 0, 0, 0 }, // TRUSS2 - no mid nodes 00149 { 0, 1, 0, 0 }, // TRUSS3 - mid nodes on edges 00150 { 0, 0, 0, 0 }, // TRI - no mid nodes 00151 { 0, 0, 0, 0 }, // TRI3 - no mid nodes 00152 { 0, 0, 0, 0 }, // SHELL3 - no mid nodes 00153 { 0, 1, 0, 0 }, // TRI6 - mid nodes on edges 00154 { 0, 1, 1, 0 }, // TRI7 - mid nodes on edges and faces 00155 { 0, 0, 0, 0 }, // QUAD - no mid nodes 00156 { 0, 0, 0, 0 }, // QUAD4 - no mid nodes 00157 { 0, 0, 1, 0 }, // QUAD5 - mid node on faces 00158 { 0, 1, 0, 0 }, // QUAD8 - mid nodes on edges 00159 { 0, 1, 1, 0 }, // QUAD9 - mid nodes on edges and faces 00160 { 0, 0, 0, 0 }, // SHELL - no mid nodes 00161 { 0, 0, 0, 0 }, // SHELL4 - no mid nodes 00162 { 0, 0, 1, 0 }, // SHELL5 - mid node on faces 00163 { 0, 1, 0, 0 }, // SHELL8 - mid nodes on edges 00164 { 0, 1, 1, 0 }, // SHELL9 - mid nodes on edges and faces 00165 { 0, 0, 0, 0 }, // TETRA - no mid nodes 00166 { 0, 0, 0, 0 }, // TETRA4 - no mid nodes 00167 { 0, 0, 0, 0 }, // TET4 - no mid nodes 00168 { 0, 0, 1, 0 }, // TETRA8 - mid nodes on faces 00169 { 0, 1, 0, 0 }, // TETRA10 - mid nodes on edges 00170 { 0, 1, 1, 0 }, // TETRA14 - mid nodes on edges and faces 00171 { 0, 0, 0, 0 }, // PYRAMID - no mid nodes 00172 { 0, 0, 0, 0 }, // PYRAMID5 - no mid nodes 00173 { 0, 0, 1, 0 }, // PYRAMID10 - *** TODO - not sure if this is right... 00174 { 0, 1, 0, 0 }, // PYRAMID13 - *** TODO - not sure if this is right... 00175 { 0, 1, 1, 0 }, // PYRAMID18 - *** TODO - not sure if this is right... 00176 { 0, 0, 0, 0 }, // WEDGE - no mid nodes 00177 { 0, 0, 0, 0 }, // KNIFE - no mid nodes 00178 { 0, 0, 0, 0 }, // HEX - no mid nodes 00179 { 0, 0, 0, 0 }, // HEX8 - no mid nodes 00180 { 0, 0, 0, 1 }, // HEX9 - mid node on element 00181 { 0, 1, 0, 0 }, // HEX20 - mid nodes on edges 00182 { 0, 1, 1, 1 }, // HEX27 - mid node on edges, faces and element 00183 { 0, 0, 0, 0 }, // HEXSHELL - *** TODO - not sure if this is right... 00184 { 0, 0, 0, 0 }, // POLYGON 00185 { 0, 0, 0, 0 }, // POLYHEDRON 00186 { 0, 0, 0, 0 } // UNKNOWN - no mid nodes 00187 }; 00188 00189 const int ExoIIUtil::ElementGeometricDimension[] = { 00190 3, // SPHERE 00191 3, // SPRING 00192 2, 2, 00193 2, // BAR 00194 3, 3, 00195 3, // BEAM 00196 3, 3, 00197 3, // TRUSS 00198 3, 3, 3, 3, 00199 3, // TRI 00200 2, 2, 2, 2, 00201 2, // QUAD 00202 3, 3, 3, 3, 00203 3, // SHELL 00204 3, 3, 3, 3, 00205 3, // TETRA 00206 3, 3, 3, 3, 3, 00207 3, // PYRAMID 00208 3, // WEDGE 00209 3, // KNIFE 00210 3, 3, 3, 3, 00211 3, // HEX 00212 3, // HEXSHELL 00213 2, // POLYGON 00214 3, // POLYHEDRON 00215 0 // UNKNOWN 00216 }; 00217 00218 ExoIIElementType ExoIIUtil::static_element_name_to_type( const char* name ) 00219 { 00220 int i; 00221 for( i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 00222 if( strcmp( ElementTypeNames[i], name ) == 0 ) return (ExoIIElementType)i; 00223 00224 return EXOII_MAX_ELEM_TYPE; 00225 } 00226 00227 ExoIIElementType ExoIIUtil::static_get_element_type( Interface* mdbImpl, 00228 const EntityHandle entity, 00229 const Tag mid_nodes_tag, 00230 const Tag geom_dimension_tag, 00231 const EntityType indiv_entity_type ) 00232 { 00233 // branch based on what kind of entity we're looking at 00234 EntityType handle_type = mdbImpl->type_from_handle( entity ); 00235 00236 if( handle_type == MBENTITYSET ) 00237 { 00238 00239 // it's a meshset - assume it's a block (check this?) and work off the midnodes tag 00240 00241 // get the element type of the block; first, get the hasMidNodes tag, then convert to an exo 00242 // element type 00243 int has_mid_nodes[4]; 00244 int dimension = -1; 00245 if( mdbImpl->tag_get_data( mid_nodes_tag, &entity, 1, has_mid_nodes ) != MB_SUCCESS ) 00246 { 00247 // no mid nodes tag - look for indiv entity type, and if it was input, output the 00248 // default number of vertices 00249 if( MBMAXTYPE != indiv_entity_type ) 00250 { 00251 // get dimension 00252 if( indiv_entity_type == MBQUAD || indiv_entity_type == MBTRI ) 00253 dimension = 3; // want to ouput shells by default 00254 else if( indiv_entity_type == MBEDGE ) 00255 dimension = 2; 00256 else 00257 dimension = CN::Dimension( indiv_entity_type ); 00258 00259 return get_element_type_from_num_verts( CN::VerticesPerEntity( indiv_entity_type ), indiv_entity_type, 00260 dimension ); 00261 } 00262 else 00263 return EXOII_MAX_ELEM_TYPE; 00264 } 00265 else 00266 { 00267 // block meshset had midnodes tag - look for geometric dimension one too 00268 mdbImpl->tag_get_data( geom_dimension_tag, &entity, 1, &dimension ); 00269 } 00270 00271 for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 00272 { 00273 if( ( indiv_entity_type == MBMAXTYPE || indiv_entity_type == ExoIIElementMBEntity[i] ) && 00274 has_mid_nodes[0] == HasMidNodes[i][0] && has_mid_nodes[1] == HasMidNodes[i][1] && 00275 has_mid_nodes[2] == HasMidNodes[i][2] && has_mid_nodes[3] == HasMidNodes[i][3] && 00276 ( -1 == dimension || ElementGeometricDimension[i] == dimension ) ) 00277 return (ExoIIElementType)i; 00278 } 00279 00280 return EXOII_MAX_ELEM_TYPE; 00281 } 00282 00283 else if( handle_type == MBVERTEX ) 00284 // only have one type of entity for vertices... 00285 return EXOII_SPHERE; 00286 00287 else 00288 { 00289 std::vector< EntityHandle > tmp( 31 ); 00290 00291 mdbImpl->get_connectivity( &entity, 1, tmp, true ); 00292 return get_element_type_from_num_verts( tmp.size(), indiv_entity_type ); 00293 // it's a regular entity - look for a connectivity tag 00294 } 00295 00296 // if we've gotten here, we failed 00297 // return EXOII_MAX_ELEM_TYPE; 00298 } 00299 00300 ExoIIElementType ExoIIUtil::get_element_type_from_num_verts( const int num_verts, 00301 const EntityType entity_type, 00302 const int dimension ) 00303 { 00304 if( MBPOLYGON == entity_type && 2 == dimension ) return EXOII_POLYGON; 00305 if( MBPOLYHEDRON == entity_type && 3 == dimension ) return EXOII_POLYHEDRON; 00306 for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ ) 00307 { 00308 if( ( entity_type == MBMAXTYPE || entity_type == ExoIIElementMBEntity[i] ) && 00309 VerticesPerElement[i] == num_verts && ElementGeometricDimension[i] >= dimension ) 00310 return (ExoIIElementType)i; 00311 } 00312 00313 return EXOII_MAX_ELEM_TYPE; 00314 } 00315 00316 } // namespace moab