moab
CN.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines