MOAB: Mesh Oriented datABase  (version 5.4.0)
ExoIIUtil.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines