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 /**
17 * \class moab::CN
18 * \author Tim Tautges
19 * \date April 2004
20 *
21 * \brief Canonical numbering data and functions
22 * This class represents canonical ordering of finite-element meshes.
23 * Elements in the finite element "zoo" are represented. Canonical numbering
24 * denotes the vertex, edge, and face numbers making up each kind of element,
25 * and the vertex numbers defining those entities. Functions for evaluating
26 * adjacencies and other things based on vertex numbering are also provided.
27 * By default, this class defines a zero-based numbering system.
28 * For a complete description of this class, see the document "MOAB Canonical
29 * Numbering Conventions", Timothy J. Tautges, Sandia National Laboratories
30 * Report #SAND2004-xxxx.
31 */
32 #ifndef MOAB_CN_HPP
33 #define MOAB_CN_HPP
34
35 #include <vector>
36 #include <algorithm>
37 #include <cassert>
38
39 #include "moab/EntityType.hpp"
40
41 namespace moab {
42
43 enum {
44 //! the maximum number n-1 dimension adjacencies a element may have
45 MAX_SUB_ENTITIES = 12,
46 //! the maximum number of nodes an n-1 dimensional element may have
47 MAX_SUB_ENTITY_VERTICES = 9
48 };
49
50 typedef std::pair<EntityType, EntityType> DimensionPair;
51
52 class CN
53 {
54 private:
55
56 //! entity names
57 static const char *entityTypeNames[];
58
59 //! declare private constructor, since we don't want to create any of these
60 CN();
61
62 //! the basis of the numbering system (normally 0 or 1, 0 by default)
63 static short int numberBasis;
64
65 //! switch the basis
66 static void SwitchBasis(const int old_basis, const int new_basis);
67
68 static short increasingInts[];
69
70 public:
71
72 enum { MAX_NODES_PER_ELEMENT = 27 };
73 enum { MID_EDGE_BIT = 1<<1,
74 MID_FACE_BIT = 1<<2,
75 MID_REGION_BIT = 1<<3 };
76
77 //! enum used to specify operation type
78 enum {INTERSECT = 0, UNION};
79
80 // each entity type has two ConnMap objects, holding information about the bounding
81 // edges and faces for each entity; see comment for mConnectivityMap
82 // (this struct not documented with Doxygen)
83 struct ConnMap
84 {
85 // Topological dimension of this entry
86 short int topo_dimension;
87
88 // Number of sub-elements of this dimension
89 short int num_sub_elements;
90
91 // Number of nodes in each sub-element of this dimension
92 short int num_corners_per_sub_element[MAX_SUB_ENTITIES];
93
94 // Type of each sub-element
95 EntityType target_type[MAX_SUB_ENTITIES];
96
97 // Connectivity of each of the sub-elements
98 short int conn[MAX_SUB_ENTITIES][MAX_SUB_ENTITY_VERTICES];
99 };
100
101 // mConnectivityMap[i=entity type][j=0,1,2]:
102 // num_sub_elements = # bounding edges(j=0) or faces(j=1) for entity type i, or self (j=2)
103 // num_corners_per_sub_element[k] (k=0..num_sub_elements-1) = number of nodes in sub-facet k
104 // (can vary over sub-facets, e.g. faces bounding a pyramid) or self (j=2)
105 // target_type[k] = entity type of sub-facet k (e.g. MBTRI or MBQUAD bounding a pyramid) or self (j=2)
106 // conn[k][l] (l=0..CN::VerticesPerEntity[target_type[k]]) = vertex connectivity of sub-facet k,
107 // with respect to entity i's canonical vertex ordering, or self (j=2)
108 // (not documented with Doxygen)
109 static const ConnMap mConnectivityMap[MBMAXTYPE][3];
110
111 // structure used to define reverse canonical ordering information
112 // (not documented with Doxygen)
113 struct UpConnMap
114 {
115 // Number of higher-dimensional entities using each sub-entity
116 short int num_targets_per_source_element[MAX_SUB_ENTITIES];
117
118 // Higher-dimensional entities using each sub-entity
119 short int targets_per_source_element[MAX_SUB_ENTITIES][MAX_SUB_ENTITIES];
120 };
121
122 // Reverse canonical numbering, duplicates data in mConnectivityMap, but
123 // connectivity data in this table must be in ascending order (used for
124 // efficient sorting)
125 // (not documented with Doxygen)
126 static const UpConnMap mUpConnMap[MBMAXTYPE][4][4];
127
128 // Mid-node bits indexed by number of nodes in element
129 static const unsigned char midNodesPerType[MBMAXTYPE][MAX_NODES_PER_ELEMENT+1];
130
131 //! Permutation and reverse permutation vectors
132 static short int permuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES+1];
133 static short int revPermuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES+1];
134
135 //! this const vector defines the starting and ending EntityType for
136 //! each dimension, e.g. TypeDimensionMap[2] returns a pair of EntityTypes
137 //! bounding dimension 2.
138 static const DimensionPair TypeDimensionMap[];
139
140 //! get the basis of the numbering system
141 static short int GetBasis();
142
143 //! set the basis of the numbering system
144 static void SetBasis(const int in_basis);
145
146 //! return the string type name for this type
147 static inline
148 const char *EntityTypeName(const EntityType this_type);
149
150 //! given a name, find the corresponding entity type
151 static EntityType EntityTypeFromName(const char *name);
152
153 //! return the topological entity dimension
154 static inline
155 short int Dimension(const EntityType t);
156
157 //! return the number of (corner) vertices contained in the specified type.
158 static inline
159 short int VerticesPerEntity(const EntityType t);
160
161 //! return the number of sub-entities bounding the entity.
162 static inline
163 short int NumSubEntities(const EntityType t, const int d);
164
165 //! return the type of a particular sub-entity.
166 //! \param this_type Type of entity for which sub-entity type is being queried
167 //! \param sub_dimension Topological dimension of sub-entity whose type is being queried
168 //! \param index Index of sub-entity whose type is being queried
169 //! \return type Entity type of sub-entity with specified dimension and index
170 static inline
171 EntityType SubEntityType(const EntityType this_type,
172 const int sub_dimension,
173 const int index);
174
175 //! return the vertex indices of the specified sub-entity.
176 //! \param this_type Type of entity for which sub-entity connectivity is being queried
177 //! \param sub_dimension Dimension of sub-entity
178 //! \param sub_index Index of sub-entity
179 //! \param sub_entity_conn Connectivity of sub-entity (returned to calling function)
180 static inline
181 void SubEntityVertexIndices(const EntityType this_type,
182 const int sub_dimension,
183 const int sub_index,
184 int sub_entity_conn[]);
185
186 //! return the vertex indices of the specified sub-entity.
187 //! \param this_type Type of entity for which sub-entity connectivity is being queried
188 //! \param sub_dimension Dimension of sub-entity
189 //! \param sub_index Index of sub-entity
190 //! \param num_sub_ent_vertices the number of vertices in the sub-entity
191 static inline
192 const short* SubEntityVertexIndices( const EntityType this_type,
193 const int sub_dimension,
194 const int sub_index,
195 EntityType& sub_type,
196 int& num_sub_ent_vertices );
197
198 //! return the node indices of the specified sub-entity.
199 //! \param this_topo The topology of the queried element type
200 //! \param num_nodes The number of nodes in the queried element type.
201 //! \param sub_dimension Dimension of sub-entity
202 //! \param sub_index Index of sub-entity
203 //! \param sub_entity_topo (Output) Topology of requested sub-entity.
204 //! \param num_sub_entity_nodes (Output) Number of nodes in the requested sub-entity.
205 //! \param sub_entity_conn (Output) Connectivity of sub-entity
206 static void SubEntityNodeIndices(const EntityType this_topo,
207 const int num_nodes,
208 const int sub_dimension,
209 const int sub_index,
210 EntityType& sub_entity_topo,
211 int& num_sub_entity_nodes,
212 int sub_entity_conn[]);
213
214 //! return the vertices of the specified sub entity
215 //! \param parent_conn Connectivity of parent entity
216 //! \param parent_type Entity type of parent entity
217 //! \param sub_dimension Dimension of sub-entity being queried
218 //! \param sub_index Index of sub-entity being queried
219 //! \param sub_entity_conn Connectivity of sub-entity, based on parent_conn and canonical
220 //! ordering for parent_type
221 //! \param num_sub_vertices Number of vertices in sub-entity
222 static void SubEntityConn(const void *parent_conn, const EntityType parent_type,
223 const int sub_dimension,
224 const int sub_index,
225 void *sub_entity_conn, int &num_sub_vertices);
226
227 //! For a specified set of sides of given dimension, return the intersection
228 //! or union of all sides of specified target dimension adjacent to those sides.
229 //! \param this_type Type of entity for which sub-entity connectivity is being queried
230 //! \param source_indices Indices of sides being queried
231 //! \param num_source_indices Number of entries in <em>source_indices</em>
232 //! \param source_dim Dimension of source entity
233 //! \param target_dim Dimension of target entity
234 //! \param index_list Indices of target entities (returned)
235 //! \param operation_type Specify either CN::INTERSECT or CN::UNION to get intersection
236 //! or union of target entity lists over source entities
237 static short int AdjacentSubEntities(const EntityType this_type,
238 const int *source_indices,
239 const int num_source_indices,
240 const int source_dim,
241 const int target_dim,
242 std::vector<int> &index_list,
243 const int operation_type = CN::INTERSECT);
244
245 //! return the side index represented in the input sub-entity connectivity in the input
246 //! parent entity connectivity array.
247 //! \param parent_conn Connectivity of parent entity being queried
248 //! \param parent_type Entity type of parent entity
249 //! \param child_conn Connectivity of child whose index is being queried
250 //! \param child_num_verts Number of vertices in <em>child_conn</em>
251 //! \param child_dim Dimension of child entity being queried
252 //! \param side_number Side number of child entity (returned)
253 //! \param sense Sense of child entity with respect to order in <em>child_conn</em> (returned)
254 //! \param offset Offset of <em>child_conn</em> with respect to canonical ordering data (returned)
255 //! \return status Returns zero if successful, -1 if not
256 static short int SideNumber(const EntityType parent_type, const int *parent_conn,
257 const int *child_conn, const int child_num_verts,
258 const int child_dim,
259 int &side_number, int &sense, int &offset);
260 static short int SideNumber(const EntityType parent_type, const unsigned int *parent_conn,
261 const unsigned int *child_conn, const int child_num_verts,
262 const int child_dim,
263 int &side_number, int &sense, int &offset);
264 static short int SideNumber(const EntityType parent_type, const long *parent_conn,
265 const long *child_conn, const int child_num_verts,
266 const int child_dim,
267 int &side_number, int &sense, int &offset);
268 static short int SideNumber(const EntityType parent_type, const unsigned long *parent_conn,
269 const unsigned long *child_conn, const int child_num_verts,
270 const int child_dim,
271 int &side_number, int &sense, int &offset);
272 static short int SideNumber(const EntityType parent_type, const unsigned long long *parent_conn,
273 const unsigned long long *child_conn, const int child_num_verts,
274 const int child_dim,
275 int &side_number, int &sense, int &offset);
276 static short int SideNumber(const EntityType parent_type, void * const *parent_conn,
277 void * const *child_conn, const int child_num_verts,
278 const int child_dim,
279 int &side_number, int &sense, int &offset);
280
281 //! return the side index represented in the input sub-entity connectivity
282 //! \param parent_type Entity type of parent entity
283 //! \param child_conn_indices Child connectivity to query, specified as indices
284 //! into the connectivity list of the parent.
285 //! \param child_num_verts Number of values in <em>child_conn_indices</em>
286 //! \param child_dim Dimension of child entity being queried
287 //! \param side_number Side number of child entity (returned)
288 //! \param sense Sense of child entity with respect to order in <em>child_conn</em> (returned)
289 //! \param offset Offset of <em>child_conn</em> with respect to canonical ordering data (returned)
290 //! \return status Returns zero if successful, -1 if not
291 static short int SideNumber(const EntityType parent_type,
292 const int *child_conn_indices, const int child_num_verts,
293 const int child_dim,
294 int &side_number, int &sense, int &offset);
295
296 //! return the dimension and index of the opposite side, given parent entity type and child
297 //! dimension and index. This function is only defined for certain types of parent/child types:
298 //! (Parent, Child dim->Opposite dim):
299 //! (Tri, 1->0), (Tri, 0->1), (Quad, 1->1), (Quad, 0->0),
300 //! (Tet, 2->0), (Tet, 1->1), (Tet, 0->2),
301 //! (Hex, 2->2), (Hex, 1->1)(diagonally across element), (Hex, 0->0) (diagonally across element)
302 //! All other parent types and child dimensions return an error.
303 //!
304 //! \param parent_type The type of parent element
305 //! \param child_type The type of child element
306 //! \param child_index The index of the child element
307 //! \param opposite_index The index of the opposite element
308 //! \return status Returns 0 if successful, -1 if not
309 static short int OppositeSide(const EntityType parent_type,
310 const int child_index,
311 const int child_dim,
312 int &opposite_index,
313 int &opposite_dim);
314
315 //! given two connectivity arrays, determine whether or not they represent the same entity.
316 //! \param conn1 Connectivity array of first entity
317 //! \param conn2 Connectivity array of second entity
318 //! \param num_vertices Number of entries in <em>conn1</em> and <em>conn2</em>
319 //! \param direct If positive, entities have the same sense (returned)
320 //! \param offset Offset of <em>conn2</em>'s first vertex in <em>conn1</em>
321 //! \return bool Returns true if <em>conn1</em> and <em>conn2</em> match
322 static bool ConnectivityMatch(const int *conn1,
323 const int *conn2,
324 const int num_vertices,
325 int &direct, int &offset);
326 static bool ConnectivityMatch(const unsigned int *conn1,
327 const unsigned int *conn2,
328 const int num_vertices,
329 int &direct, int &offset);
330 static bool ConnectivityMatch(const long* conn1,
331 const long* conn2,
332 const int num_vertices,
333 int& direct, int& offset );
334 static bool ConnectivityMatch(const unsigned long* conn1,
335 const unsigned long* conn2,
336 const int num_vertices,
337 int &direct, int& offset );
338 static bool ConnectivityMatch(const unsigned long long* conn1,
339 const unsigned long long* conn2,
340 const int num_vertices,
341 int &direct, int& offset );
342 static bool ConnectivityMatch(void* const* conn1,
343 void* const* conn2,
344 const int num_vertices,
345 int& direct, int& offset );
346
347 //! Set permutation or reverse permutation vector
348 //! Forward permutation is from CN's numbering into application's ordering;
349 //! that is, if i is CN's index, pvec[i] is application's index. This
350 //! function stores the permutation vector for this type and facet dimension,
351 //! which then is used in calls to permuteThis or revPermuteThis.
352 //! \param t EntityType for which to set permutation
353 //! \param dim Dimension of facets whose permutation array is being set
354 //! \param pvec Permutation array
355 //! \param num_entries Number of indicies in permutation array
356 //! \param is_reverse Array is reverse permutation
357 static inline
358 void setPermutation(const EntityType t, const int dim, short int *pvec,
359 const int num_entries, const bool is_reverse = false);
360
361 //! Reset permutation or reverse permutation vector
362 //! \param t EntityType whose permutation vector is being reset
363 //! \param dim Dimension of facets being reset; if -1 is input, all dimensions are reset
364 static inline
365 void resetPermutation(const EntityType t, const int dim);
366
367 //! Permute a handle array according to permutation vector set with setPermute;
368 //! permutation is done in-place
369 //! \param t EntityType of handles in pvec
370 //! \param dim Dimension of handles in pvec
371 //! \param pvec Handle array being permuted
372 //! \param indices_per_ent Number of indices per entity
373 //! \param num_entries Number of entities in pvec
374 static int permuteThis(const EntityType t, const int dim, int *pvec,
375 const int indices_per_ent, const int num_entries);
376 static int permuteThis(const EntityType t, const int dim, unsigned int *pvec,
377 const int indices_per_ent, const int num_entries);
378 static int permuteThis(const EntityType t, const int dim, long *pvec,
379 const int indices_per_ent, const int num_entries);
380 static int permuteThis(const EntityType t, const int dim, void **pvec,
381 const int indices_per_ent, const int num_entries);
382
383 //! Reverse permute a handle array according to reverse permutation vector set with setPermute;
384 //! reverse permutation is done in-place
385 //! \param t EntityType of handles in pvec
386 //! \param dim Dimension of handles in pvec
387 //! \param pvec Handle array being reverse permuted
388 //! \param indices_per_ent Number of indices per entity
389 //! \param num_entries Number of entities in pvec
390 static int revPermuteThis(const EntityType t, const int dim, int *pvec,
391 const int indices_per_ent, const int num_entries);
392 static int revPermuteThis(const EntityType t, const int dim, unsigned int *pvec,
393 const int indices_per_ent, const int num_entries);
394 static int revPermuteThis(const EntityType t, const int dim, long *pvec,
395 const int indices_per_ent, const int num_entries);
396 static int revPermuteThis(const EntityType t, const int dim, void **pvec,
397 const int indices_per_ent, const int num_entries);
398
399 //! true if entities of a given type and number of nodes indicates mid edge nodes are present.
400 //! \param this_type Type of entity for which sub-entity connectivity is being queried
401 //! \param num_verts Number of nodes defining entity
402 //! \return bool Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
403 //! mid-edge nodes are likely
404 static inline
405 bool HasMidEdgeNodes(const EntityType this_type,
406 const int num_verts);
407
408 //! true if entities of a given type and number of nodes indicates mid face nodes are present.
409 //! \param this_type Type of entity for which sub-entity connectivity is being queried
410 //! \param num_verts Number of nodes defining entity
411 //! \return bool Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
412 //! mid-face nodes are likely
413 static inline
414 bool HasMidFaceNodes(const EntityType this_type,
415 const int num_verts);
416
417 //! true if entities of a given type and number of nodes indicates mid region nodes are present.
418 //! \param this_type Type of entity for which sub-entity connectivity is being queried
419 //! \param num_verts Number of nodes defining entity
420 //! \return bool Returns true if <em>this_type</em> combined with <em>num_nodes</em> indicates
421 //! mid-region nodes are likely
422 static inline
423 bool HasMidRegionNodes(const EntityType this_type,
424 const int num_verts);
425
426 //! true if entities of a given type and number of nodes indicates mid edge/face/region nodes
427 //! are present.
428 //! \param this_type Type of entity for which sub-entity connectivity is being queried
429 //! \param num_verts Number of nodes defining entity
430 //! \param mid_nodes If <em>mid_nodes[i], i=1..2</em> is non-zero, indicates that mid-edge
431 //! (i=1), mid-face (i=2), and/or mid-region (i=3) nodes are likely
432 static inline
433 void HasMidNodes(const EntityType this_type,
434 const int num_verts,
435 int mid_nodes[4]);
436
437 //! Same as above, except returns a single integer with the bits, from
438 //! least significant to most significant set to one if the corresponding
439 //! mid nodes on sub entities of the least dimension (0) to the highest
440 //! dimension (3) are present in the elment type.
441 static inline
442 int HasMidNodes( const EntityType this_type, const int num_verts );
443
444 //! given data about an element and a vertex in that element, return the dimension
445 //! and index of the sub-entity that the vertex resolves. If it does not resolve a
446 //! sub-entity, either because it's a corner node or it's not in the element, -1 is
447 //! returned in both return values.
448 //! \param elem_type Type of entity being queried
449 //! \param num_nodes The number of nodes in the element connectivity
450 //! \param ho_node_index The position of the HO node in the connectivity list (zero based)
451 //! \param parent_dim Dimension of sub-entity high-order node resolves (returned)
452 //! \param parent_index Index of sub-entity high-order node resolves (returned)
453 static void HONodeParent( EntityType elem_type,
454 int num_nodes,
455 int ho_node_index,
456 int &parent_dim,
457 int &parent_index );
458
459 //! for an entity of this type with num_verts vertices, and a specified subfacet
460 //! (dimension and index), return the index of the higher order node for that entity
461 //! in this entity's connectivity array
462 //! \param this_type Type of entity being queried
463 //! \param num_verts Number of vertices for the entity being queried
464 //! \param subfacet_dim Dimension of sub-entity being queried
465 //! \param subfacet_index Index of sub-entity being queried
466 //! \return index Index of sub-entity's higher-order node
467 static short int HONodeIndex(const EntityType this_type, const int num_verts,
468 const int subfacet_dim, const int subfacet_index);
469 };
470
471 //! get the basis of the numbering system
GetBasis()472 inline short int CN::GetBasis() {return numberBasis;}
473
EntityTypeName(const EntityType this_type)474 inline const char *CN::EntityTypeName(const EntityType this_type)
475 {
476 return entityTypeNames[this_type];
477 }
478
Dimension(const EntityType t)479 inline short int CN::Dimension(const EntityType t)
480 {
481 return mConnectivityMap[t][0].topo_dimension;
482 }
483
VerticesPerEntity(const EntityType t)484 inline short int CN::VerticesPerEntity(const EntityType t)
485 {
486 return (MBVERTEX == t ? (short int) 1 : mConnectivityMap[t][mConnectivityMap[t][0].topo_dimension-1].num_corners_per_sub_element[0]);
487 }
488
NumSubEntities(const EntityType t,const int d)489 inline short int CN::NumSubEntities(const EntityType t, const int d)
490 {
491 return (t != MBVERTEX && d > 0 ? mConnectivityMap[t][d-1].num_sub_elements :
492 (d ? (short int) -1 : VerticesPerEntity(t)));
493 }
494
495 //! return the type of a particular sub-entity.
SubEntityType(const EntityType this_type,const int sub_dimension,const int index)496 inline EntityType CN::SubEntityType(const EntityType this_type,
497 const int sub_dimension,
498 const int index)
499 {
500
501 return (!sub_dimension ? MBVERTEX :
502 (Dimension(this_type) == sub_dimension && 0 == index ? this_type :
503 mConnectivityMap[this_type][sub_dimension-1].target_type[index]));
504 }
505
SubEntityVertexIndices(const EntityType this_type,const int sub_dimension,const int index,EntityType & sub_type,int & n)506 inline const short* CN::SubEntityVertexIndices( const EntityType this_type,
507 const int sub_dimension,
508 const int index,
509 EntityType& sub_type,
510 int& n )
511 {
512 if (sub_dimension == 0) {
513 n = 1;
514 sub_type = MBVERTEX;
515 return increasingInts + index;
516 }
517 else {
518 const CN::ConnMap& map = mConnectivityMap[this_type][sub_dimension-1];
519 sub_type = map.target_type[index];
520 n = map.num_corners_per_sub_element[index];
521 return map.conn[index];
522 }
523 }
524
525 //! return the connectivity of the specified sub-entity.
SubEntityVertexIndices(const EntityType this_type,const int sub_dimension,const int index,int sub_entity_conn[])526 inline void CN::SubEntityVertexIndices(const EntityType this_type,
527 const int sub_dimension,
528 const int index,
529 int sub_entity_conn[])
530 {
531 EntityType type;
532 int n;
533 const short* indices = SubEntityVertexIndices( this_type, sub_dimension, index, type, n );
534 std::copy( indices, indices+n, sub_entity_conn );
535 }
536
HasMidEdgeNodes(const EntityType this_type,const int num_nodes)537 inline bool CN::HasMidEdgeNodes(const EntityType this_type,
538 const int num_nodes)
539 {
540 const int bits = HasMidNodes( this_type, num_nodes );
541 return static_cast<bool>( (bits & (1<<1)) >> 1 );
542 }
543
HasMidFaceNodes(const EntityType this_type,const int num_nodes)544 inline bool CN::HasMidFaceNodes(const EntityType this_type,
545 const int num_nodes)
546 {
547 const int bits = HasMidNodes( this_type, num_nodes );
548 return static_cast<bool>( (bits & (1<<2)) >> 2 );
549 }
550
HasMidRegionNodes(const EntityType this_type,const int num_nodes)551 inline bool CN::HasMidRegionNodes(const EntityType this_type,
552 const int num_nodes)
553 {
554 const int bits = HasMidNodes( this_type, num_nodes );
555 return static_cast<bool>( (bits & (1<<3)) >> 3 );
556 }
557
HasMidNodes(const EntityType this_type,const int num_nodes)558 inline int CN::HasMidNodes( const EntityType this_type, const int num_nodes )
559 {
560 assert( (unsigned)num_nodes <= (unsigned)MAX_NODES_PER_ELEMENT );
561 return midNodesPerType[this_type][num_nodes];
562 }
563
564
HasMidNodes(const EntityType this_type,const int num_nodes,int mid_nodes[4])565 inline void CN::HasMidNodes(const EntityType this_type, const int num_nodes,
566 int mid_nodes[4])
567 {
568 const int bits = HasMidNodes( this_type, num_nodes );
569 mid_nodes[0] = 0;
570 mid_nodes[1] = (bits & (1<<1)) >> 1;
571 mid_nodes[2] = (bits & (1<<2)) >> 2;
572 mid_nodes[3] = (bits & (1<<3)) >> 3;
573 }
574
575 //! Set permutation or reverse permutation vector
setPermutation(const EntityType t,const int dim,short int * pvec,const int num_entries,const bool is_reverse)576 inline void CN::setPermutation(const EntityType t, const int dim, short int *pvec,
577 const int num_entries, const bool is_reverse)
578 {
579 short int *this_vec = permuteVec[t][dim], *that_vec = revPermuteVec[t][dim];
580 if (is_reverse) {
581 this_vec = revPermuteVec[t][dim];
582 that_vec = permuteVec[t][dim];
583 }
584
585 for (short int i = 0; i < num_entries; i++) {
586 this_vec[i] = pvec[i];
587 that_vec[pvec[i]] = i;
588 }
589
590 this_vec[MAX_SUB_ENTITIES] = that_vec[MAX_SUB_ENTITIES] = (short)num_entries;
591 }
592
593 //! Reset permutation or reverse permutation vector
resetPermutation(const EntityType t,const int dim)594 inline void CN::resetPermutation(const EntityType t, const int dim)
595 {
596 if (-1 == dim) {
597 for (unsigned int i = 0; i < 3; i++) resetPermutation(t, i);
598 return;
599 }
600
601 for (short unsigned int i = 0; i < MAX_SUB_ENTITIES; i++) {
602 revPermuteVec[t][dim][i] = permuteVec[t][dim][i] = i;
603 }
604
605 revPermuteVec[t][dim][MAX_SUB_ENTITIES] =
606 permuteVec[t][dim][MAX_SUB_ENTITIES] = MAX_SUB_ENTITIES+1;
607 }
608
609 } // namespace moab
610
611 #endif
612