Branch data Line data Source code
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 <string.h>
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 : 110 : ExoIIElementType ExoIIUtil::static_element_name_to_type( const char* name )
219 : : {
220 : : int i;
221 [ + - ]: 3246 : for( i = 0; i < EXOII_MAX_ELEM_TYPE; i++ )
222 [ + + ]: 3246 : if( strcmp( ElementTypeNames[i], name ) == 0 ) return (ExoIIElementType)i;
223 : :
224 : 0 : return EXOII_MAX_ELEM_TYPE;
225 : : }
226 : :
227 : 0 : ExoIIElementType ExoIIUtil::static_get_element_type( Interface* mdbImpl, const EntityHandle entity,
228 : : const Tag mid_nodes_tag, const Tag geom_dimension_tag,
229 : : const EntityType indiv_entity_type )
230 : : {
231 : : // branch based on what kind of entity we're looking at
232 : 0 : EntityType handle_type = mdbImpl->type_from_handle( entity );
233 : :
234 [ # # ]: 0 : if( handle_type == MBENTITYSET )
235 : : {
236 : :
237 : : // it's a meshset - assume it's a block (check this?) and work off the midnodes tag
238 : :
239 : : // get the element type of the block; first, get the hasMidNodes tag, then convert to an exo
240 : : // element type
241 : : int has_mid_nodes[4];
242 : 0 : int dimension = -1;
243 [ # # ][ # # ]: 0 : if( mdbImpl->tag_get_data( mid_nodes_tag, &entity, 1, has_mid_nodes ) != MB_SUCCESS )
244 : : {
245 : : // no mid nodes tag - look for indiv entity type, and if it was input, output the
246 : : // default number of vertices
247 [ # # ]: 0 : if( MBMAXTYPE != indiv_entity_type )
248 : : {
249 : : // get dimension
250 [ # # ][ # # ]: 0 : if( indiv_entity_type == MBQUAD || indiv_entity_type == MBTRI )
251 : 0 : dimension = 3; // want to ouput shells by default
252 [ # # ]: 0 : else if( indiv_entity_type == MBEDGE )
253 : 0 : dimension = 2;
254 : : else
255 [ # # ]: 0 : dimension = CN::Dimension( indiv_entity_type );
256 : :
257 [ # # ]: 0 : return get_element_type_from_num_verts( CN::VerticesPerEntity( indiv_entity_type ), indiv_entity_type,
258 [ # # ]: 0 : dimension );
259 : : }
260 : : else
261 : 0 : return EXOII_MAX_ELEM_TYPE;
262 : : }
263 : : else
264 : : {
265 : : // block meshset had midnodes tag - look for geometric dimension one too
266 [ # # ]: 0 : mdbImpl->tag_get_data( geom_dimension_tag, &entity, 1, &dimension );
267 : : }
268 : :
269 [ # # ]: 0 : for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ )
270 : : {
271 [ # # ][ # # ]: 0 : if( ( indiv_entity_type == MBMAXTYPE || indiv_entity_type == ExoIIElementMBEntity[i] ) &&
[ # # ]
272 [ # # ][ # # ]: 0 : has_mid_nodes[0] == HasMidNodes[i][0] && has_mid_nodes[1] == HasMidNodes[i][1] &&
273 [ # # ][ # # ]: 0 : has_mid_nodes[2] == HasMidNodes[i][2] && has_mid_nodes[3] == HasMidNodes[i][3] &&
274 [ # # ]: 0 : ( -1 == dimension || ElementGeometricDimension[i] == dimension ) )
275 : 0 : return (ExoIIElementType)i;
276 : : }
277 : :
278 : 0 : return EXOII_MAX_ELEM_TYPE;
279 : : }
280 : :
281 [ # # ]: 0 : else if( handle_type == MBVERTEX )
282 : : // only have one type of entity for vertices...
283 : 0 : return EXOII_SPHERE;
284 : :
285 : : else
286 : : {
287 [ # # ]: 0 : std::vector< EntityHandle > tmp( 31 );
288 : :
289 [ # # ]: 0 : mdbImpl->get_connectivity( &entity, 1, tmp, true );
290 [ # # ]: 0 : return get_element_type_from_num_verts( tmp.size(), indiv_entity_type );
291 : : // it's a regular entity - look for a connectivity tag
292 : : }
293 : :
294 : : // if we've gotten here, we failed
295 : : // return EXOII_MAX_ELEM_TYPE;
296 : : }
297 : :
298 : 25 : ExoIIElementType ExoIIUtil::get_element_type_from_num_verts( const int num_verts, const EntityType entity_type,
299 : : const int dimension )
300 : : {
301 [ - + ][ # # ]: 25 : if( MBPOLYGON == entity_type && 2 == dimension ) return EXOII_POLYGON;
302 [ - + ][ # # ]: 25 : if( MBPOLYHEDRON == entity_type && 3 == dimension ) return EXOII_POLYHEDRON;
303 [ + - ]: 703 : for( int i = 0; i < EXOII_MAX_ELEM_TYPE; i++ )
304 : : {
305 [ + - ][ + + ]: 703 : if( ( entity_type == MBMAXTYPE || entity_type == ExoIIElementMBEntity[i] ) &&
[ + + ]
306 [ + - ]: 25 : VerticesPerElement[i] == num_verts && ElementGeometricDimension[i] >= dimension )
307 : 25 : return (ExoIIElementType)i;
308 : : }
309 : :
310 : 0 : return EXOII_MAX_ELEM_TYPE;
311 : : }
312 : :
313 [ + - ][ + - ]: 228 : } // namespace moab
|