MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "TestUtil.hpp" 00002 #include "moab/CN.hpp" 00003 00004 using namespace moab; 00005 00006 void test_dimension_pair(); 00007 void test_type_names(); 00008 void test_dimension(); 00009 void test_vertices_per_entity(); 00010 void test_num_sub_entities(); 00011 00012 void test_sub_entity_type_vtx(); 00013 void test_sub_entity_type_edge(); 00014 void test_sub_entity_type_tri(); 00015 void test_sub_entity_type_quad(); 00016 void test_sub_entity_type_tet(); 00017 void test_sub_entity_type_pyr(); 00018 void test_sub_entity_type_pri(); 00019 void test_sub_entity_type_knife(); 00020 void test_sub_entity_type_hex(); 00021 00022 void test_sub_entity_indices_vtx(); 00023 void test_sub_entity_indices_edge(); 00024 void test_sub_entity_indices_tri(); 00025 void test_sub_entity_indices_quad(); 00026 void test_sub_entity_indices_tet(); 00027 void test_sub_entity_indices_pyr(); 00028 void test_sub_entity_indices_pri(); 00029 void test_sub_entity_indices_hex(); 00030 00031 void test_side_number_tri(); 00032 void test_side_number_quad(); 00033 void test_side_number_tet(); 00034 void test_side_number_pyr(); 00035 void test_side_number_pri(); 00036 void test_side_number_hex(); 00037 00038 void test_opposite_side_tri(); 00039 void test_opposite_side_quad(); 00040 void test_opposite_side_tet(); 00041 void test_opposite_side_hex(); 00042 00043 void test_has_mid_nodes( EntityType type ); 00044 void test_has_mid_nodes_edge() 00045 { 00046 test_has_mid_nodes( MBEDGE ); 00047 } 00048 void test_has_mid_nodes_tri() 00049 { 00050 test_has_mid_nodes( MBTRI ); 00051 } 00052 void test_has_mid_nodes_quad() 00053 { 00054 test_has_mid_nodes( MBQUAD ); 00055 } 00056 void test_has_mid_nodes_tet() 00057 { 00058 test_has_mid_nodes( MBTET ); 00059 } 00060 void test_has_mid_nodes_pyr() 00061 { 00062 test_has_mid_nodes( MBPYRAMID ); 00063 } 00064 void test_has_mid_nodes_pri() 00065 { 00066 test_has_mid_nodes( MBPRISM ); 00067 } 00068 void test_has_mid_nodes_knife() 00069 { 00070 test_has_mid_nodes( MBKNIFE ); 00071 } 00072 void test_has_mid_nodes_hex() 00073 { 00074 test_has_mid_nodes( MBHEX ); 00075 } 00076 00077 void test_ho_node_parent(); 00078 void test_ho_node_index(); 00079 00080 void test_sub_entity_nodes( EntityType parent, int sub_dimension ); 00081 void test_sub_entity_nodes( EntityType parent, int num_nodes, int sub_dimension ); 00082 void test_sub_entity_nodes_tri_edges() 00083 { 00084 test_sub_entity_nodes( MBTRI, 1 ); 00085 } 00086 void test_sub_entity_nodes_quad_edges() 00087 { 00088 test_sub_entity_nodes( MBQUAD, 1 ); 00089 } 00090 void test_sub_entity_nodes_tet_edges() 00091 { 00092 test_sub_entity_nodes( MBTET, 1 ); 00093 } 00094 void test_sub_entity_nodes_tet_faces() 00095 { 00096 test_sub_entity_nodes( MBTET, 2 ); 00097 } 00098 void test_sub_entity_nodes_pyr_edges() 00099 { 00100 test_sub_entity_nodes( MBPYRAMID, 1 ); 00101 } 00102 void test_sub_entity_nodes_pyr_faces() 00103 { 00104 test_sub_entity_nodes( MBPYRAMID, 2 ); 00105 } 00106 void test_sub_entity_nodes_pri_edges() 00107 { 00108 test_sub_entity_nodes( MBPRISM, 1 ); 00109 } 00110 void test_sub_entity_nodes_pri_faces() 00111 { 00112 test_sub_entity_nodes( MBPRISM, 2 ); 00113 } 00114 void test_sub_entity_nodes_kni_edges() 00115 { 00116 test_sub_entity_nodes( MBKNIFE, 1 ); 00117 } 00118 void test_sub_entity_nodes_kni_faces() 00119 { 00120 test_sub_entity_nodes( MBKNIFE, 2 ); 00121 } 00122 void test_sub_entity_nodes_hex_edges() 00123 { 00124 test_sub_entity_nodes( MBHEX, 1 ); 00125 } 00126 void test_sub_entity_nodes_hex_faces() 00127 { 00128 test_sub_entity_nodes( MBHEX, 2 ); 00129 } 00130 void prism_issue(); 00131 void test_wedges(); 00132 00133 int main() 00134 { 00135 int result = 0; 00136 result += RUN_TEST( test_dimension_pair ); 00137 result += RUN_TEST( test_type_names ); 00138 result += RUN_TEST( test_dimension ); 00139 result += RUN_TEST( test_vertices_per_entity ); 00140 result += RUN_TEST( test_num_sub_entities ); 00141 00142 result += RUN_TEST( test_sub_entity_type_vtx ); 00143 result += RUN_TEST( test_sub_entity_type_edge ); 00144 result += RUN_TEST( test_sub_entity_type_tri ); 00145 result += RUN_TEST( test_sub_entity_type_quad ); 00146 result += RUN_TEST( test_sub_entity_type_tet ); 00147 result += RUN_TEST( test_sub_entity_type_pyr ); 00148 result += RUN_TEST( test_sub_entity_type_pri ); 00149 result += RUN_TEST( test_sub_entity_type_knife ); 00150 result += RUN_TEST( test_sub_entity_type_hex ); 00151 00152 result += RUN_TEST( test_sub_entity_indices_vtx ); 00153 result += RUN_TEST( test_sub_entity_indices_edge ); 00154 result += RUN_TEST( test_sub_entity_indices_tri ); 00155 result += RUN_TEST( test_sub_entity_indices_quad ); 00156 result += RUN_TEST( test_sub_entity_indices_tet ); 00157 result += RUN_TEST( test_sub_entity_indices_pyr ); 00158 result += RUN_TEST( test_sub_entity_indices_pri ); 00159 result += RUN_TEST( test_sub_entity_indices_hex ); 00160 00161 result += RUN_TEST( test_side_number_tri ); 00162 result += RUN_TEST( test_side_number_quad ); 00163 result += RUN_TEST( test_side_number_tet ); 00164 result += RUN_TEST( test_side_number_pyr ); 00165 result += RUN_TEST( test_side_number_pri ); 00166 result += RUN_TEST( test_side_number_hex ); 00167 00168 result += RUN_TEST( test_opposite_side_tri ); 00169 result += RUN_TEST( test_opposite_side_quad ); 00170 result += RUN_TEST( test_opposite_side_tet ); 00171 result += RUN_TEST( test_opposite_side_hex ); 00172 00173 result += RUN_TEST( test_has_mid_nodes_edge ); 00174 result += RUN_TEST( test_has_mid_nodes_tri ); 00175 result += RUN_TEST( test_has_mid_nodes_quad ); 00176 result += RUN_TEST( test_has_mid_nodes_tet ); 00177 result += RUN_TEST( test_has_mid_nodes_pyr ); 00178 result += RUN_TEST( test_has_mid_nodes_pri ); 00179 result += RUN_TEST( test_has_mid_nodes_knife ); 00180 result += RUN_TEST( test_has_mid_nodes_hex ); 00181 00182 result += RUN_TEST( test_sub_entity_nodes_tri_edges ); 00183 result += RUN_TEST( test_sub_entity_nodes_quad_edges ); 00184 result += RUN_TEST( test_sub_entity_nodes_tet_edges ); 00185 result += RUN_TEST( test_sub_entity_nodes_tet_faces ); 00186 result += RUN_TEST( test_sub_entity_nodes_pyr_edges ); 00187 result += RUN_TEST( test_sub_entity_nodes_pyr_faces ); 00188 result += RUN_TEST( test_sub_entity_nodes_pri_edges ); 00189 result += RUN_TEST( test_sub_entity_nodes_pri_faces ); 00190 result += RUN_TEST( test_sub_entity_nodes_kni_edges ); 00191 result += RUN_TEST( test_sub_entity_nodes_kni_faces ); 00192 result += RUN_TEST( test_sub_entity_nodes_hex_edges ); 00193 result += RUN_TEST( test_sub_entity_nodes_hex_faces ); 00194 00195 result += RUN_TEST( test_ho_node_parent ); 00196 result += RUN_TEST( test_ho_node_index ); 00197 result += RUN_TEST( prism_issue ); 00198 result += RUN_TEST( test_wedges ); 00199 return result; 00200 } 00201 00202 const EntityType elem_types[] = { MBTRI, MBQUAD, MBTET, MBPYRAMID, MBPRISM, MBHEX, MBMAXTYPE }; 00203 // const int num_elem_types = sizeof(elem_types)/sizeof(elem_types[0]) - 1; 00204 00205 void test_dimension_pair() 00206 { 00207 DimensionPair dp; 00208 00209 dp = CN::TypeDimensionMap[0]; 00210 CHECK_EQUAL( MBVERTEX, dp.first ); 00211 CHECK_EQUAL( MBVERTEX, dp.second ); 00212 00213 dp = CN::TypeDimensionMap[1]; 00214 CHECK_EQUAL( MBEDGE, dp.first ); 00215 CHECK_EQUAL( MBEDGE, dp.second ); 00216 00217 dp = CN::TypeDimensionMap[2]; 00218 CHECK_EQUAL( MBTRI, dp.first ); 00219 CHECK_EQUAL( MBPOLYGON, dp.second ); 00220 00221 dp = CN::TypeDimensionMap[3]; 00222 CHECK_EQUAL( MBTET, dp.first ); 00223 CHECK_EQUAL( MBPOLYHEDRON, dp.second ); 00224 } 00225 00226 void test_type_names() 00227 { 00228 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00229 { 00230 const char* name = CN::EntityTypeName( t ); 00231 CHECK_EQUAL( t, CN::EntityTypeFromName( name ) ); 00232 } 00233 } 00234 00235 void test_dimension() 00236 { 00237 CHECK_EQUAL( 0, CN::Dimension( MBVERTEX ) ); 00238 CHECK_EQUAL( 1, CN::Dimension( MBEDGE ) ); 00239 CHECK_EQUAL( 2, CN::Dimension( MBTRI ) ); 00240 CHECK_EQUAL( 2, CN::Dimension( MBQUAD ) ); 00241 CHECK_EQUAL( 2, CN::Dimension( MBPOLYGON ) ); 00242 CHECK_EQUAL( 3, CN::Dimension( MBTET ) ); 00243 CHECK_EQUAL( 3, CN::Dimension( MBPYRAMID ) ); 00244 CHECK_EQUAL( 3, CN::Dimension( MBPRISM ) ); 00245 CHECK_EQUAL( 3, CN::Dimension( MBKNIFE ) ); 00246 CHECK_EQUAL( 3, CN::Dimension( MBHEX ) ); 00247 CHECK_EQUAL( 3, CN::Dimension( MBPOLYHEDRON ) ); 00248 } 00249 00250 void test_vertices_per_entity() 00251 { 00252 CHECK_EQUAL( 1, CN::VerticesPerEntity( MBVERTEX ) ); 00253 CHECK_EQUAL( 2, CN::VerticesPerEntity( MBEDGE ) ); 00254 CHECK_EQUAL( 3, CN::VerticesPerEntity( MBTRI ) ); 00255 CHECK_EQUAL( 4, CN::VerticesPerEntity( MBQUAD ) ); 00256 CHECK_EQUAL( 4, CN::VerticesPerEntity( MBTET ) ); 00257 CHECK_EQUAL( 5, CN::VerticesPerEntity( MBPYRAMID ) ); 00258 CHECK_EQUAL( 6, CN::VerticesPerEntity( MBPRISM ) ); 00259 CHECK_EQUAL( 7, CN::VerticesPerEntity( MBKNIFE ) ); 00260 CHECK_EQUAL( 8, CN::VerticesPerEntity( MBHEX ) ); 00261 } 00262 00263 void test_num_sub_entities() 00264 { 00265 CHECK_EQUAL( 1, CN::NumSubEntities( MBVERTEX, 0 ) ); 00266 00267 CHECK_EQUAL( 2, CN::NumSubEntities( MBEDGE, 0 ) ); 00268 CHECK_EQUAL( 1, CN::NumSubEntities( MBEDGE, 1 ) ); 00269 00270 CHECK_EQUAL( 3, CN::NumSubEntities( MBTRI, 0 ) ); 00271 CHECK_EQUAL( 3, CN::NumSubEntities( MBTRI, 1 ) ); 00272 CHECK_EQUAL( 1, CN::NumSubEntities( MBTRI, 2 ) ); 00273 00274 CHECK_EQUAL( 4, CN::NumSubEntities( MBQUAD, 0 ) ); 00275 CHECK_EQUAL( 4, CN::NumSubEntities( MBQUAD, 1 ) ); 00276 CHECK_EQUAL( 1, CN::NumSubEntities( MBQUAD, 2 ) ); 00277 00278 CHECK_EQUAL( 4, CN::NumSubEntities( MBTET, 0 ) ); 00279 CHECK_EQUAL( 6, CN::NumSubEntities( MBTET, 1 ) ); 00280 CHECK_EQUAL( 4, CN::NumSubEntities( MBTET, 2 ) ); 00281 00282 CHECK_EQUAL( 5, CN::NumSubEntities( MBPYRAMID, 0 ) ); 00283 CHECK_EQUAL( 8, CN::NumSubEntities( MBPYRAMID, 1 ) ); 00284 CHECK_EQUAL( 5, CN::NumSubEntities( MBPYRAMID, 2 ) ); 00285 00286 CHECK_EQUAL( 6, CN::NumSubEntities( MBPRISM, 0 ) ); 00287 CHECK_EQUAL( 9, CN::NumSubEntities( MBPRISM, 1 ) ); 00288 CHECK_EQUAL( 5, CN::NumSubEntities( MBPRISM, 2 ) ); 00289 00290 CHECK_EQUAL( 7, CN::NumSubEntities( MBKNIFE, 0 ) ); 00291 CHECK_EQUAL( 10, CN::NumSubEntities( MBKNIFE, 1 ) ); 00292 CHECK_EQUAL( 5, CN::NumSubEntities( MBKNIFE, 2 ) ); 00293 00294 CHECK_EQUAL( 8, CN::NumSubEntities( MBHEX, 0 ) ); 00295 CHECK_EQUAL( 12, CN::NumSubEntities( MBHEX, 1 ) ); 00296 CHECK_EQUAL( 6, CN::NumSubEntities( MBHEX, 2 ) ); 00297 } 00298 00299 void do_test_sub_entity_type_2d( EntityType type ) 00300 { 00301 for( int j = 0; j < CN::VerticesPerEntity( type ); ++j ) 00302 { 00303 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( type, 0, j ) ); 00304 CHECK_EQUAL( MBEDGE, CN::SubEntityType( type, 1, j ) ); 00305 } 00306 CHECK_EQUAL( type, CN::SubEntityType( type, 2, 0 ) ); 00307 } 00308 00309 void do_test_sub_entity_type_3d( EntityType type, int num_faces, const EntityType* face_types ) 00310 { 00311 for( int j = 0; j < CN::VerticesPerEntity( type ); ++j ) 00312 { 00313 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( type, 0, j ) ); 00314 } 00315 00316 for( int j = 0; j < CN::NumSubEntities( type, 1 ); ++j ) 00317 { 00318 CHECK_EQUAL( MBEDGE, CN::SubEntityType( type, 1, j ) ); 00319 } 00320 00321 for( int j = 0; j < num_faces; ++j ) 00322 { 00323 EntityType sub_type = CN::SubEntityType( type, 2, j ); 00324 CHECK_EQUAL( face_types[j], sub_type ); 00325 } 00326 00327 CHECK_EQUAL( type, CN::SubEntityType( type, 3, 0 ) ); 00328 } 00329 00330 void test_sub_entity_type_vtx() 00331 { 00332 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBVERTEX, 0, 0 ) ); 00333 } 00334 00335 void test_sub_entity_type_edge() 00336 { 00337 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBEDGE, 0, 0 ) ); 00338 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBEDGE, 0, 1 ) ); 00339 CHECK_EQUAL( MBEDGE, CN::SubEntityType( MBEDGE, 1, 0 ) ); 00340 } 00341 00342 void test_sub_entity_type_tri() 00343 { 00344 do_test_sub_entity_type_2d( MBTRI ); 00345 } 00346 00347 void test_sub_entity_type_quad() 00348 { 00349 do_test_sub_entity_type_2d( MBQUAD ); 00350 } 00351 00352 void test_sub_entity_type_tet() 00353 { 00354 const EntityType types[] = { MBTRI, MBTRI, MBTRI, MBTRI }; 00355 do_test_sub_entity_type_3d( MBTET, sizeof( types ) / sizeof( types[0] ), types ); 00356 } 00357 00358 void test_sub_entity_type_pyr() 00359 { 00360 const EntityType types[] = { MBTRI, MBTRI, MBTRI, MBTRI, MBQUAD }; 00361 do_test_sub_entity_type_3d( MBPYRAMID, sizeof( types ) / sizeof( types[0] ), types ); 00362 } 00363 00364 void test_sub_entity_type_pri() 00365 { 00366 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBTRI, MBTRI }; 00367 do_test_sub_entity_type_3d( MBPRISM, sizeof( types ) / sizeof( types[0] ), types ); 00368 } 00369 00370 void test_sub_entity_type_knife() 00371 { 00372 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD }; 00373 do_test_sub_entity_type_3d( MBKNIFE, sizeof( types ) / sizeof( types[0] ), types ); 00374 } 00375 00376 void test_sub_entity_type_hex() 00377 { 00378 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD }; 00379 do_test_sub_entity_type_3d( MBHEX, sizeof( types ) / sizeof( types[0] ), types ); 00380 } 00381 00382 void test_0d_sub_entity_indices( EntityType type, int num_vtx ) 00383 { 00384 for( int i = 0; i < num_vtx; ++i ) 00385 { 00386 // zero input array 00387 int indices[2] = { 0, -100 }; 00388 // check correct results 00389 CN::SubEntityVertexIndices( type, 0, i, indices ); 00390 CHECK_EQUAL( i, indices[0] ); 00391 // check didn't write past end of array 00392 CHECK_EQUAL( -100, indices[1] ); 00393 } 00394 } 00395 00396 void test_1d_sub_entity_indices( EntityType type, int num_edges, const int ( *edge_indices )[2] ) 00397 { 00398 for( int i = 0; i < num_edges; ++i ) 00399 { 00400 // zero input array 00401 int indices[3] = { 0, 0, -99 }; 00402 // check correct results 00403 CN::SubEntityVertexIndices( type, 1, i, indices ); 00404 if( edge_indices[i][0] == indices[0] ) 00405 { 00406 CHECK_EQUAL( edge_indices[i][1], indices[1] ); 00407 } 00408 else 00409 { 00410 CHECK_EQUAL( edge_indices[i][0], indices[1] ); 00411 CHECK_EQUAL( edge_indices[i][1], indices[0] ); 00412 } 00413 // check didn't write past end of array 00414 CHECK_EQUAL( -99, indices[2] ); 00415 } 00416 } 00417 00418 void test_2d_sub_entity_indices( EntityType type, int num_faces, const int ( *face_indices )[5] ) 00419 { 00420 for( int i = 0; i < num_faces; ++i ) 00421 { 00422 // zero input array 00423 int indices[5] = { 0, 0, 0, -99, -99 }; 00424 // check correct results 00425 CN::SubEntityVertexIndices( type, 2, i, indices ); 00426 const int num_vtx = face_indices[i][0]; 00427 if( num_vtx != 3 ) CHECK_EQUAL( 4, num_vtx ); 00428 const int* exp_index = face_indices[i] + 1; 00429 int off = std::find( indices, indices + num_vtx, exp_index[0] ) - indices; 00430 CHECK( off < num_vtx ); 00431 /* Expect faces to be ordered such that CCW normal is outwards 00432 * 00433 bool reverse = indices[(off+num_vtx-1)%num_vtx] == exp_index[1]; 00434 if (reverse) { 00435 CHECK_EQUAL( exp_index[1], indices[(off+num_vtx-1)%num_vtx] ); 00436 CHECK_EQUAL( exp_index[2], indices[(off+num_vtx-2)%num_vtx] ); 00437 if (num_vtx == 4) 00438 CHECK_EQUAL( exp_index[3], indices[(off+num_vtx-3)%num_vtx] ); 00439 } 00440 else { 00441 */ 00442 CHECK_EQUAL( exp_index[1], indices[( off + 1 ) % num_vtx] ); 00443 CHECK_EQUAL( exp_index[2], indices[( off + 2 ) % num_vtx] ); 00444 if( num_vtx == 4 ) CHECK_EQUAL( exp_index[3], indices[( off + 3 ) % num_vtx] ); 00445 /* 00446 } 00447 */ 00448 00449 // check didn't write past end of array 00450 if( num_vtx == 3 ) CHECK_EQUAL( -99, indices[3] ); 00451 CHECK_EQUAL( -99, indices[4] ); 00452 } 00453 } 00454 00455 void test_elem_as_sub_entity( EntityType type, int dim, int num_vertices ) 00456 { 00457 int indices[9] = { -2, -2, -2, -2, -2, -2, -2, -2, -2 }; 00458 CN::SubEntityVertexIndices( type, dim, 0, indices ); 00459 for( int i = 0; i < num_vertices; ++i ) 00460 CHECK_EQUAL( i, indices[i] ); 00461 // make sure didn't write past end 00462 CHECK_EQUAL( -2, indices[num_vertices] ); 00463 } 00464 00465 void test_sub_entity_indices_vtx() 00466 { 00467 test_elem_as_sub_entity( MBVERTEX, 0, 1 ); 00468 } 00469 00470 void test_sub_entity_indices_edge() 00471 { 00472 test_0d_sub_entity_indices( MBEDGE, 2 ); 00473 test_elem_as_sub_entity( MBEDGE, 1, 2 ); 00474 } 00475 00476 void test_sub_entity_indices_tri() 00477 { 00478 const int edges[3][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 } }; 00479 test_0d_sub_entity_indices( MBTRI, 3 ); 00480 test_1d_sub_entity_indices( MBTRI, 3, edges ); 00481 test_elem_as_sub_entity( MBTRI, 2, 3 ); 00482 } 00483 00484 void test_sub_entity_indices_quad() 00485 { 00486 const int edges[4][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 } }; 00487 test_0d_sub_entity_indices( MBQUAD, 4 ); 00488 test_1d_sub_entity_indices( MBQUAD, 4, edges ); 00489 test_elem_as_sub_entity( MBQUAD, 2, 4 ); 00490 } 00491 00492 void test_sub_entity_indices_tet() 00493 { 00494 const EntityType type = MBTET; 00495 const int num_vtx = 4; 00496 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 } }; 00497 const int faces[][5] = { { 3, 0, 1, 3, 0 }, { 3, 1, 2, 3, 0 }, { 3, 2, 0, 3, 0 }, { 3, 2, 1, 0, 0 } }; 00498 test_0d_sub_entity_indices( type, num_vtx ); 00499 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00500 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00501 test_elem_as_sub_entity( type, 3, num_vtx ); 00502 } 00503 00504 void test_sub_entity_indices_pyr() 00505 { 00506 const EntityType type = MBPYRAMID; 00507 const int num_vtx = 5; 00508 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 }, { 2, 4 }, { 3, 4 } }; 00509 const int faces[][5] = { 00510 { 3, 0, 1, 4, 0 }, { 3, 1, 2, 4, 0 }, { 3, 2, 3, 4, 0 }, { 3, 3, 0, 4, 0 }, { 4, 3, 2, 1, 0 } }; 00511 test_0d_sub_entity_indices( type, num_vtx ); 00512 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00513 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00514 test_elem_as_sub_entity( type, 3, num_vtx ); 00515 } 00516 00517 void test_sub_entity_indices_pri() 00518 { 00519 const EntityType type = MBPRISM; 00520 const int num_vtx = 6; 00521 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 4 }, { 4, 5 }, { 5, 3 } }; 00522 const int faces[][5] = { 00523 { 4, 0, 1, 4, 3 }, { 4, 1, 2, 5, 4 }, { 4, 2, 0, 3, 5 }, { 3, 2, 1, 0, 0 }, { 3, 3, 4, 5, 0 } }; 00524 test_0d_sub_entity_indices( type, num_vtx ); 00525 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00526 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00527 test_elem_as_sub_entity( type, 3, num_vtx ); 00528 } 00529 00530 void test_sub_entity_indices_hex() 00531 { 00532 const EntityType type = MBHEX; 00533 const int num_vtx = 8; 00534 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 5 }, 00535 { 2, 6 }, { 3, 7 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 } }; 00536 const int faces[][5] = { { 4, 0, 1, 5, 4 }, { 4, 1, 2, 6, 5 }, { 4, 2, 3, 7, 6 }, 00537 { 4, 3, 0, 4, 7 }, { 4, 3, 2, 1, 0 }, { 4, 4, 5, 6, 7 } }; 00538 test_0d_sub_entity_indices( type, num_vtx ); 00539 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00540 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00541 test_elem_as_sub_entity( type, 3, num_vtx ); 00542 } 00543 00544 static void do_test_side_number_1d( EntityType type, int idx ) 00545 { 00546 // define a random handle list 00547 const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 }; 00548 // get side indices 00549 int side_idx[4] = { 0, 0 }; 00550 CN::SubEntityVertexIndices( type, 1, idx, side_idx ); 00551 00552 // "reversed" and "offset" are the same thing for edges. 00553 int side_conn[2] = { elem_verts[side_idx[0]], elem_verts[side_idx[1]] }; 00554 int rev_conn[2] = { elem_verts[side_idx[1]], elem_verts[side_idx[0]] }; 00555 int result_side = -100, result_sense = -100, result_offset = -100; 00556 int err = CN::SideNumber( type, elem_verts, side_conn, 2, 1, result_side, result_sense, result_offset ); 00557 CHECK_EQUAL( 0, err ); 00558 CHECK_EQUAL( idx, result_side ); 00559 CHECK_EQUAL( 1, result_sense ); 00560 CHECK_EQUAL( 0, result_offset ); 00561 err = CN::SideNumber( type, elem_verts, rev_conn, 2, 1, result_side, result_sense, result_offset ); 00562 CHECK_EQUAL( 0, err ); 00563 CHECK_EQUAL( idx, result_side ); 00564 CHECK( result_offset == 1 || result_sense == -1 ); 00565 } 00566 00567 static void do_test_side_number_2d( EntityType type, int idx ) 00568 { 00569 // define a random handle list 00570 const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 }; 00571 // get side indices 00572 const int side_size = CN::VerticesPerEntity( CN::SubEntityType( type, 2, idx ) ); 00573 int side_idx[4] = { 0, 0, 0, 0 }; 00574 CN::SubEntityVertexIndices( type, 2, idx, side_idx ); 00575 00576 // for each possible forward or reverse offset 00577 for( int rev = -1; rev < 2; rev += 2 ) 00578 { 00579 for( int off = 0; off < side_size; ++off ) 00580 { 00581 int side_conn[4]; 00582 side_conn[3] = 0; 00583 for( int i = 0; i < side_size; ++i ) 00584 side_conn[( side_size + rev * i ) % side_size] = elem_verts[side_idx[( i + off ) % side_size]]; 00585 00586 int result_side = -100, result_sense = -100, result_offset = -100; 00587 int err = 00588 CN::SideNumber( type, elem_verts, side_conn, side_size, 2, result_side, result_sense, result_offset ); 00589 CHECK_EQUAL( 0, err ); 00590 CHECK_EQUAL( idx, result_side ); 00591 CHECK_EQUAL( rev, result_sense ); 00592 CHECK_EQUAL( off, result_offset ); 00593 } 00594 } 00595 } 00596 00597 void test_side_number_tri() 00598 { 00599 for( int side = 0; side < 3; ++side ) 00600 do_test_side_number_1d( MBTRI, side ); 00601 } 00602 00603 void test_side_number_quad() 00604 { 00605 for( int side = 0; side < 4; ++side ) 00606 do_test_side_number_1d( MBQUAD, side ); 00607 } 00608 00609 void test_side_number_tet() 00610 { 00611 for( int edge = 0; edge < 6; ++edge ) 00612 do_test_side_number_1d( MBTET, edge ); 00613 for( int face = 0; face < 4; ++face ) 00614 do_test_side_number_2d( MBTET, face ); 00615 } 00616 00617 void test_side_number_pyr() 00618 { 00619 for( int edge = 0; edge < 8; ++edge ) 00620 do_test_side_number_1d( MBPYRAMID, edge ); 00621 for( int face = 0; face < 5; ++face ) 00622 do_test_side_number_2d( MBPYRAMID, face ); 00623 } 00624 00625 void test_side_number_pri() 00626 { 00627 for( int edge = 0; edge < 9; ++edge ) 00628 do_test_side_number_1d( MBPRISM, edge ); 00629 for( int face = 0; face < 5; ++face ) 00630 do_test_side_number_2d( MBPRISM, face ); 00631 } 00632 00633 void test_side_number_hex() 00634 { 00635 for( int edge = 0; edge < 12; ++edge ) 00636 do_test_side_number_1d( MBHEX, edge ); 00637 for( int face = 0; face < 6; ++face ) 00638 do_test_side_number_2d( MBHEX, face ); 00639 } 00640 00641 void test_opposite_side_tri() 00642 { 00643 int idx, dim, err; 00644 err = CN::OppositeSide( MBTRI, 0, 0, idx, dim ); 00645 CHECK_EQUAL( 0, err ); 00646 CHECK_EQUAL( 1, dim ); 00647 CHECK_EQUAL( 1, idx ); 00648 err = CN::OppositeSide( MBTRI, 1, 0, idx, dim ); 00649 CHECK_EQUAL( 0, err ); 00650 CHECK_EQUAL( 1, dim ); 00651 CHECK_EQUAL( 2, idx ); 00652 err = CN::OppositeSide( MBTRI, 2, 0, idx, dim ); 00653 CHECK_EQUAL( 0, err ); 00654 CHECK_EQUAL( 1, dim ); 00655 CHECK_EQUAL( 0, idx ); 00656 err = CN::OppositeSide( MBTRI, 0, 1, idx, dim ); 00657 CHECK_EQUAL( 0, err ); 00658 CHECK_EQUAL( 0, dim ); 00659 CHECK_EQUAL( 2, idx ); 00660 err = CN::OppositeSide( MBTRI, 1, 1, idx, dim ); 00661 CHECK_EQUAL( 0, err ); 00662 CHECK_EQUAL( 0, dim ); 00663 CHECK_EQUAL( 0, idx ); 00664 err = CN::OppositeSide( MBTRI, 2, 1, idx, dim ); 00665 CHECK_EQUAL( 0, err ); 00666 CHECK_EQUAL( 0, dim ); 00667 CHECK_EQUAL( 1, idx ); 00668 } 00669 00670 void test_opposite_side_quad() 00671 { 00672 int idx, dim, err; 00673 err = CN::OppositeSide( MBQUAD, 0, 0, idx, dim ); 00674 CHECK_EQUAL( 0, err ); 00675 CHECK_EQUAL( 0, dim ); 00676 CHECK_EQUAL( 2, idx ); 00677 err = CN::OppositeSide( MBQUAD, 1, 0, idx, dim ); 00678 CHECK_EQUAL( 0, err ); 00679 CHECK_EQUAL( 0, dim ); 00680 CHECK_EQUAL( 3, idx ); 00681 err = CN::OppositeSide( MBQUAD, 2, 0, idx, dim ); 00682 CHECK_EQUAL( 0, err ); 00683 CHECK_EQUAL( 0, dim ); 00684 CHECK_EQUAL( 0, idx ); 00685 err = CN::OppositeSide( MBQUAD, 3, 0, idx, dim ); 00686 CHECK_EQUAL( 0, err ); 00687 CHECK_EQUAL( 0, dim ); 00688 CHECK_EQUAL( 1, idx ); 00689 00690 err = CN::OppositeSide( MBQUAD, 0, 1, idx, dim ); 00691 CHECK_EQUAL( 0, err ); 00692 CHECK_EQUAL( 1, dim ); 00693 CHECK_EQUAL( 2, idx ); 00694 err = CN::OppositeSide( MBQUAD, 1, 1, idx, dim ); 00695 CHECK_EQUAL( 0, err ); 00696 CHECK_EQUAL( 1, dim ); 00697 CHECK_EQUAL( 3, idx ); 00698 err = CN::OppositeSide( MBQUAD, 2, 1, idx, dim ); 00699 CHECK_EQUAL( 0, err ); 00700 CHECK_EQUAL( 1, dim ); 00701 CHECK_EQUAL( 0, idx ); 00702 err = CN::OppositeSide( MBQUAD, 3, 1, idx, dim ); 00703 CHECK_EQUAL( 0, err ); 00704 CHECK_EQUAL( 1, dim ); 00705 CHECK_EQUAL( 1, idx ); 00706 } 00707 00708 void test_opposite_side_tet() 00709 { 00710 int idx, dim, err; 00711 00712 err = CN::OppositeSide( MBTET, 0, 0, idx, dim ); 00713 CHECK_EQUAL( 0, err ); 00714 CHECK_EQUAL( 2, dim ); 00715 CHECK_EQUAL( 1, idx ); 00716 err = CN::OppositeSide( MBTET, 1, 0, idx, dim ); 00717 CHECK_EQUAL( 0, err ); 00718 CHECK_EQUAL( 2, dim ); 00719 CHECK_EQUAL( 2, idx ); 00720 err = CN::OppositeSide( MBTET, 2, 0, idx, dim ); 00721 CHECK_EQUAL( 0, err ); 00722 CHECK_EQUAL( 2, dim ); 00723 CHECK_EQUAL( 0, idx ); 00724 err = CN::OppositeSide( MBTET, 3, 0, idx, dim ); 00725 CHECK_EQUAL( 0, err ); 00726 CHECK_EQUAL( 2, dim ); 00727 CHECK_EQUAL( 3, idx ); 00728 00729 err = CN::OppositeSide( MBTET, 0, 2, idx, dim ); 00730 CHECK_EQUAL( 0, err ); 00731 CHECK_EQUAL( 0, dim ); 00732 CHECK_EQUAL( 2, idx ); 00733 err = CN::OppositeSide( MBTET, 1, 2, idx, dim ); 00734 CHECK_EQUAL( 0, err ); 00735 CHECK_EQUAL( 0, dim ); 00736 CHECK_EQUAL( 0, idx ); 00737 err = CN::OppositeSide( MBTET, 2, 2, idx, dim ); 00738 CHECK_EQUAL( 0, err ); 00739 CHECK_EQUAL( 0, dim ); 00740 CHECK_EQUAL( 1, idx ); 00741 err = CN::OppositeSide( MBTET, 3, 2, idx, dim ); 00742 CHECK_EQUAL( 0, err ); 00743 CHECK_EQUAL( 0, dim ); 00744 CHECK_EQUAL( 3, idx ); 00745 00746 err = CN::OppositeSide( MBTET, 0, 1, idx, dim ); 00747 CHECK_EQUAL( 0, err ); 00748 CHECK_EQUAL( 1, dim ); 00749 CHECK_EQUAL( 5, idx ); 00750 err = CN::OppositeSide( MBTET, 1, 1, idx, dim ); 00751 CHECK_EQUAL( 0, err ); 00752 CHECK_EQUAL( 1, dim ); 00753 CHECK_EQUAL( 3, idx ); 00754 err = CN::OppositeSide( MBTET, 2, 1, idx, dim ); 00755 CHECK_EQUAL( 0, err ); 00756 CHECK_EQUAL( 1, dim ); 00757 CHECK_EQUAL( 4, idx ); 00758 err = CN::OppositeSide( MBTET, 3, 1, idx, dim ); 00759 CHECK_EQUAL( 0, err ); 00760 CHECK_EQUAL( 1, dim ); 00761 CHECK_EQUAL( 1, idx ); 00762 err = CN::OppositeSide( MBTET, 4, 1, idx, dim ); 00763 CHECK_EQUAL( 0, err ); 00764 CHECK_EQUAL( 1, dim ); 00765 CHECK_EQUAL( 2, idx ); 00766 err = CN::OppositeSide( MBTET, 5, 1, idx, dim ); 00767 CHECK_EQUAL( 0, err ); 00768 CHECK_EQUAL( 1, dim ); 00769 CHECK_EQUAL( 0, idx ); 00770 } 00771 00772 void test_opposite_side_hex() 00773 { 00774 int idx, dim, err; 00775 00776 err = CN::OppositeSide( MBHEX, 0, 0, idx, dim ); 00777 CHECK_EQUAL( 0, err ); 00778 CHECK_EQUAL( 0, dim ); 00779 CHECK_EQUAL( 6, idx ); 00780 err = CN::OppositeSide( MBHEX, 1, 0, idx, dim ); 00781 CHECK_EQUAL( 0, err ); 00782 CHECK_EQUAL( 0, dim ); 00783 CHECK_EQUAL( 7, idx ); 00784 err = CN::OppositeSide( MBHEX, 2, 0, idx, dim ); 00785 CHECK_EQUAL( 0, err ); 00786 CHECK_EQUAL( 0, dim ); 00787 CHECK_EQUAL( 4, idx ); 00788 err = CN::OppositeSide( MBHEX, 3, 0, idx, dim ); 00789 CHECK_EQUAL( 0, err ); 00790 CHECK_EQUAL( 0, dim ); 00791 CHECK_EQUAL( 5, idx ); 00792 err = CN::OppositeSide( MBHEX, 4, 0, idx, dim ); 00793 CHECK_EQUAL( 0, err ); 00794 CHECK_EQUAL( 0, dim ); 00795 CHECK_EQUAL( 2, idx ); 00796 err = CN::OppositeSide( MBHEX, 5, 0, idx, dim ); 00797 CHECK_EQUAL( 0, err ); 00798 CHECK_EQUAL( 0, dim ); 00799 CHECK_EQUAL( 3, idx ); 00800 err = CN::OppositeSide( MBHEX, 6, 0, idx, dim ); 00801 CHECK_EQUAL( 0, err ); 00802 CHECK_EQUAL( 0, dim ); 00803 CHECK_EQUAL( 0, idx ); 00804 err = CN::OppositeSide( MBHEX, 7, 0, idx, dim ); 00805 CHECK_EQUAL( 0, err ); 00806 CHECK_EQUAL( 0, dim ); 00807 CHECK_EQUAL( 1, idx ); 00808 00809 err = CN::OppositeSide( MBHEX, 0, 1, idx, dim ); 00810 CHECK_EQUAL( 0, err ); 00811 CHECK_EQUAL( 1, dim ); 00812 CHECK_EQUAL( 10, idx ); 00813 err = CN::OppositeSide( MBHEX, 1, 1, idx, dim ); 00814 CHECK_EQUAL( 0, err ); 00815 CHECK_EQUAL( 1, dim ); 00816 CHECK_EQUAL( 11, idx ); 00817 err = CN::OppositeSide( MBHEX, 2, 1, idx, dim ); 00818 CHECK_EQUAL( 0, err ); 00819 CHECK_EQUAL( 1, dim ); 00820 CHECK_EQUAL( 8, idx ); 00821 err = CN::OppositeSide( MBHEX, 3, 1, idx, dim ); 00822 CHECK_EQUAL( 0, err ); 00823 CHECK_EQUAL( 1, dim ); 00824 CHECK_EQUAL( 9, idx ); 00825 err = CN::OppositeSide( MBHEX, 4, 1, idx, dim ); 00826 CHECK_EQUAL( 0, err ); 00827 CHECK_EQUAL( 1, dim ); 00828 CHECK_EQUAL( 6, idx ); 00829 err = CN::OppositeSide( MBHEX, 5, 1, idx, dim ); 00830 CHECK_EQUAL( 0, err ); 00831 CHECK_EQUAL( 1, dim ); 00832 CHECK_EQUAL( 7, idx ); 00833 err = CN::OppositeSide( MBHEX, 6, 1, idx, dim ); 00834 CHECK_EQUAL( 0, err ); 00835 CHECK_EQUAL( 1, dim ); 00836 CHECK_EQUAL( 4, idx ); 00837 err = CN::OppositeSide( MBHEX, 7, 1, idx, dim ); 00838 CHECK_EQUAL( 0, err ); 00839 CHECK_EQUAL( 1, dim ); 00840 CHECK_EQUAL( 5, idx ); 00841 err = CN::OppositeSide( MBHEX, 8, 1, idx, dim ); 00842 CHECK_EQUAL( 0, err ); 00843 CHECK_EQUAL( 1, dim ); 00844 CHECK_EQUAL( 2, idx ); 00845 err = CN::OppositeSide( MBHEX, 9, 1, idx, dim ); 00846 CHECK_EQUAL( 0, err ); 00847 CHECK_EQUAL( 1, dim ); 00848 CHECK_EQUAL( 3, idx ); 00849 err = CN::OppositeSide( MBHEX, 10, 1, idx, dim ); 00850 CHECK_EQUAL( 0, err ); 00851 CHECK_EQUAL( 1, dim ); 00852 CHECK_EQUAL( 0, idx ); 00853 err = CN::OppositeSide( MBHEX, 11, 1, idx, dim ); 00854 CHECK_EQUAL( 0, err ); 00855 CHECK_EQUAL( 1, dim ); 00856 CHECK_EQUAL( 1, idx ); 00857 00858 err = CN::OppositeSide( MBHEX, 0, 2, idx, dim ); 00859 CHECK_EQUAL( 0, err ); 00860 CHECK_EQUAL( 2, dim ); 00861 CHECK_EQUAL( 2, idx ); 00862 err = CN::OppositeSide( MBHEX, 1, 2, idx, dim ); 00863 CHECK_EQUAL( 0, err ); 00864 CHECK_EQUAL( 2, dim ); 00865 CHECK_EQUAL( 3, idx ); 00866 err = CN::OppositeSide( MBHEX, 2, 2, idx, dim ); 00867 CHECK_EQUAL( 0, err ); 00868 CHECK_EQUAL( 2, dim ); 00869 CHECK_EQUAL( 0, idx ); 00870 err = CN::OppositeSide( MBHEX, 3, 2, idx, dim ); 00871 CHECK_EQUAL( 0, err ); 00872 CHECK_EQUAL( 2, dim ); 00873 CHECK_EQUAL( 1, idx ); 00874 err = CN::OppositeSide( MBHEX, 4, 2, idx, dim ); 00875 CHECK_EQUAL( 0, err ); 00876 CHECK_EQUAL( 2, dim ); 00877 CHECK_EQUAL( 5, idx ); 00878 err = CN::OppositeSide( MBHEX, 5, 2, idx, dim ); 00879 CHECK_EQUAL( 0, err ); 00880 CHECK_EQUAL( 2, dim ); 00881 CHECK_EQUAL( 4, idx ); 00882 } 00883 00884 void test_has_mid_nodes( EntityType type ) 00885 { 00886 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00887 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00888 00889 const int dim = CN::Dimension( type ); 00890 // calculate number of valid combinations of ho node flags 00891 int num_comb = 1; 00892 for( int i = 0; i < dim; ++i ) 00893 num_comb *= 2; 00894 // for each valid combination 00895 for( int c = 0; c < num_comb; ++c ) 00896 { 00897 // calculate corresponding number of vertices in element 00898 const int* ho_nodes = combinations[c]; 00899 int num_vtx = CN::VerticesPerEntity( type ); 00900 switch( dim ) 00901 { 00902 case 3: 00903 case 2: 00904 // extra clauses to avoid fall-through error 00905 if( 3 == dim && ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 00906 if( 2 <= dim && ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 00907 } 00908 if( ho_nodes[dim] ) ++num_vtx; 00909 00910 CHECK_EQUAL( ho_nodes[1], (int)CN::HasMidEdgeNodes( type, num_vtx ) ); 00911 CHECK_EQUAL( ho_nodes[2], (int)CN::HasMidFaceNodes( type, num_vtx ) ); 00912 CHECK_EQUAL( ho_nodes[3], (int)CN::HasMidRegionNodes( type, num_vtx ) ); 00913 00914 int results[4] = { 0, -1, -1, -1 }; 00915 CN::HasMidNodes( type, num_vtx, results ); 00916 CHECK_EQUAL( 0, !!results[0] ); 00917 CHECK_EQUAL( ho_nodes[1], !!results[1] ); 00918 CHECK_EQUAL( ho_nodes[2], !!results[2] ); 00919 CHECK_EQUAL( ho_nodes[3], !!results[3] ); 00920 } 00921 } 00922 00923 void test_ho_node_parent() 00924 { 00925 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00926 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00927 00928 for( const EntityType* t = elem_types; *t != MBMAXTYPE; ++t ) 00929 { 00930 const EntityType type = *t; 00931 const int dim = CN::Dimension( type ); 00932 // calculate number of valid combinations of ho node flags 00933 int num_comb = 1; 00934 for( int i = 0; i < dim; ++i ) 00935 num_comb *= 2; 00936 // for each valid combination 00937 for( int c = 0; c < num_comb; ++c ) 00938 { 00939 // calculate corresponding number of vertices in element 00940 const int* ho_nodes = combinations[c]; 00941 int num_vtx = CN::VerticesPerEntity( type ); 00942 switch( dim ) 00943 { 00944 case 3: 00945 case 2: 00946 // extra clauses to avoid fall-through error 00947 if( 3 == dim && ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 00948 if( 2 <= dim && ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 00949 } 00950 if( ho_nodes[dim] ) ++num_vtx; 00951 00952 // start at first higher-order node 00953 int pos = CN::VerticesPerEntity( type ); 00954 00955 // check mid-edge 00956 if( dim > 1 && ho_nodes[1] ) 00957 { 00958 for( int i = 0; i < CN::NumSubEntities( type, 1 ); ++i ) 00959 { 00960 int pdim = -1, pidx = -1; 00961 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00962 CHECK_EQUAL( 1, pdim ); 00963 CHECK_EQUAL( i, pidx ); 00964 } 00965 } 00966 00967 // check mid-face 00968 if( dim > 2 && ho_nodes[2] ) 00969 { 00970 for( int i = 0; i < CN::NumSubEntities( type, 2 ); ++i ) 00971 { 00972 int pdim = -1, pidx = -1; 00973 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00974 CHECK_EQUAL( 2, pdim ); 00975 CHECK_EQUAL( i, pidx ); 00976 } 00977 } 00978 00979 // check mid-volume 00980 if( ho_nodes[dim] ) 00981 { 00982 int pdim = -1, pidx = -1; 00983 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00984 CHECK_EQUAL( dim, pdim ); 00985 CHECK_EQUAL( 0, pidx ); 00986 } 00987 } // for ho_node combinatinos 00988 } // for each type 00989 } 00990 00991 void test_ho_node_index() 00992 { 00993 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00994 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00995 00996 for( const EntityType* t = elem_types; *t != MBMAXTYPE; ++t ) 00997 { 00998 const EntityType type = *t; 00999 const int dim = CN::Dimension( type ); 01000 // calculate number of valid combinations of ho node flags 01001 int num_comb = 1; 01002 for( int i = 0; i < dim; ++i ) 01003 num_comb *= 2; 01004 // for each valid combination 01005 for( int c = 0; c < num_comb; ++c ) 01006 { 01007 // calculate corresponding number of vertices in element 01008 const int* ho_nodes = combinations[c]; 01009 int num_vtx = CN::VerticesPerEntity( type ); 01010 switch( dim ) 01011 { 01012 case 3: 01013 case 2: 01014 // extra clauses to avoid fall-through error 01015 if( 3 == dim && ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 01016 if( 2 <= dim && ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 01017 } 01018 if( ho_nodes[dim] ) ++num_vtx; 01019 01020 // start at first higher-order node 01021 int pos = CN::VerticesPerEntity( type ); 01022 01023 // check mid-edge 01024 if( dim > 1 && ho_nodes[1] ) 01025 { 01026 for( int i = 0; i < CN::NumSubEntities( type, 1 ); ++i ) 01027 { 01028 int idx = CN::HONodeIndex( type, num_vtx, 1, i ); 01029 CHECK_EQUAL( pos++, idx ); 01030 } 01031 } 01032 01033 // check mid-face 01034 if( dim > 2 && ho_nodes[2] ) 01035 { 01036 for( int i = 0; i < CN::NumSubEntities( type, 2 ); ++i ) 01037 { 01038 int idx = CN::HONodeIndex( type, num_vtx, 2, i ); 01039 CHECK_EQUAL( pos++, idx ); 01040 } 01041 } 01042 01043 // check mid-volume 01044 if( ho_nodes[dim] ) 01045 { 01046 int idx = CN::HONodeIndex( type, num_vtx, dim, 0 ); 01047 CHECK_EQUAL( pos++, idx ); 01048 } 01049 } // for ho_node combinatinos 01050 } // for each type 01051 } 01052 01053 void test_sub_entity_nodes( EntityType parent, int sub_dimension ) 01054 { 01055 const int num_corner = CN::VerticesPerEntity( parent ); 01056 const int num_edge = CN::NumSubEntities( parent, 1 ); 01057 const int num_face = CN::NumSubEntities( parent, 2 ); 01058 01059 auto dim = CN::Dimension( parent ); 01060 switch( dim ) 01061 { 01062 case 3: 01063 case 2: 01064 case 1: 01065 test_sub_entity_nodes( parent, num_corner + num_face, sub_dimension ); 01066 test_sub_entity_nodes( parent, num_corner + num_edge + num_face, sub_dimension ); 01067 test_sub_entity_nodes( parent, num_corner + num_face + 1, sub_dimension ); 01068 test_sub_entity_nodes( parent, num_corner + num_edge + num_face + 1, sub_dimension ); 01069 if( 2 <= dim ) 01070 { 01071 test_sub_entity_nodes( parent, num_corner + num_edge, sub_dimension ); 01072 test_sub_entity_nodes( parent, num_corner + num_edge + 1, sub_dimension ); 01073 } 01074 if( 1 <= dim ) 01075 { 01076 test_sub_entity_nodes( parent, num_corner, sub_dimension ); 01077 test_sub_entity_nodes( parent, num_corner + 1, sub_dimension ); 01078 } 01079 break; 01080 default: 01081 CHECK( false ); 01082 } 01083 } 01084 01085 void test_sub_entity_nodes( EntityType parent, int num_nodes, int sub_dimension ) 01086 { 01087 const int num_sub = CN::NumSubEntities( parent, sub_dimension ); 01088 const int parent_ho = CN::HasMidNodes( parent, num_nodes ); 01089 int child_ho = 0; 01090 for( int d = 1; d <= sub_dimension; ++d ) 01091 child_ho |= ( parent_ho & ( 1 << d ) ); 01092 01093 // first test the types 01094 for( int i = 0; i < num_sub; ++i ) 01095 { 01096 int num, conn[moab::MAX_SUB_ENTITY_VERTICES]; 01097 EntityType type; 01098 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01099 CHECK_EQUAL( CN::SubEntityType( parent, sub_dimension, i ), type ); 01100 } 01101 01102 // now test that they have the correct number of higher-order node 01103 for( int i = 0; i < num_sub; ++i ) 01104 { 01105 int num, conn[moab::MAX_SUB_ENTITY_VERTICES]; 01106 EntityType type; 01107 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01108 const int ho = CN::HasMidNodes( type, num ); 01109 CHECK_EQUAL( child_ho, ho ); 01110 } 01111 01112 // now test the actual indices 01113 for( int i = 0; i < num_sub; ++i ) 01114 { 01115 int num, conn[moab::MAX_SUB_ENTITY_VERTICES], corners[moab::MAX_SUB_ENTITY_VERTICES]; 01116 EntityType type; 01117 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01118 01119 // check corner indices against SubEntityVertexIndices 01120 const int num_corner = CN::VerticesPerEntity( type ); 01121 CHECK( num >= num_corner ); 01122 CN::SubEntityVertexIndices( parent, sub_dimension, i, corners ); 01123 for( int j = 0; j < num_corner; ++j ) 01124 CHECK_EQUAL( corners[j], conn[j] ); 01125 01126 // check mid-edge indices, if present 01127 int idx = num_corner; 01128 if( child_ho & CN::MID_EDGE_BIT ) 01129 { 01130 // for each edge in the sub-entity type 01131 const int num_edge = CN::NumSubEntities( type, 1 ); 01132 for( int j = 0; j < num_edge; ++j ) 01133 { 01134 // get edge indices for sub-entity connectivity 01135 int edge_ends[2]; 01136 CN::SubEntityVertexIndices( type, 1, j, edge_ends ); 01137 // convert to indices into parent type's connectivity 01138 CHECK( edge_ends[0] < num_corner ); 01139 edge_ends[0] = corners[edge_ends[0]]; 01140 CHECK( edge_ends[1] < num_corner ); 01141 edge_ends[1] = corners[edge_ends[1]]; 01142 // find edge index in parent element 01143 int side, sense, off; 01144 int result = CN::SideNumber( parent, edge_ends, 2, 1, side, sense, off ); 01145 CHECK_EQUAL( 0, result ); 01146 // get location in parent entity connectivity for mid-edge node 01147 int loc = CN::HONodeIndex( parent, num_nodes, 1, side ); 01148 CHECK_EQUAL( loc, conn[idx++] ); 01149 } 01150 } 01151 01152 // check mid-face indices, if present 01153 if( child_ho & CN::MID_FACE_BIT ) 01154 { 01155 CHECK_EQUAL( 2, CN::Dimension( type ) ); 01156 int loc = CN::HONodeIndex( parent, num_nodes, 2, i ); 01157 CHECK_EQUAL( loc, conn[idx++] ); 01158 } 01159 01160 // make sure there were no extra node indices returned 01161 CHECK_EQUAL( idx, num ); 01162 } 01163 } 01164 01165 #include "moab/Core.hpp" 01166 void prism_issue() 01167 { 01168 moab::Core mb; 01169 01170 std::vector< moab::EntityHandle > conn; 01171 double coords[3]; 01172 for( int i = 0; i < 15; ++i ) 01173 { 01174 moab::EntityHandle h; 01175 mb.create_vertex( coords, h ); 01176 conn.push_back( h ); 01177 } 01178 01179 moab::EntityHandle w; 01180 mb.create_element( moab::MBPRISM, conn.data(), 15, w ); 01181 01182 // this leads to the failure 01183 { 01184 std::vector< moab::EntityHandle > adj; 01185 mb.get_adjacencies( &w, 1, 2, true, adj ); 01186 } 01187 std::vector< moab::EntityHandle > edges; 01188 std::vector< moab::EntityHandle > faces; 01189 mb.get_entities_by_dimension( 0, 1, edges ); 01190 for( const auto& e : edges ) 01191 { 01192 std::vector< moab::EntityHandle > conn; 01193 std::cout << "edge " << e << " connectivity: "; 01194 01195 mb.get_connectivity( &e, 1, conn ); 01196 for( const auto& n : conn ) 01197 std::cout << n << " "; 01198 std::cout << "\n"; 01199 } 01200 mb.get_entities_by_dimension( 0, 2, faces ); 01201 for( const auto& f : faces ) 01202 { 01203 std::vector< moab::EntityHandle > conn; 01204 std::cout << "face " << f << " connectivity: "; 01205 01206 mb.get_connectivity( &f, 1, conn ); 01207 for( const auto& n : conn ) 01208 std::cout << n << " "; 01209 std::cout << "\n"; 01210 } 01211 std::vector< moab::EntityHandle > nodes; 01212 mb.get_entities_by_dimension( 0, 0, nodes ); 01213 for( const auto& n : nodes ) 01214 { 01215 std::vector< moab::EntityHandle > adj; 01216 std::cout << "node " << n << " connection: "; 01217 adj.clear(); 01218 mb.get_adjacencies( &n, 1, 1, true, adj ); 01219 std::cout << adj.size() << " edges,"; 01220 // there are either 1 or 3 adjacent edges to each vertex (1 for mid edge vertex) 01221 CHECK( 1 == adj.size() || 3 == adj.size() ); 01222 adj.clear(); 01223 mb.get_adjacencies( &n, 1, 2, true, adj ); 01224 std::cout << adj.size() << " faces,"; 01225 // there are either 2 or 3 adjacent faces to each vertex ( 2 for mid edge evertex) 01226 CHECK( 2 == adj.size() || 3 == adj.size() ); 01227 adj.clear(); 01228 mb.get_adjacencies( &n, 1, 3, true, adj ); 01229 std::cout << adj.size() << " volumes\n"; 01230 } 01231 } 01232 01233 void test_wedges() 01234 { 01235 moab::Core mb; 01236 01237 //mb.load_file("./wed15_2.h5m"); 01238 std::vector< moab::EntityHandle > conn; 01239 double coords[3]; 01240 for( int i = 0; i < 22; ++i ) 01241 { 01242 moab::EntityHandle h; 01243 mb.create_vertex( coords, h ); 01244 } 01245 moab::EntityHandle conn1[15] = { 10, 20, 14, 1, 8, 5, 21, 19, 15, 16, 22, 18, 9, 7, 6 }; 01246 moab::EntityHandle conn2[15] = { 10, 14, 12, 1, 5, 3, 15, 13, 11, 16, 18, 17, 6, 4, 2 }; 01247 01248 moab::EntityHandle w; 01249 mb.create_element( moab::MBPRISM, conn1, 15, w ); 01250 mb.create_element( moab::MBPRISM, conn2, 15, w ); 01251 01252 std::vector< moab::EntityHandle > wedges; 01253 mb.get_entities_by_dimension( 0, 3, wedges ); 01254 01255 // > If I comment this block there is no problem 01256 for( const auto& w : wedges ) 01257 { 01258 std::vector< moab::EntityHandle > adj; 01259 mb.get_adjacencies( &w, 1, 2, true, adj ); 01260 CHECK( 5 == adj.size() ); 01261 } 01262 // < 01263 01264 for( const auto& w : wedges ) 01265 { 01266 std::vector< moab::EntityHandle > conn; 01267 mb.get_connectivity( &w, 1, conn ); 01268 CHECK( 15 == conn.size() ); 01269 for( const auto& n : conn ) 01270 { 01271 std::vector< moab::EntityHandle > edges; 01272 mb.get_adjacencies( &n, 1, 1, true, edges ); 01273 if( edges.size() == 0 ) 01274 { 01275 std::cout << " node " << n << " not connected to edges \n"; 01276 std::vector< moab::EntityHandle > faces; 01277 mb.get_adjacencies( &n, 1, 2, false, faces ); 01278 for( const auto& f : faces ) 01279 { 01280 std::vector< moab::EntityHandle > connf; 01281 mb.get_connectivity( &f, 1, connf ); 01282 std::cout << "face:" << mb.id_from_handle( f ); 01283 for( const auto& n1 : connf ) 01284 std::cout << " " << n1; 01285 std::cout << "\n"; 01286 } 01287 std::vector< moab::EntityHandle > prisms; 01288 mb.get_adjacencies( &n, 1, 3, false, prisms ); 01289 for( const auto& p : prisms ) 01290 { 01291 std::vector< moab::EntityHandle > connf; 01292 mb.get_connectivity( &p, 1, connf ); 01293 std::cout << "prism:" << mb.id_from_handle( p ); 01294 for( const auto& n1 : connf ) 01295 std::cout << " " << n1; 01296 std::cout << "\n"; 01297 } 01298 CHECK( edges.size() != 0 ); 01299 } 01300 } 01301 } 01302 }