moab
|
00001 00032 #ifndef MOAB_CN_HPP 00033 #define MOAB_CN_HPP 00034 00035 #include <vector> 00036 #include <algorithm> 00037 #include <cassert> 00038 00039 #include "moab/EntityType.hpp" 00040 00041 namespace moab { 00042 00043 enum { 00045 MAX_SUB_ENTITIES = 12, 00047 MAX_SUB_ENTITY_VERTICES = 9 00048 }; 00049 00050 typedef std::pair<EntityType, EntityType> DimensionPair; 00051 00052 class CN 00053 { 00054 private: 00055 00057 static const char *entityTypeNames[]; 00058 00060 CN(); 00061 00063 static short int numberBasis; 00064 00066 static void SwitchBasis(const int old_basis, const int new_basis); 00067 00068 static short increasingInts[]; 00069 00070 public: 00071 00072 enum { MAX_NODES_PER_ELEMENT = 27 }; 00073 enum { MID_EDGE_BIT = 1<<1, 00074 MID_FACE_BIT = 1<<2, 00075 MID_REGION_BIT = 1<<3 }; 00076 00078 enum {INTERSECT = 0, UNION}; 00079 00080 // each entity type has two ConnMap objects, holding information about the bounding 00081 // edges and faces for each entity; see comment for mConnectivityMap 00082 // (this struct not documented with Doxygen) 00083 struct ConnMap 00084 { 00085 // Topological dimension of this entry 00086 short int topo_dimension; 00087 00088 // Number of sub-elements of this dimension 00089 short int num_sub_elements; 00090 00091 // Number of nodes in each sub-element of this dimension 00092 short int num_corners_per_sub_element[MAX_SUB_ENTITIES]; 00093 00094 // Type of each sub-element 00095 EntityType target_type[MAX_SUB_ENTITIES]; 00096 00097 // Connectivity of each of the sub-elements 00098 short int conn[MAX_SUB_ENTITIES][MAX_SUB_ENTITY_VERTICES]; 00099 }; 00100 00101 // mConnectivityMap[i=entity type][j=0,1,2]: 00102 // num_sub_elements = # bounding edges(j=0) or faces(j=1) for entity type i, or self (j=2) 00103 // num_corners_per_sub_element[k] (k=0..num_sub_elements-1) = number of nodes in sub-facet k 00104 // (can vary over sub-facets, e.g. faces bounding a pyramid) or self (j=2) 00105 // target_type[k] = entity type of sub-facet k (e.g. MBTRI or MBQUAD bounding a pyramid) or self (j=2) 00106 // conn[k][l] (l=0..CN::VerticesPerEntity[target_type[k]]) = vertex connectivity of sub-facet k, 00107 // with respect to entity i's canonical vertex ordering, or self (j=2) 00108 // (not documented with Doxygen) 00109 static const ConnMap mConnectivityMap[MBMAXTYPE][3]; 00110 00111 // structure used to define reverse canonical ordering information 00112 // (not documented with Doxygen) 00113 struct UpConnMap 00114 { 00115 // Number of higher-dimensional entities using each sub-entity 00116 short int num_targets_per_source_element[MAX_SUB_ENTITIES]; 00117 00118 // Higher-dimensional entities using each sub-entity 00119 short int targets_per_source_element[MAX_SUB_ENTITIES][MAX_SUB_ENTITIES]; 00120 }; 00121 00122 // Reverse canonical numbering, duplicates data in mConnectivityMap, but 00123 // connectivity data in this table must be in ascending order (used for 00124 // efficient sorting) 00125 // (not documented with Doxygen) 00126 static const UpConnMap mUpConnMap[MBMAXTYPE][4][4]; 00127 00128 // Mid-node bits indexed by number of nodes in element 00129 static const unsigned char midNodesPerType[MBMAXTYPE][MAX_NODES_PER_ELEMENT+1]; 00130 00132 static short int permuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES+1]; 00133 static short int revPermuteVec[MBMAXTYPE][3][MAX_SUB_ENTITIES+1]; 00134 00138 static const DimensionPair TypeDimensionMap[]; 00139 00141 static short int GetBasis(); 00142 00144 static void SetBasis(const int in_basis); 00145 00147 static inline 00148 const char *EntityTypeName(const EntityType this_type); 00149 00151 static EntityType EntityTypeFromName(const char *name); 00152 00154 static inline 00155 short int Dimension(const EntityType t); 00156 00158 static inline 00159 short int VerticesPerEntity(const EntityType t); 00160 00162 static inline 00163 short int NumSubEntities(const EntityType t, const int d); 00164 00170 static inline 00171 EntityType SubEntityType(const EntityType this_type, 00172 const int sub_dimension, 00173 const int index); 00174 00180 static inline 00181 void SubEntityVertexIndices(const EntityType this_type, 00182 const int sub_dimension, 00183 const int sub_index, 00184 int sub_entity_conn[]); 00185 00191 static inline 00192 const short* SubEntityVertexIndices( const EntityType this_type, 00193 const int sub_dimension, 00194 const int sub_index, 00195 EntityType& sub_type, 00196 int& num_sub_ent_vertices ); 00197 00206 static void SubEntityNodeIndices(const EntityType this_topo, 00207 const int num_nodes, 00208 const int sub_dimension, 00209 const int sub_index, 00210 EntityType& sub_entity_topo, 00211 int& num_sub_entity_nodes, 00212 int sub_entity_conn[]); 00213 00222 static void SubEntityConn(const void *parent_conn, const EntityType parent_type, 00223 const int sub_dimension, 00224 const int sub_index, 00225 void *sub_entity_conn, int &num_sub_vertices); 00226 00237 static short int AdjacentSubEntities(const EntityType this_type, 00238 const int *source_indices, 00239 const int num_source_indices, 00240 const int source_dim, 00241 const int target_dim, 00242 std::vector<int> &index_list, 00243 const int operation_type = CN::INTERSECT); 00244 00256 static short int SideNumber(const EntityType parent_type, const int *parent_conn, 00257 const int *child_conn, const int child_num_verts, 00258 const int child_dim, 00259 int &side_number, int &sense, int &offset); 00260 static short int SideNumber(const EntityType parent_type, const unsigned int *parent_conn, 00261 const unsigned int *child_conn, const int child_num_verts, 00262 const int child_dim, 00263 int &side_number, int &sense, int &offset); 00264 static short int SideNumber(const EntityType parent_type, const long *parent_conn, 00265 const long *child_conn, const int child_num_verts, 00266 const int child_dim, 00267 int &side_number, int &sense, int &offset); 00268 static short int SideNumber(const EntityType parent_type, const unsigned long *parent_conn, 00269 const unsigned long *child_conn, const int child_num_verts, 00270 const int child_dim, 00271 int &side_number, int &sense, int &offset); 00272 static short int SideNumber(const EntityType parent_type, void * const *parent_conn, 00273 void * const *child_conn, const int child_num_verts, 00274 const int child_dim, 00275 int &side_number, int &sense, int &offset); 00276 00287 static short int SideNumber(const EntityType parent_type, 00288 const int *child_conn_indices, const int child_num_verts, 00289 const int child_dim, 00290 int &side_number, int &sense, int &offset); 00291 00305 static short int OppositeSide(const EntityType parent_type, 00306 const int child_index, 00307 const int child_dim, 00308 int &opposite_index, 00309 int &opposite_dim); 00310 00318 static bool ConnectivityMatch(const int *conn1, 00319 const int *conn2, 00320 const int num_vertices, 00321 int &direct, int &offset); 00322 static bool ConnectivityMatch(const unsigned int *conn1, 00323 const unsigned int *conn2, 00324 const int num_vertices, 00325 int &direct, int &offset); 00326 static bool ConnectivityMatch(const long* conn1, 00327 const long* conn2, 00328 const int num_vertices, 00329 int& direct, int& offset ); 00330 static bool ConnectivityMatch(const unsigned long* conn1, 00331 const unsigned long* conn2, 00332 const int num_vertices, 00333 int &direct, int& offset ); 00334 static bool ConnectivityMatch(void* const* conn1, 00335 void* const* conn2, 00336 const int num_vertices, 00337 int& direct, int& offset ); 00338 00349 static inline 00350 void setPermutation(const EntityType t, const int dim, short int *pvec, 00351 const int num_entries, const bool is_reverse = false); 00352 00356 static inline 00357 void resetPermutation(const EntityType t, const int dim); 00358 00366 static int permuteThis(const EntityType t, const int dim, int *pvec, 00367 const int indices_per_ent, const int num_entries); 00368 static int permuteThis(const EntityType t, const int dim, unsigned int *pvec, 00369 const int indices_per_ent, const int num_entries); 00370 static int permuteThis(const EntityType t, const int dim, long *pvec, 00371 const int indices_per_ent, const int num_entries); 00372 static int permuteThis(const EntityType t, const int dim, void **pvec, 00373 const int indices_per_ent, const int num_entries); 00374 00382 static int revPermuteThis(const EntityType t, const int dim, int *pvec, 00383 const int indices_per_ent, const int num_entries); 00384 static int revPermuteThis(const EntityType t, const int dim, unsigned int *pvec, 00385 const int indices_per_ent, const int num_entries); 00386 static int revPermuteThis(const EntityType t, const int dim, long *pvec, 00387 const int indices_per_ent, const int num_entries); 00388 static int revPermuteThis(const EntityType t, const int dim, void **pvec, 00389 const int indices_per_ent, const int num_entries); 00390 00396 static inline 00397 bool HasMidEdgeNodes(const EntityType this_type, 00398 const int num_verts); 00399 00405 static inline 00406 bool HasMidFaceNodes(const EntityType this_type, 00407 const int num_verts); 00408 00414 static inline 00415 bool HasMidRegionNodes(const EntityType this_type, 00416 const int num_verts); 00417 00424 static inline 00425 void HasMidNodes(const EntityType this_type, 00426 const int num_verts, 00427 int mid_nodes[4]); 00428 00433 static inline 00434 int HasMidNodes( const EntityType this_type, const int num_verts ); 00435 00445 static void HONodeParent( EntityType elem_type, 00446 int num_nodes, 00447 int ho_node_index, 00448 int &parent_dim, 00449 int &parent_index ); 00450 00459 static short int HONodeIndex(const EntityType this_type, const int num_verts, 00460 const int subfacet_dim, const int subfacet_index); 00461 }; 00462 00464 inline short int CN::GetBasis() {return numberBasis;} 00465 00466 inline const char *CN::EntityTypeName(const EntityType this_type) 00467 { 00468 return entityTypeNames[this_type]; 00469 } 00470 00471 inline short int CN::Dimension(const EntityType t) 00472 { 00473 return mConnectivityMap[t][0].topo_dimension; 00474 } 00475 00476 inline short int CN::VerticesPerEntity(const EntityType t) 00477 { 00478 return (MBVERTEX == t ? (short int) 1 : mConnectivityMap[t][mConnectivityMap[t][0].topo_dimension-1].num_corners_per_sub_element[0]); 00479 } 00480 00481 inline short int CN::NumSubEntities(const EntityType t, const int d) 00482 { 00483 return (t != MBVERTEX && d > 0 ? mConnectivityMap[t][d-1].num_sub_elements : 00484 (d ? (short int) -1 : VerticesPerEntity(t))); 00485 } 00486 00488 inline EntityType CN::SubEntityType(const EntityType this_type, 00489 const int sub_dimension, 00490 const int index) 00491 { 00492 00493 return (!sub_dimension ? MBVERTEX : 00494 (Dimension(this_type) == sub_dimension && 0 == index ? this_type : 00495 mConnectivityMap[this_type][sub_dimension-1].target_type[index])); 00496 } 00497 00498 inline const short* CN::SubEntityVertexIndices( const EntityType this_type, 00499 const int sub_dimension, 00500 const int index, 00501 EntityType& sub_type, 00502 int& n ) 00503 { 00504 if (sub_dimension == 0) { 00505 n = 1; 00506 sub_type = MBVERTEX; 00507 return increasingInts + index; 00508 } 00509 else { 00510 const CN::ConnMap& map = mConnectivityMap[this_type][sub_dimension-1]; 00511 sub_type = map.target_type[index]; 00512 n = map.num_corners_per_sub_element[index]; 00513 return map.conn[index]; 00514 } 00515 } 00516 00518 inline void CN::SubEntityVertexIndices(const EntityType this_type, 00519 const int sub_dimension, 00520 const int index, 00521 int sub_entity_conn[]) 00522 { 00523 EntityType type; 00524 int n; 00525 const short* indices = SubEntityVertexIndices( this_type, sub_dimension, index, type, n ); 00526 std::copy( indices, indices+n, sub_entity_conn ); 00527 } 00528 00529 inline bool CN::HasMidEdgeNodes(const EntityType this_type, 00530 const int num_nodes) 00531 { 00532 const int bits = HasMidNodes( this_type, num_nodes ); 00533 return static_cast<bool>( (bits & (1<<1)) >> 1 ); 00534 } 00535 00536 inline bool CN::HasMidFaceNodes(const EntityType this_type, 00537 const int num_nodes) 00538 { 00539 const int bits = HasMidNodes( this_type, num_nodes ); 00540 return static_cast<bool>( (bits & (1<<2)) >> 2 ); 00541 } 00542 00543 inline bool CN::HasMidRegionNodes(const EntityType this_type, 00544 const int num_nodes) 00545 { 00546 const int bits = HasMidNodes( this_type, num_nodes ); 00547 return static_cast<bool>( (bits & (1<<3)) >> 3 ); 00548 } 00549 00550 inline int CN::HasMidNodes( const EntityType this_type, const int num_nodes ) 00551 { 00552 assert( (unsigned)num_nodes <= (unsigned)MAX_NODES_PER_ELEMENT ); 00553 return midNodesPerType[this_type][num_nodes]; 00554 } 00555 00556 00557 inline void CN::HasMidNodes(const EntityType this_type, const int num_nodes, 00558 int mid_nodes[4]) 00559 { 00560 const int bits = HasMidNodes( this_type, num_nodes ); 00561 mid_nodes[0] = 0; 00562 mid_nodes[1] = (bits & (1<<1)) >> 1; 00563 mid_nodes[2] = (bits & (1<<2)) >> 2; 00564 mid_nodes[3] = (bits & (1<<3)) >> 3; 00565 } 00566 00568 inline void CN::setPermutation(const EntityType t, const int dim, short int *pvec, 00569 const int num_entries, const bool is_reverse) 00570 { 00571 short int *this_vec = permuteVec[t][dim], *that_vec = revPermuteVec[t][dim]; 00572 if (is_reverse) { 00573 this_vec = revPermuteVec[t][dim]; 00574 that_vec = permuteVec[t][dim]; 00575 } 00576 00577 for (short int i = 0; i < num_entries; i++) { 00578 this_vec[i] = pvec[i]; 00579 that_vec[pvec[i]] = i; 00580 } 00581 00582 this_vec[MAX_SUB_ENTITIES] = that_vec[MAX_SUB_ENTITIES] = (short)num_entries; 00583 } 00584 00586 inline void CN::resetPermutation(const EntityType t, const int dim) 00587 { 00588 if (-1 == dim) { 00589 for (unsigned int i = 0; i < 3; i++) resetPermutation(t, i); 00590 return; 00591 } 00592 00593 for (short unsigned int i = 0; i < MAX_SUB_ENTITIES; i++) { 00594 revPermuteVec[t][dim][i] = permuteVec[t][dim][i] = i; 00595 } 00596 00597 revPermuteVec[t][dim][MAX_SUB_ENTITIES] = 00598 permuteVec[t][dim][MAX_SUB_ENTITIES] = MAX_SUB_ENTITIES+1; 00599 } 00600 00601 } // namespace moab 00602 00603 #endif