MOAB: Mesh Oriented datABase  (version 5.2.1)
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 <string.h>
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, const EntityHandle entity,
00228                                                      const Tag mid_nodes_tag, const Tag geom_dimension_tag,
00229                                                      const EntityType indiv_entity_type )
00230 {
00231     // branch based on what kind of entity we're looking at
00232     EntityType handle_type = mdbImpl->type_from_handle( entity );
00233 
00234     if( handle_type == MBENTITYSET )
00235     {
00236 
00237         // it's a meshset - assume it's a block (check this?) and work off the midnodes tag
00238 
00239         // get the element type of the block; first, get the hasMidNodes tag, then convert to an exo
00240         // element type
00241         int has_mid_nodes[4];
00242         int dimension = -1;
00243         if( mdbImpl->tag_get_data( mid_nodes_tag, &entity, 1, has_mid_nodes ) != MB_SUCCESS )
00244         {
00245             // no mid nodes tag - look for indiv entity type, and if it was input, output the
00246             // default number of vertices
00247             if( MBMAXTYPE != indiv_entity_type )
00248             {
00249                 // get dimension
00250                 if( indiv_entity_type == MBQUAD || indiv_entity_type == MBTRI )
00251                     dimension = 3;  // want to ouput shells by default
00252                 else if( indiv_entity_type == MBEDGE )
00253                     dimension = 2;
00254                 else
00255                     dimension = CN::Dimension( indiv_entity_type );
00256 
00257                 return get_element_type_from_num_verts( CN::VerticesPerEntity( indiv_entity_type ), indiv_entity_type,
00258                                                         dimension );
00259             }
00260             else
00261                 return EXOII_MAX_ELEM_TYPE;
00262         }
00263         else
00264         {
00265             // block meshset had midnodes tag - look for geometric dimension one too
00266             mdbImpl->tag_get_data( geom_dimension_tag, &entity, 1, &dimension );
00267         }
00268 
00269         for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ )
00270         {
00271             if( ( indiv_entity_type == MBMAXTYPE || indiv_entity_type == ExoIIElementMBEntity[i] ) &&
00272                 has_mid_nodes[0] == HasMidNodes[i][0] && has_mid_nodes[1] == HasMidNodes[i][1] &&
00273                 has_mid_nodes[2] == HasMidNodes[i][2] && has_mid_nodes[3] == HasMidNodes[i][3] &&
00274                 ( -1 == dimension || ElementGeometricDimension[i] == dimension ) )
00275                 return (ExoIIElementType)i;
00276         }
00277 
00278         return EXOII_MAX_ELEM_TYPE;
00279     }
00280 
00281     else if( handle_type == MBVERTEX )
00282         // only have one type of entity for vertices...
00283         return EXOII_SPHERE;
00284 
00285     else
00286     {
00287         std::vector< EntityHandle > tmp( 31 );
00288 
00289         mdbImpl->get_connectivity( &entity, 1, tmp, true );
00290         return get_element_type_from_num_verts( tmp.size(), indiv_entity_type );
00291         // it's a regular entity - look for a connectivity tag
00292     }
00293 
00294     // if we've gotten here, we failed
00295     // return EXOII_MAX_ELEM_TYPE;
00296 }
00297 
00298 ExoIIElementType ExoIIUtil::get_element_type_from_num_verts( const int num_verts, const EntityType entity_type,
00299                                                              const int dimension )
00300 {
00301     if( MBPOLYGON == entity_type && 2 == dimension ) return EXOII_POLYGON;
00302     if( MBPOLYHEDRON == entity_type && 3 == dimension ) return EXOII_POLYHEDRON;
00303     for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ )
00304     {
00305         if( ( entity_type == MBMAXTYPE || entity_type == ExoIIElementMBEntity[i] ) &&
00306             VerticesPerElement[i] == num_verts && ElementGeometricDimension[i] >= dimension )
00307             return (ExoIIElementType)i;
00308     }
00309 
00310     return EXOII_MAX_ELEM_TYPE;
00311 }
00312 
00313 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines