moab
|
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