Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
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 
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 
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 
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 
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