moab
CN.cpp
Go to the documentation of this file.
00001 
00016 #include "moab/CN.hpp"
00017 #include "MBCNArrays.hpp"
00018 #include "MBCN.h"
00019 #include <assert.h>
00020 #include <string.h>
00021 
00022 namespace moab {
00023 
00024 const char *CN::entityTypeNames[] = {
00025     "Vertex",
00026     "Edge",
00027     "Tri",
00028     "Quad",
00029     "Polygon",
00030     "Tet",
00031     "Pyramid",
00032     "Prism",
00033     "Knife",
00034     "Hex",
00035     "Polyhedron",
00036     "EntitySet",
00037     "MaxType"
00038 };
00039 
00040 short int CN::numberBasis = 0;
00041 
00042 const DimensionPair CN::TypeDimensionMap[] = 
00043 {
00044     DimensionPair(MBVERTEX,   MBVERTEX), 
00045     DimensionPair(MBEDGE,     MBEDGE), 
00046     DimensionPair(MBTRI,     MBPOLYGON),
00047     DimensionPair(MBTET,     MBPOLYHEDRON),
00048     DimensionPair(MBENTITYSET, MBENTITYSET), 
00049     DimensionPair(MBMAXTYPE, MBMAXTYPE)
00050 };
00051 
00052 short CN::increasingInts[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
00053                                 10,11,12,13,14,15,16,17,18,19,
00054                                 20,21,22,23,24,25,26,27,28,29,
00055                                 30,31,32,33,34,35,36,37,38,39 };
00056 
00059 void CN::SetBasis(const int in_basis) 
00060 {
00061   numberBasis = in_basis;
00062 }
00063 
00065 EntityType CN::EntityTypeFromName(const char *name)
00066 {
00067   for (EntityType i = MBVERTEX; i < MBMAXTYPE; i++) {
00068     if (0 == strcmp(name, entityTypeNames[i]))
00069       return i;
00070   }
00071   
00072   return MBMAXTYPE;
00073 }
00074 
00075 void CN::SubEntityNodeIndices( const EntityType this_topo, 
00076                                  const int num_nodes,
00077                                  const int sub_dimension,
00078                                  const int sub_index,
00079                                  EntityType& subentity_topo,
00080                                  int& num_sub_entity_nodes,
00081                                  int sub_entity_conn[] )
00082 {
00083     // If asked for a node, the special case...
00084   if (sub_dimension == 0) {
00085     assert( sub_index < num_nodes );
00086     subentity_topo = MBVERTEX;
00087     num_sub_entity_nodes = 1;
00088     sub_entity_conn[0] = sub_index;
00089     return;
00090   }
00091   
00092   const int ho_bits = HasMidNodes( this_topo, num_nodes );
00093   subentity_topo = SubEntityType(this_topo, sub_dimension, sub_index);
00094   num_sub_entity_nodes = VerticesPerEntity(subentity_topo);
00095   const short* corners = mConnectivityMap[this_topo][sub_dimension-1].conn[sub_index];
00096   std::copy( corners, corners+num_sub_entity_nodes, sub_entity_conn );
00097   
00098   int sub_sub_corners[MAX_SUB_ENTITY_VERTICES];
00099   int side, sense, offset;
00100   for (int dim = 1; dim <= sub_dimension; ++dim) {
00101     if (!(ho_bits & (1<<dim)))
00102       continue;
00103     
00104     const short num_mid = NumSubEntities( subentity_topo, dim );
00105     for (int i = 0; i < num_mid; ++i) {
00106       const EntityType sub_sub_topo = SubEntityType( subentity_topo, dim, i );
00107       const int sub_sub_num_vert = VerticesPerEntity( sub_sub_topo );
00108       SubEntityVertexIndices( subentity_topo, dim, i, sub_sub_corners );
00109 
00110       for (int j = 0; j < sub_sub_num_vert; ++j)
00111         sub_sub_corners[j] = corners[sub_sub_corners[j]];
00112       SideNumber( this_topo, sub_sub_corners, sub_sub_num_vert, dim, side, sense, offset );
00113       sub_entity_conn[num_sub_entity_nodes++] = HONodeIndex( this_topo, num_nodes, dim, side );
00114     }
00115   }
00116 }
00117 
00118 
00127 void CN::SubEntityConn(const void *parent_conn, const EntityType parent_type,
00128                          const int sub_dimension,
00129                          const int sub_index,
00130                          void *sub_entity_conn, int &num_sub_vertices) 
00131 {
00132   static int sub_indices[MAX_SUB_ENTITY_VERTICES];
00133   
00134   SubEntityVertexIndices(parent_type, sub_dimension, sub_index, sub_indices);
00135   
00136   num_sub_vertices = VerticesPerEntity(SubEntityType(parent_type, sub_dimension, sub_index));
00137   void **parent_conn_ptr = static_cast<void **>(const_cast<void *>(parent_conn));
00138   void **sub_conn_ptr = static_cast<void **>(sub_entity_conn);
00139   for (int i = 0; i < num_sub_vertices; i++)
00140     sub_conn_ptr[i] = parent_conn_ptr[sub_indices[i]];
00141 }
00142 
00144 short int CN::AdjacentSubEntities(const EntityType this_type,
00145                               const int *source_indices,
00146                               const int num_source_indices,
00147                               const int source_dim,
00148                               const int target_dim,
00149                               std::vector<int> &index_list,
00150                               const int operation_type)
00151 {
00152     // first get all the vertex indices
00153   std::vector<int> tmp_indices;
00154   const int* it1 = source_indices;
00155 
00156   assert(source_dim >= 0 && source_dim <= 3 &&
00157          target_dim >= 0 && target_dim <= 3 &&
00158            // make sure we're not stepping off the end of the array; 
00159          ((source_dim > 0 && 
00160            *it1 < mConnectivityMap[this_type][source_dim-1].num_sub_elements) ||
00161           (source_dim == 0 && 
00162            *it1 < mConnectivityMap[this_type][Dimension(this_type)-1].num_corners_per_sub_element[0])) && 
00163          *it1 >= 0);
00164 
00165 
00166 #define MUC CN::mUpConnMap[this_type][source_dim][target_dim]
00167 
00168     // if we're looking for the vertices of a single side, return them in
00169     // the canonical ordering; otherwise, return them in sorted order
00170   if (num_source_indices == 1 && 0 == target_dim && source_dim != target_dim) {
00171 
00172       // element of mConnectivityMap should be for this type and for one
00173       // less than source_dim, which should give the connectivity of that sub element
00174     const ConnMap &cm = mConnectivityMap[this_type][source_dim-1];
00175     std::copy(cm.conn[source_indices[0]],
00176               cm.conn[source_indices[0]]+cm.num_corners_per_sub_element[source_indices[0]],
00177               std::back_inserter(index_list));
00178     return 0;
00179   }
00180               
00181     // now go through source indices, folding adjacencies into target list
00182   for (it1 = source_indices; it1 != source_indices+num_source_indices; it1++) {
00183       // *it1 is the side index
00184       // at start of iteration, index_list has the target list
00185 
00186       // if a union, or first iteration and index list was empty, copy the list
00187     if (operation_type == CN::UNION || 
00188         (it1 == source_indices && index_list.empty())) {
00189       std::copy(MUC.targets_per_source_element[*it1],
00190                 MUC.targets_per_source_element[*it1]+
00191                 MUC.num_targets_per_source_element[*it1],
00192                 std::back_inserter(index_list));
00193     }
00194     else {
00195         // else we're intersecting, and have a non-empty list; intersect with this target list
00196       tmp_indices.clear();
00197       for (int i = MUC.num_targets_per_source_element[*it1]-1; i>= 0; i--)
00198         if (std::find(index_list.begin(), index_list.end(), MUC.targets_per_source_element[*it1][i]) !=
00199             index_list.end())
00200           tmp_indices.push_back(MUC.targets_per_source_element[*it1][i]);
00201 //      std::set_intersection(MUC.targets_per_source_element[*it1],
00202 //                            MUC.targets_per_source_element[*it1]+
00203 //                            MUC.num_targets_per_source_element[*it1],
00204 //                            index_list.begin(), index_list.end(),
00205 //                            std::back_inserter(tmp_indices));
00206       index_list.swap(tmp_indices);
00207 
00208         // if we're at this point and the list is empty, the intersection will be NULL;
00209         // return if so
00210       if (index_list.empty()) return 0;
00211     }
00212   }
00213   
00214   if (operation_type == CN::UNION && num_source_indices != 1) {
00215       // need to sort then unique the list
00216     std::sort(index_list.begin(), index_list.end());
00217     index_list.erase(std::unique(index_list.begin(), index_list.end()), 
00218                      index_list.end());
00219   }
00220   
00221   return 0;
00222 }
00223 
00224 template <typename T> static 
00225 short int side_number(const T *parent_conn, 
00226                 const EntityType parent_type,
00227                 const T *child_conn,
00228                 const int child_num_verts,
00229                 const int child_dim,
00230                 int &side_no,
00231                 int &sense,
00232                 int &offset)
00233 {
00234   int parent_num_verts = CN::VerticesPerEntity(parent_type);
00235   int side_indices[8]; 
00236   assert(sizeof(side_indices)/sizeof(side_indices[0]) >= (size_t)child_num_verts);
00237   
00238   for (int i = 0; i < child_num_verts; i++) {
00239     side_indices[i] = std::find(parent_conn, parent_conn+parent_num_verts, child_conn[i]) - parent_conn;
00240     if (side_indices[i] == parent_num_verts) 
00241       return -1;
00242   }
00243   
00244   return CN::SideNumber(parent_type, &side_indices[0], child_num_verts,
00245                     child_dim, side_no, sense, offset);
00246 }
00247 
00248 short int CN::SideNumber(const EntityType parent_type, const int *parent_conn, 
00249                      const int *child_conn, const int child_num_verts,
00250                      const int child_dim,
00251                      int &side_no, int &sense, int &offset) 
00252 {
00253   return side_number(parent_conn, parent_type, child_conn, child_num_verts,
00254                      child_dim, side_no, sense, offset);
00255 }
00256 
00257 short int CN::SideNumber(const EntityType parent_type, const unsigned int *parent_conn, 
00258                      const unsigned int *child_conn, const int child_num_verts,
00259                      const int child_dim,
00260                      int &side_no, int &sense, int &offset)
00261 {
00262   return side_number(parent_conn, parent_type, child_conn, child_num_verts,
00263                      child_dim, side_no, sense, offset);
00264 }
00265 short int CN::SideNumber(const EntityType parent_type, const long *parent_conn, 
00266                      const long *child_conn, const int child_num_verts,
00267                      const int child_dim,
00268                      int &side_no, int &sense, int &offset)
00269 {
00270   return side_number(parent_conn, parent_type, child_conn, child_num_verts,
00271                      child_dim, side_no, sense, offset);
00272 }
00273 short int CN::SideNumber(const EntityType parent_type, const unsigned long *parent_conn, 
00274                      const unsigned long *child_conn, const int child_num_verts,
00275                      const int child_dim,
00276                      int &side_no, int &sense, int &offset)
00277 {
00278   return side_number(parent_conn, parent_type, child_conn, child_num_verts,
00279                      child_dim, side_no, sense, offset);
00280 }
00281 short int CN::SideNumber(const EntityType parent_type, void * const *parent_conn, 
00282                      void * const *child_conn, const int child_num_verts,
00283                      const int child_dim,
00284                      int &side_no, int &sense, int &offset)
00285 {
00286   return side_number(parent_conn, parent_type, child_conn, child_num_verts,
00287                      child_dim, side_no, sense, offset);
00288 }
00289 
00290 short int CN::SideNumber( const EntityType parent_type,
00291                       const int *child_conn_indices,
00292                       const int child_num_verts,
00293                       const int child_dim,
00294                       int &side_no,
00295                       int &sense,
00296                       int &offset )
00297 {
00298   int parent_dim = Dimension(parent_type);
00299   int parent_num_verts = VerticesPerEntity(parent_type);
00300 
00301     // degenerate case (vertex), output == input
00302   if (child_dim == 0) {
00303     if (child_num_verts != 1)
00304       return -1;
00305     side_no = *child_conn_indices;
00306     sense = offset = 0;
00307   }
00308     
00309     // given a parent and child element, find the corresponding side number
00310 
00311     // dim_diff should be -1, 0 or 1 (same dimension, one less dimension, two less, resp.)
00312   if (child_dim > parent_dim || child_dim < 0)
00313     return -1;
00314 
00315     // different types of same dimension won't be the same
00316   if (parent_dim == child_dim &&
00317       parent_num_verts != child_num_verts) {
00318     side_no = -1;
00319     sense = 0;
00320     return 0;
00321   }
00322 
00323     // loop over the sub-elements, comparing to child connectivity
00324   int sub_conn_indices[10];
00325   for (int i = 0; i < NumSubEntities(parent_type, child_dim); i++) {
00326     int sub_size = VerticesPerEntity(SubEntityType(parent_type, child_dim, i));
00327     if (sub_size != child_num_verts) 
00328       continue;
00329 
00330     SubEntityVertexIndices(parent_type, child_dim, i, sub_conn_indices);
00331     bool they_match = ConnectivityMatch(child_conn_indices, 
00332                                         sub_conn_indices, sub_size, 
00333                                         sense, offset);
00334     if (they_match) {
00335       side_no = i;
00336       return 0;
00337     }
00338   }
00339 
00340     // if we've gotten here, we don't match
00341   side_no = -1;
00342 
00343     // return value is still success, we didn't have any fatal errors or anything
00344   return 0;
00345 }
00346 
00360 short int CN::OppositeSide(const EntityType parent_type,
00361                        const int child_index,
00362                        const int child_dim,
00363                        int &opposite_index,
00364                        int &opposite_dim) 
00365 {
00366   switch (parent_type) {
00367     case MBEDGE:
00368         if (0 != child_dim) return -1;
00369         else opposite_index = 1-child_index;
00370         opposite_dim = 0;
00371         break;
00372       
00373     case MBTRI:
00374         switch (child_dim) {
00375           case 0:
00376               opposite_dim = 1;
00377               opposite_index = (child_index+1)%3;
00378               break;
00379           case 1:
00380               opposite_dim = 0;
00381               opposite_index = (child_index+2)%3;
00382               break;
00383           default:
00384               return -1;
00385         }
00386         break;
00387 
00388     case MBQUAD:
00389         switch (child_dim) {
00390           case 0:
00391           case 1:
00392               opposite_dim = child_dim;
00393               opposite_index = (child_index+2)%4;
00394               break;
00395           default:
00396               return -1;
00397         }
00398         break;
00399       
00400     case MBTET:
00401         switch (child_dim) {
00402           case 0:
00403               opposite_dim = 2;
00404               opposite_index = (child_index+1)%3 + 2*(child_index/3);
00405               break;
00406           case 1:
00407               opposite_dim = 1;
00408               opposite_index = child_index < 3 
00409                              ? 3 + (child_index + 2)%3
00410                              : (child_index + 1)%3;
00411               break;
00412           case 2:
00413               opposite_dim = 0;
00414               opposite_index = (child_index+2)%3 + child_index/3;
00415               break;
00416           default:
00417               return -1;
00418         }
00419         break;
00420     case MBHEX:
00421       opposite_dim = child_dim;
00422       switch (child_dim) {
00423         case 0:
00424           opposite_index = child_index < 4 
00425                          ? 4 + (child_index + 2) % 4
00426                          : (child_index - 2) % 4;
00427           break;
00428         case 1:
00429           opposite_index = 4*(2-child_index/4) + (child_index+2)%4;
00430           break;
00431         case 2:
00432           opposite_index = child_index < 4 
00433                          ? (child_index + 2) % 4
00434                          : 9 - child_index;
00435           break;
00436         default:
00437           return -1;
00438       }
00439       break;
00440         
00441       
00442     default:
00443         return -1;
00444   }
00445   
00446   return 0;
00447 }
00448 
00449 template <typename T> 
00450 inline bool connectivity_match( const T* conn1_i,
00451                                        const T* conn2_i,
00452                                        const int num_vertices,
00453                                        int& direct, int& offset )
00454 {
00455 
00456   bool they_match;
00457   
00458     // special test for 2 handles, since we don't want to wrap the list in this
00459     // case
00460   if (num_vertices == 2) {
00461     they_match = false;
00462     if (conn1_i[0] == conn2_i[0] && conn1_i[1] == conn2_i[1]) {
00463       direct = 1;
00464       they_match = true;
00465       offset = 0;
00466     }
00467     else if (conn1_i[0] == conn2_i[1] && conn1_i[1] == conn2_i[0]) {
00468       they_match = true;
00469       direct = -1;
00470       offset = 1;
00471     }
00472   }
00473 
00474   else {
00475     const T *iter;
00476     iter = std::find(&conn2_i[0], &conn2_i[num_vertices], conn1_i[0]);
00477     if(iter == &conn2_i[num_vertices])
00478       return false;
00479 
00480     they_match = true;
00481 
00482     offset = iter - conn2_i;
00483     int i;
00484 
00485       // first compare forward
00486     for(i = 1; i<num_vertices; ++i)
00487     {
00488       if(conn1_i[i] != conn2_i[(offset+i)%num_vertices])
00489       {
00490         they_match = false;
00491         break;
00492       }
00493     }
00494   
00495     if(they_match == true)
00496     {
00497       direct = 1;
00498       return they_match;
00499     }
00500   
00501     they_match = true;
00502   
00503       // then compare reverse
00504     for(i = 1; i<num_vertices; i++)
00505     {
00506       if(conn1_i[i] != conn2_i[(offset+num_vertices-i)%num_vertices])
00507       {
00508         they_match = false;
00509         break;
00510       }
00511     }
00512     if (they_match)
00513     {
00514       direct = -1;
00515     }
00516   }
00517 
00518   return they_match;
00519 }
00520 
00521 
00522 bool CN::ConnectivityMatch( const int *conn1_i,
00523                               const int *conn2_i,
00524                               const int num_vertices,
00525                               int &direct, int &offset )
00526 {
00527   return connectivity_match<int>(conn1_i, conn2_i, num_vertices, direct, offset );
00528 }
00529 
00530 bool CN::ConnectivityMatch( const unsigned int *conn1_i,
00531                               const unsigned int *conn2_i,
00532                               const int num_vertices,
00533                               int &direct, int &offset )
00534 {
00535   return connectivity_match<unsigned int>(conn1_i, conn2_i, num_vertices, direct, offset );
00536 }
00537 
00538 bool CN::ConnectivityMatch( const long *conn1_i,
00539                               const long *conn2_i,
00540                               const int num_vertices,
00541                               int &direct, int &offset )
00542 {
00543   return connectivity_match<long>(conn1_i, conn2_i, num_vertices, direct, offset );
00544 }
00545 
00546 bool CN::ConnectivityMatch( const unsigned long *conn1_i,
00547                               const unsigned long *conn2_i,
00548                               const int num_vertices,
00549                               int &direct, int &offset )
00550 {
00551   return connectivity_match<unsigned long>(conn1_i, conn2_i, num_vertices, direct, offset );
00552 }
00553 
00554 bool CN::ConnectivityMatch( void* const *conn1_i,
00555                               void* const *conn2_i,
00556                               const int num_vertices,
00557                               int &direct, int &offset )
00558 {
00559   return connectivity_match<void*>(conn1_i, conn2_i, num_vertices, direct, offset );
00560 }
00561 
00562 
00563 
00566 short int CN::HONodeIndex(const EntityType this_type, const int num_verts,
00567                       const int subfacet_dim, const int subfacet_index) 
00568 {
00569   int i;
00570   int has_mids[4];
00571   HasMidNodes(this_type, num_verts, has_mids);
00572 
00573     // if we have no mid nodes on the subfacet_dim, we have no index
00574   if (subfacet_index != -1 && !has_mids[subfacet_dim]) return -1;
00575 
00576     // put start index at last index (one less than the number of vertices 
00577     // plus the index basis)
00578   int index = VerticesPerEntity(this_type) - 1 + numberBasis;
00579 
00580     // for each subfacet dimension less than the target subfacet dim which has mid nodes, 
00581     // add the number of subfacets of that dimension to the index
00582   for (i = 1; i < subfacet_dim; i++)
00583     if (has_mids[i]) index += NumSubEntities(this_type, i);
00584     
00585 
00586     // now add the index of this subfacet, or one if we're asking about the entity as a whole
00587   if (subfacet_index == -1 && has_mids[subfacet_dim])
00588       // want the index of the last ho node on this subfacet
00589     index += NumSubEntities(this_type, subfacet_dim);
00590   
00591   else if (subfacet_index != -1 && has_mids[subfacet_dim])
00592     index += subfacet_index + 1 - numberBasis;
00593 
00594     // that's it
00595   return index;
00596 }
00597 
00602 void CN::HONodeParent( EntityType elem_type,
00603                          int num_verts, 
00604                          int ho_index,
00605                          int& parent_dim,
00606                          int& parent_index )
00607 {
00608     // begin with error values
00609   parent_dim = parent_index = -1;
00610      
00611     // given the number of verts and the element type, get the hasmidnodes solution
00612   int has_mids[4];
00613   HasMidNodes(elem_type, num_verts, has_mids);
00614 
00615   int index = VerticesPerEntity(elem_type)-1;
00616   const int dim = Dimension(elem_type);
00617 
00618     // keep a running sum of the ho node indices for this type of element, and stop
00619     // when you get to the dimension which has the ho node
00620   for (int i = 1; i < dim; i++) {
00621     if (has_mids[i]) {
00622       if (ho_index <= index + NumSubEntities(elem_type, i)) {
00623           // the ho_index resolves an entity of dimension i, so set the return values
00624           // and break out of the loop
00625         parent_dim = i;
00626         parent_index = ho_index - index - 1;
00627         return;
00628       }
00629       else {
00630         index += NumSubEntities(elem_type, i);
00631       } 
00632     }
00633   }
00634   
00635     // mid region node case  
00636   if( has_mids[dim] && ho_index == index+1 ) {
00637     parent_dim = dim;
00638     parent_index = 0; 
00639   }
00640 }
00641 
00642 } // namespace moab
00643 
00644 
00645 using moab::CN;
00646 using moab::EntityType;
00647 
00649 void MBCN_GetBasis(int *rval) {*rval = CN::GetBasis();}
00650   
00652 void MBCN_SetBasis(const int in_basis) {CN::SetBasis(in_basis);}
00653 
00655 void MBCN_EntityTypeName(const int this_type, char *rval, int rval_len) 
00656 {
00657   const char *rval_tmp = CN::EntityTypeName((EntityType)this_type);
00658   int rval_len_tmp = strlen(rval_tmp);
00659   rval_len_tmp = (rval_len_tmp < rval_len ? rval_len_tmp : rval_len);
00660   strncpy(rval, rval_tmp, rval_len_tmp);
00661 }
00662   
00664 void MBCN_EntityTypeFromName(const char *name, int *rval) 
00665 {
00666   *rval = CN::EntityTypeFromName(name);
00667 }
00668   
00670 void MBCN_Dimension(const int t, int *rval) 
00671 {
00672   *rval = CN::Dimension((EntityType)t);
00673 }
00674 
00676 void MBCN_VerticesPerEntity(const int t, int *rval) 
00677 {
00678   *rval = CN::VerticesPerEntity((EntityType)t);
00679 }
00680   
00682 void MBCN_NumSubEntities(const int t, const int d, int *rval) 
00683 {
00684   *rval = CN::NumSubEntities((EntityType)t, d);
00685 }
00686 
00692 void MBCN_SubEntityType(const int this_type,
00693                         const int sub_dimension,
00694                         const int index, int *rval) 
00695 
00696 {
00697   
00698   *rval = CN::SubEntityType((EntityType)this_type, sub_dimension, index);
00699 
00700 }
00701 
00702   
00708 void MBCN_SubEntityVertexIndices(const int this_type, 
00709                                  const int sub_dimension,
00710                                  const int sub_index,
00711                                  int sub_entity_conn[]) 
00712 {
00713   CN::SubEntityVertexIndices((EntityType)this_type, sub_dimension, 
00714                                sub_index, sub_entity_conn);
00715 }
00716 
00725 //  void MBCN_SubEntityConn(const void *parent_conn, const int parent_type,
00726 //                            const int sub_dimension,
00727 //                            const int sub_index,
00728 //                            void *sub_entity_conn, int &num_sub_vertices) {return CN::SubEntityConn();}
00729 
00740 void MBCN_AdjacentSubEntities(const int this_type,
00741                               const int *source_indices,
00742                               const int num_source_indices,
00743                               const int source_dim,
00744                               const int target_dim,
00745                               int *index_list,
00746                               int *num_indices,
00747                               const int operation_type, int *rval) 
00748 {
00749   std::vector<int> tmp_index_list;
00750   *rval = CN::AdjacentSubEntities((EntityType)this_type, source_indices, 
00751                                     num_source_indices, source_dim, target_dim, 
00752                                     tmp_index_list, operation_type);
00753   std::copy(tmp_index_list.begin(), tmp_index_list.end(), index_list);
00754   *num_indices = tmp_index_list.size();
00755 }
00756 
00767 void MBCN_SideNumber(const int parent_type,
00768                      const int *child_conn_indices, const int child_num_verts,
00769                      const int child_dim,
00770                      int *side_no, int *sense, int *offset) 
00771 {
00772   CN::SideNumber((EntityType)parent_type, child_conn_indices, child_num_verts, child_dim,
00773                    *side_no, *sense, *offset);
00774 }
00775 
00776 void MBCN_SideNumberInt(const int *parent_conn, const EntityType parent_type,
00777                         const int *child_conn, const int child_num_verts,
00778                         const int child_dim,
00779                         int *side_no, int *sense, int *offset) 
00780 {
00781   moab::side_number(parent_conn, parent_type, child_conn, child_num_verts, 
00782               child_dim, *side_no, *sense, *offset);
00783 }
00784 
00785 void MBCN_SideNumberUint(const unsigned int *parent_conn, const EntityType parent_type,
00786                          const unsigned int *child_conn, const int child_num_verts,
00787                          const int child_dim,
00788                          int *side_no, int *sense, int *offset)
00789 {
00790   moab::side_number(parent_conn, parent_type, child_conn, child_num_verts, 
00791               child_dim, *side_no, *sense, *offset);
00792 }
00793 
00794 void MBCN_SideNumberLong(const long *parent_conn, const EntityType parent_type,
00795                          const long *child_conn, const int child_num_verts,
00796                          const int child_dim,
00797                          int *side_no, int *sense, int *offset)
00798 {
00799   moab::side_number(parent_conn, parent_type, child_conn, child_num_verts, 
00800               child_dim, *side_no, *sense, *offset);
00801 }
00802 
00803 void MBCN_SideNumberUlong(const unsigned long *parent_conn, const EntityType parent_type,
00804                           const unsigned long *child_conn, const int child_num_verts,
00805                           const int child_dim,
00806                           int *side_no, int *sense, int *offset)
00807 {
00808   moab::side_number(parent_conn, parent_type, child_conn, child_num_verts, 
00809               child_dim, *side_no, *sense, *offset);
00810 }
00811 
00812 void MBCN_SideNumberVoid(void * const *parent_conn, const EntityType parent_type,
00813                          void * const *child_conn, const int child_num_verts,
00814                          const int child_dim,
00815                          int *side_no, int *sense, int *offset)
00816 {
00817   moab::side_number(parent_conn, parent_type, child_conn, child_num_verts, 
00818               child_dim, *side_no, *sense, *offset);
00819 }
00820 
00834 void MBCN_OppositeSide(const int parent_type,
00835                        const int child_index,
00836                        const int child_dim,
00837                        int *opposite_index,
00838                        int *opposite_dim, int *rval) 
00839 {
00840   *rval = CN::OppositeSide((EntityType)parent_type, child_index, child_dim, 
00841                              *opposite_index, *opposite_dim);
00842 }
00843 
00851 void MBCN_ConnectivityMatchInt(const int *conn1,
00852                                const int *conn2,
00853                                const int num_vertices,
00854                                int *direct, int *offset, int *rval) 
00855 {
00856   *rval = CN::ConnectivityMatch(conn1, conn2, num_vertices, 
00857                                   *direct, *offset);
00858 }
00859 
00860 void MBCN_ConnectivityMatchUint(const unsigned int *conn1,
00861                                 const unsigned int *conn2,
00862                                 const int num_vertices,
00863                                 int *direct, int *offset, int *rval) 
00864 {
00865   *rval = CN::ConnectivityMatch(conn1, conn2, num_vertices, 
00866                                   *direct, *offset);
00867 }
00868 
00869 void MBCN_ConnectivityMatchLong(const long* conn1,
00870                                 const long* conn2,
00871                                 const int num_vertices,
00872                                 int* direct, int* offset , int *rval) 
00873 {
00874   *rval = CN::ConnectivityMatch(conn1, conn2, num_vertices, 
00875                                   *direct, *offset);
00876 }
00877 
00878 void MBCN_ConnectivityMatchUlong(const unsigned long* conn1,
00879                                  const unsigned long* conn2,
00880                                  const int num_vertices,
00881                                  int *direct, int* offset , int *rval) 
00882 {
00883   *rval = CN::ConnectivityMatch(conn1, conn2, num_vertices, 
00884                                   *direct, *offset);
00885 }
00886 
00887 void MBCN_ConnectivityMatchVoid(void* const* conn1,
00888                                 void* const* conn2,
00889                                 const int num_vertices,
00890                                 int* direct, int* offset , int *rval) 
00891 {
00892   *rval = CN::ConnectivityMatch(conn1, conn2, num_vertices, 
00893                                   *direct, *offset);
00894 }
00895 
00901 void MBCN_HasMidEdgeNodes(const int this_type, 
00902                           const int num_verts, int *rval) 
00903 {
00904   *rval = CN::HasMidEdgeNodes((EntityType)this_type, num_verts);
00905 }
00906 
00912 void MBCN_HasMidFaceNodes(const int this_type, 
00913                           const int num_verts, int *rval) 
00914 {
00915   *rval = CN::HasMidFaceNodes((EntityType)this_type, num_verts);
00916 }
00917 
00923 void MBCN_HasMidRegionNodes(const int this_type, 
00924                             const int num_verts, int *rval) 
00925 {
00926   *rval = CN::HasMidRegionNodes((EntityType)this_type, num_verts);
00927 }
00928 
00935 void MBCN_HasMidNodes(const int this_type, 
00936                       const int num_verts, 
00937                       int mid_nodes[4]) 
00938 {
00939   return CN::HasMidNodes((EntityType)this_type, num_verts, mid_nodes);
00940 }
00941 
00951 void MBCN_HONodeParent( int elem_type,
00952                         int num_nodes, 
00953                         int ho_node_index,
00954                         int *parent_dim, 
00955                         int *parent_index ) 
00956 {
00957   return CN::HONodeParent((EntityType)elem_type, num_nodes, ho_node_index, 
00958                             *parent_dim, *parent_index);
00959 }
00960 
00969 void MBCN_HONodeIndex(const int this_type, const int num_verts,
00970                       const int subfacet_dim, const int subfacet_index, int *rval) 
00971 
00972 {
00973   
00974   *rval = CN::HONodeIndex((EntityType)this_type, num_verts, subfacet_dim, subfacet_index);
00975 
00976 }
00977 
00978 namespace moab {
00979 
00980 template <typename T> 
00981 inline int permute_this(EntityType t,
00982                         const int dim,
00983                         T* conn,
00984                         const int indices_per_ent,
00985                         const int num_entries) 
00986 {
00987   T tmp_conn[MAX_SUB_ENTITIES];
00988   assert(indices_per_ent <= CN::permuteVec[t][dim][MAX_SUB_ENTITIES]);
00989   if (indices_per_ent > CN::permuteVec[t][dim][MAX_SUB_ENTITIES]) return 1;
00990   short int *tvec = CN::permuteVec[t][dim];
00991   T *pvec = conn;
00992   for (int j = 0; j < num_entries; j++) {
00993     for (int i = 0; i < indices_per_ent; i++)
00994       tmp_conn[tvec[i]] = pvec[i];
00995     memcpy(pvec, tmp_conn, indices_per_ent*sizeof(T));
00996     pvec += indices_per_ent;
00997   }
00998 
00999   return 0;
01000 }
01001 
01002 template <typename T> 
01003 inline int rev_permute_this(EntityType t,
01004                             const int dim,
01005                             T* conn,
01006                             const int indices_per_ent,
01007                             const int num_entries) 
01008 {
01009   T tmp_conn[MAX_SUB_ENTITIES];
01010   assert(indices_per_ent <= CN::revPermuteVec[t][dim][MAX_SUB_ENTITIES]);
01011   if (indices_per_ent > CN::revPermuteVec[t][dim][MAX_SUB_ENTITIES]) return 1;
01012   short int *tvec = CN::revPermuteVec[t][dim];
01013   T *pvec = conn;
01014   for (int j = 0; j < num_entries; j++) {
01015     for (int i = 0; i < indices_per_ent; i++)
01016       tmp_conn[i] = pvec[tvec[i]];
01017     memcpy(pvec, tmp_conn, indices_per_ent*sizeof(T));
01018     pvec += indices_per_ent;
01019   }
01020 
01021   return 0;
01022 }
01023 
01025 inline int CN::permuteThis(const EntityType t, const int dim, int *pvec, 
01026                              const int num_indices, const int num_entries) 
01027 {return permute_this(t, dim, pvec, num_indices, num_entries);}
01028 inline int CN::permuteThis(const EntityType t, const int dim, unsigned int *pvec, 
01029                              const int num_indices, const int num_entries) 
01030 {return permute_this(t, dim, pvec, num_indices, num_entries);}
01031 inline int CN::permuteThis(const EntityType t, const int dim, long *pvec, 
01032                              const int num_indices, const int num_entries) 
01033 {return permute_this(t, dim, pvec, num_indices, num_entries);}
01034 inline int CN::permuteThis(const EntityType t, const int dim, void **pvec, 
01035                              const int num_indices, const int num_entries) 
01036 {return permute_this(t, dim, pvec, num_indices, num_entries);}
01037 
01039 inline int CN::revPermuteThis(const EntityType t, const int dim, int *pvec, 
01040                              const int num_indices, const int num_entries) 
01041 {return rev_permute_this(t, dim, pvec, num_indices, num_entries);}
01042 inline int CN::revPermuteThis(const EntityType t, const int dim, unsigned int *pvec, 
01043                              const int num_indices, const int num_entries) 
01044 {return rev_permute_this(t, dim, pvec, num_indices, num_entries);}
01045 inline int CN::revPermuteThis(const EntityType t, const int dim, long *pvec, 
01046                              const int num_indices, const int num_entries) 
01047 {return rev_permute_this(t, dim, pvec, num_indices, num_entries);}
01048 inline int CN::revPermuteThis(const EntityType t, const int dim, void **pvec, 
01049                              const int num_indices, const int num_entries) 
01050 {return rev_permute_this(t, dim, pvec, num_indices, num_entries);}
01051 
01052   
01053 } // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines