MOAB: Mesh Oriented datABase
(version 5.2.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 00131 int main() 00132 { 00133 int result = 0; 00134 result += RUN_TEST( test_dimension_pair ); 00135 result += RUN_TEST( test_type_names ); 00136 result += RUN_TEST( test_dimension ); 00137 result += RUN_TEST( test_vertices_per_entity ); 00138 result += RUN_TEST( test_num_sub_entities ); 00139 00140 result += RUN_TEST( test_sub_entity_type_vtx ); 00141 result += RUN_TEST( test_sub_entity_type_edge ); 00142 result += RUN_TEST( test_sub_entity_type_tri ); 00143 result += RUN_TEST( test_sub_entity_type_quad ); 00144 result += RUN_TEST( test_sub_entity_type_tet ); 00145 result += RUN_TEST( test_sub_entity_type_pyr ); 00146 result += RUN_TEST( test_sub_entity_type_pri ); 00147 result += RUN_TEST( test_sub_entity_type_knife ); 00148 result += RUN_TEST( test_sub_entity_type_hex ); 00149 00150 result += RUN_TEST( test_sub_entity_indices_vtx ); 00151 result += RUN_TEST( test_sub_entity_indices_edge ); 00152 result += RUN_TEST( test_sub_entity_indices_tri ); 00153 result += RUN_TEST( test_sub_entity_indices_quad ); 00154 result += RUN_TEST( test_sub_entity_indices_tet ); 00155 result += RUN_TEST( test_sub_entity_indices_pyr ); 00156 result += RUN_TEST( test_sub_entity_indices_pri ); 00157 result += RUN_TEST( test_sub_entity_indices_hex ); 00158 00159 result += RUN_TEST( test_side_number_tri ); 00160 result += RUN_TEST( test_side_number_quad ); 00161 result += RUN_TEST( test_side_number_tet ); 00162 result += RUN_TEST( test_side_number_pyr ); 00163 result += RUN_TEST( test_side_number_pri ); 00164 result += RUN_TEST( test_side_number_hex ); 00165 00166 result += RUN_TEST( test_opposite_side_tri ); 00167 result += RUN_TEST( test_opposite_side_quad ); 00168 result += RUN_TEST( test_opposite_side_tet ); 00169 result += RUN_TEST( test_opposite_side_hex ); 00170 00171 result += RUN_TEST( test_has_mid_nodes_edge ); 00172 result += RUN_TEST( test_has_mid_nodes_tri ); 00173 result += RUN_TEST( test_has_mid_nodes_quad ); 00174 result += RUN_TEST( test_has_mid_nodes_tet ); 00175 result += RUN_TEST( test_has_mid_nodes_pyr ); 00176 result += RUN_TEST( test_has_mid_nodes_pri ); 00177 result += RUN_TEST( test_has_mid_nodes_knife ); 00178 result += RUN_TEST( test_has_mid_nodes_hex ); 00179 00180 result += RUN_TEST( test_sub_entity_nodes_tri_edges ); 00181 result += RUN_TEST( test_sub_entity_nodes_quad_edges ); 00182 result += RUN_TEST( test_sub_entity_nodes_tet_edges ); 00183 result += RUN_TEST( test_sub_entity_nodes_tet_faces ); 00184 result += RUN_TEST( test_sub_entity_nodes_pyr_edges ); 00185 result += RUN_TEST( test_sub_entity_nodes_pyr_faces ); 00186 result += RUN_TEST( test_sub_entity_nodes_pri_edges ); 00187 result += RUN_TEST( test_sub_entity_nodes_pri_faces ); 00188 result += RUN_TEST( test_sub_entity_nodes_kni_edges ); 00189 result += RUN_TEST( test_sub_entity_nodes_kni_faces ); 00190 result += RUN_TEST( test_sub_entity_nodes_hex_edges ); 00191 result += RUN_TEST( test_sub_entity_nodes_hex_faces ); 00192 00193 result += RUN_TEST( test_ho_node_parent ); 00194 result += RUN_TEST( test_ho_node_index ); 00195 return result; 00196 } 00197 00198 const EntityType elem_types[] = { MBTRI, MBQUAD, MBTET, MBPYRAMID, MBPRISM, MBHEX, MBMAXTYPE }; 00199 // const int num_elem_types = sizeof(elem_types)/sizeof(elem_types[0]) - 1; 00200 00201 void test_dimension_pair() 00202 { 00203 DimensionPair dp; 00204 00205 dp = CN::TypeDimensionMap[0]; 00206 CHECK_EQUAL( MBVERTEX, dp.first ); 00207 CHECK_EQUAL( MBVERTEX, dp.second ); 00208 00209 dp = CN::TypeDimensionMap[1]; 00210 CHECK_EQUAL( MBEDGE, dp.first ); 00211 CHECK_EQUAL( MBEDGE, dp.second ); 00212 00213 dp = CN::TypeDimensionMap[2]; 00214 CHECK_EQUAL( MBTRI, dp.first ); 00215 CHECK_EQUAL( MBPOLYGON, dp.second ); 00216 00217 dp = CN::TypeDimensionMap[3]; 00218 CHECK_EQUAL( MBTET, dp.first ); 00219 CHECK_EQUAL( MBPOLYHEDRON, dp.second ); 00220 } 00221 00222 void test_type_names() 00223 { 00224 for( EntityType t = MBVERTEX; t != MBMAXTYPE; ++t ) 00225 { 00226 const char* name = CN::EntityTypeName( t ); 00227 CHECK_EQUAL( t, CN::EntityTypeFromName( name ) ); 00228 } 00229 } 00230 00231 void test_dimension() 00232 { 00233 CHECK_EQUAL( 0, CN::Dimension( MBVERTEX ) ); 00234 CHECK_EQUAL( 1, CN::Dimension( MBEDGE ) ); 00235 CHECK_EQUAL( 2, CN::Dimension( MBTRI ) ); 00236 CHECK_EQUAL( 2, CN::Dimension( MBQUAD ) ); 00237 CHECK_EQUAL( 2, CN::Dimension( MBPOLYGON ) ); 00238 CHECK_EQUAL( 3, CN::Dimension( MBTET ) ); 00239 CHECK_EQUAL( 3, CN::Dimension( MBPYRAMID ) ); 00240 CHECK_EQUAL( 3, CN::Dimension( MBPRISM ) ); 00241 CHECK_EQUAL( 3, CN::Dimension( MBKNIFE ) ); 00242 CHECK_EQUAL( 3, CN::Dimension( MBHEX ) ); 00243 CHECK_EQUAL( 3, CN::Dimension( MBPOLYHEDRON ) ); 00244 } 00245 00246 void test_vertices_per_entity() 00247 { 00248 CHECK_EQUAL( 1, CN::VerticesPerEntity( MBVERTEX ) ); 00249 CHECK_EQUAL( 2, CN::VerticesPerEntity( MBEDGE ) ); 00250 CHECK_EQUAL( 3, CN::VerticesPerEntity( MBTRI ) ); 00251 CHECK_EQUAL( 4, CN::VerticesPerEntity( MBQUAD ) ); 00252 CHECK_EQUAL( 4, CN::VerticesPerEntity( MBTET ) ); 00253 CHECK_EQUAL( 5, CN::VerticesPerEntity( MBPYRAMID ) ); 00254 CHECK_EQUAL( 6, CN::VerticesPerEntity( MBPRISM ) ); 00255 CHECK_EQUAL( 7, CN::VerticesPerEntity( MBKNIFE ) ); 00256 CHECK_EQUAL( 8, CN::VerticesPerEntity( MBHEX ) ); 00257 } 00258 00259 void test_num_sub_entities() 00260 { 00261 CHECK_EQUAL( 1, CN::NumSubEntities( MBVERTEX, 0 ) ); 00262 00263 CHECK_EQUAL( 2, CN::NumSubEntities( MBEDGE, 0 ) ); 00264 CHECK_EQUAL( 1, CN::NumSubEntities( MBEDGE, 1 ) ); 00265 00266 CHECK_EQUAL( 3, CN::NumSubEntities( MBTRI, 0 ) ); 00267 CHECK_EQUAL( 3, CN::NumSubEntities( MBTRI, 1 ) ); 00268 CHECK_EQUAL( 1, CN::NumSubEntities( MBTRI, 2 ) ); 00269 00270 CHECK_EQUAL( 4, CN::NumSubEntities( MBQUAD, 0 ) ); 00271 CHECK_EQUAL( 4, CN::NumSubEntities( MBQUAD, 1 ) ); 00272 CHECK_EQUAL( 1, CN::NumSubEntities( MBQUAD, 2 ) ); 00273 00274 CHECK_EQUAL( 4, CN::NumSubEntities( MBTET, 0 ) ); 00275 CHECK_EQUAL( 6, CN::NumSubEntities( MBTET, 1 ) ); 00276 CHECK_EQUAL( 4, CN::NumSubEntities( MBTET, 2 ) ); 00277 00278 CHECK_EQUAL( 5, CN::NumSubEntities( MBPYRAMID, 0 ) ); 00279 CHECK_EQUAL( 8, CN::NumSubEntities( MBPYRAMID, 1 ) ); 00280 CHECK_EQUAL( 5, CN::NumSubEntities( MBPYRAMID, 2 ) ); 00281 00282 CHECK_EQUAL( 6, CN::NumSubEntities( MBPRISM, 0 ) ); 00283 CHECK_EQUAL( 9, CN::NumSubEntities( MBPRISM, 1 ) ); 00284 CHECK_EQUAL( 5, CN::NumSubEntities( MBPRISM, 2 ) ); 00285 00286 CHECK_EQUAL( 7, CN::NumSubEntities( MBKNIFE, 0 ) ); 00287 CHECK_EQUAL( 10, CN::NumSubEntities( MBKNIFE, 1 ) ); 00288 CHECK_EQUAL( 5, CN::NumSubEntities( MBKNIFE, 2 ) ); 00289 00290 CHECK_EQUAL( 8, CN::NumSubEntities( MBHEX, 0 ) ); 00291 CHECK_EQUAL( 12, CN::NumSubEntities( MBHEX, 1 ) ); 00292 CHECK_EQUAL( 6, CN::NumSubEntities( MBHEX, 2 ) ); 00293 } 00294 00295 void do_test_sub_entity_type_2d( EntityType type ) 00296 { 00297 for( int j = 0; j < CN::VerticesPerEntity( type ); ++j ) 00298 { 00299 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( type, 0, j ) ); 00300 CHECK_EQUAL( MBEDGE, CN::SubEntityType( type, 1, j ) ); 00301 } 00302 CHECK_EQUAL( type, CN::SubEntityType( type, 2, 0 ) ); 00303 } 00304 00305 void do_test_sub_entity_type_3d( EntityType type, int num_faces, const EntityType* face_types ) 00306 { 00307 for( int j = 0; j < CN::VerticesPerEntity( type ); ++j ) 00308 { 00309 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( type, 0, j ) ); 00310 } 00311 00312 for( int j = 0; j < CN::NumSubEntities( type, 1 ); ++j ) 00313 { 00314 CHECK_EQUAL( MBEDGE, CN::SubEntityType( type, 1, j ) ); 00315 } 00316 00317 for( int j = 0; j < num_faces; ++j ) 00318 { 00319 EntityType sub_type = CN::SubEntityType( type, 2, j ); 00320 CHECK_EQUAL( face_types[j], sub_type ); 00321 } 00322 00323 CHECK_EQUAL( type, CN::SubEntityType( type, 3, 0 ) ); 00324 } 00325 00326 void test_sub_entity_type_vtx() 00327 { 00328 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBVERTEX, 0, 0 ) ); 00329 } 00330 00331 void test_sub_entity_type_edge() 00332 { 00333 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBEDGE, 0, 0 ) ); 00334 CHECK_EQUAL( MBVERTEX, CN::SubEntityType( MBEDGE, 0, 1 ) ); 00335 CHECK_EQUAL( MBEDGE, CN::SubEntityType( MBEDGE, 1, 0 ) ); 00336 } 00337 00338 void test_sub_entity_type_tri() 00339 { 00340 do_test_sub_entity_type_2d( MBTRI ); 00341 } 00342 00343 void test_sub_entity_type_quad() 00344 { 00345 do_test_sub_entity_type_2d( MBQUAD ); 00346 } 00347 00348 void test_sub_entity_type_tet() 00349 { 00350 const EntityType types[] = { MBTRI, MBTRI, MBTRI, MBTRI }; 00351 do_test_sub_entity_type_3d( MBTET, sizeof( types ) / sizeof( types[0] ), types ); 00352 } 00353 00354 void test_sub_entity_type_pyr() 00355 { 00356 const EntityType types[] = { MBTRI, MBTRI, MBTRI, MBTRI, MBQUAD }; 00357 do_test_sub_entity_type_3d( MBPYRAMID, sizeof( types ) / sizeof( types[0] ), types ); 00358 } 00359 00360 void test_sub_entity_type_pri() 00361 { 00362 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBTRI, MBTRI }; 00363 do_test_sub_entity_type_3d( MBPRISM, sizeof( types ) / sizeof( types[0] ), types ); 00364 } 00365 00366 void test_sub_entity_type_knife() 00367 { 00368 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD }; 00369 do_test_sub_entity_type_3d( MBKNIFE, sizeof( types ) / sizeof( types[0] ), types ); 00370 } 00371 00372 void test_sub_entity_type_hex() 00373 { 00374 const EntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD }; 00375 do_test_sub_entity_type_3d( MBHEX, sizeof( types ) / sizeof( types[0] ), types ); 00376 } 00377 00378 void test_0d_sub_entity_indices( EntityType type, int num_vtx ) 00379 { 00380 for( int i = 0; i < num_vtx; ++i ) 00381 { 00382 // zero input array 00383 int indices[2] = { 0, -100 }; 00384 // check correct results 00385 CN::SubEntityVertexIndices( type, 0, i, indices ); 00386 CHECK_EQUAL( i, indices[0] ); 00387 // check didn't write past end of array 00388 CHECK_EQUAL( -100, indices[1] ); 00389 } 00390 } 00391 00392 void test_1d_sub_entity_indices( EntityType type, int num_edges, const int ( *edge_indices )[2] ) 00393 { 00394 for( int i = 0; i < num_edges; ++i ) 00395 { 00396 // zero input array 00397 int indices[3] = { 0, 0, -99 }; 00398 // check correct results 00399 CN::SubEntityVertexIndices( type, 1, i, indices ); 00400 if( edge_indices[i][0] == indices[0] ) { CHECK_EQUAL( edge_indices[i][1], indices[1] ); } 00401 else 00402 { 00403 CHECK_EQUAL( edge_indices[i][0], indices[1] ); 00404 CHECK_EQUAL( edge_indices[i][1], indices[0] ); 00405 } 00406 // check didn't write past end of array 00407 CHECK_EQUAL( -99, indices[2] ); 00408 } 00409 } 00410 00411 void test_2d_sub_entity_indices( EntityType type, int num_faces, const int ( *face_indices )[5] ) 00412 { 00413 for( int i = 0; i < num_faces; ++i ) 00414 { 00415 // zero input array 00416 int indices[5] = { 0, 0, 0, -99, -99 }; 00417 // check correct results 00418 CN::SubEntityVertexIndices( type, 2, i, indices ); 00419 const int num_vtx = face_indices[i][0]; 00420 if( num_vtx != 3 ) CHECK_EQUAL( 4, num_vtx ); 00421 const int* exp_index = face_indices[i] + 1; 00422 int off = std::find( indices, indices + num_vtx, exp_index[0] ) - indices; 00423 CHECK( off < num_vtx ); 00424 /* Expect faces to be ordered such that CCW normal is outwards 00425 * 00426 bool reverse = indices[(off+num_vtx-1)%num_vtx] == exp_index[1]; 00427 if (reverse) { 00428 CHECK_EQUAL( exp_index[1], indices[(off+num_vtx-1)%num_vtx] ); 00429 CHECK_EQUAL( exp_index[2], indices[(off+num_vtx-2)%num_vtx] ); 00430 if (num_vtx == 4) 00431 CHECK_EQUAL( exp_index[3], indices[(off+num_vtx-3)%num_vtx] ); 00432 } 00433 else { 00434 */ 00435 CHECK_EQUAL( exp_index[1], indices[( off + 1 ) % num_vtx] ); 00436 CHECK_EQUAL( exp_index[2], indices[( off + 2 ) % num_vtx] ); 00437 if( num_vtx == 4 ) CHECK_EQUAL( exp_index[3], indices[( off + 3 ) % num_vtx] ); 00438 /* 00439 } 00440 */ 00441 00442 // check didn't write past end of array 00443 if( num_vtx == 3 ) CHECK_EQUAL( -99, indices[3] ); 00444 CHECK_EQUAL( -99, indices[4] ); 00445 } 00446 } 00447 00448 void test_elem_as_sub_entity( EntityType type, int dim, int num_vertices ) 00449 { 00450 int indices[9] = { -2, -2, -2, -2, -2, -2, -2, -2, -2 }; 00451 CN::SubEntityVertexIndices( type, dim, 0, indices ); 00452 for( int i = 0; i < num_vertices; ++i ) 00453 CHECK_EQUAL( i, indices[i] ); 00454 // make sure didn't write past end 00455 CHECK_EQUAL( -2, indices[num_vertices] ); 00456 } 00457 00458 void test_sub_entity_indices_vtx() 00459 { 00460 test_elem_as_sub_entity( MBVERTEX, 0, 1 ); 00461 } 00462 00463 void test_sub_entity_indices_edge() 00464 { 00465 test_0d_sub_entity_indices( MBEDGE, 2 ); 00466 test_elem_as_sub_entity( MBEDGE, 1, 2 ); 00467 } 00468 00469 void test_sub_entity_indices_tri() 00470 { 00471 const int edges[3][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 } }; 00472 test_0d_sub_entity_indices( MBTRI, 3 ); 00473 test_1d_sub_entity_indices( MBTRI, 3, edges ); 00474 test_elem_as_sub_entity( MBTRI, 2, 3 ); 00475 } 00476 00477 void test_sub_entity_indices_quad() 00478 { 00479 const int edges[4][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 } }; 00480 test_0d_sub_entity_indices( MBQUAD, 4 ); 00481 test_1d_sub_entity_indices( MBQUAD, 4, edges ); 00482 test_elem_as_sub_entity( MBQUAD, 2, 4 ); 00483 } 00484 00485 void test_sub_entity_indices_tet() 00486 { 00487 const EntityType type = MBTET; 00488 const int num_vtx = 4; 00489 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 3 }, { 2, 3 } }; 00490 const int faces[][5] = { { 3, 0, 1, 3, 0 }, { 3, 1, 2, 3, 0 }, { 3, 2, 0, 3, 0 }, { 3, 2, 1, 0, 0 } }; 00491 test_0d_sub_entity_indices( type, num_vtx ); 00492 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00493 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00494 test_elem_as_sub_entity( type, 3, num_vtx ); 00495 } 00496 00497 void test_sub_entity_indices_pyr() 00498 { 00499 const EntityType type = MBPYRAMID; 00500 const int num_vtx = 5; 00501 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 4 }, { 2, 4 }, { 3, 4 } }; 00502 const int faces[][5] = { 00503 { 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 } 00504 }; 00505 test_0d_sub_entity_indices( type, num_vtx ); 00506 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00507 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00508 test_elem_as_sub_entity( type, 3, num_vtx ); 00509 } 00510 00511 void test_sub_entity_indices_pri() 00512 { 00513 const EntityType type = MBPRISM; 00514 const int num_vtx = 6; 00515 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 0 }, { 0, 3 }, { 1, 4 }, { 2, 5 }, { 3, 4 }, { 4, 5 }, { 5, 3 } }; 00516 const int faces[][5] = { 00517 { 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 } 00518 }; 00519 test_0d_sub_entity_indices( type, num_vtx ); 00520 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00521 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00522 test_elem_as_sub_entity( type, 3, num_vtx ); 00523 } 00524 00525 void test_sub_entity_indices_hex() 00526 { 00527 const EntityType type = MBHEX; 00528 const int num_vtx = 8; 00529 const int edges[][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 0, 4 }, { 1, 5 }, 00530 { 2, 6 }, { 3, 7 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 } }; 00531 const int faces[][5] = { { 4, 0, 1, 5, 4 }, { 4, 1, 2, 6, 5 }, { 4, 2, 3, 7, 6 }, 00532 { 4, 3, 0, 4, 7 }, { 4, 3, 2, 1, 0 }, { 4, 4, 5, 6, 7 } }; 00533 test_0d_sub_entity_indices( type, num_vtx ); 00534 test_1d_sub_entity_indices( type, sizeof( edges ) / sizeof( edges[0] ), edges ); 00535 test_2d_sub_entity_indices( type, sizeof( faces ) / sizeof( faces[0] ), faces ); 00536 test_elem_as_sub_entity( type, 3, num_vtx ); 00537 } 00538 00539 static void do_test_side_number_1d( EntityType type, int idx ) 00540 { 00541 // define a random handle list 00542 const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 }; 00543 // get side indices 00544 int side_idx[4] = { 0, 0 }; 00545 CN::SubEntityVertexIndices( type, 1, idx, side_idx ); 00546 00547 // "reversed" and "offset" are the same thing for edges. 00548 int side_conn[2] = { elem_verts[side_idx[0]], elem_verts[side_idx[1]] }; 00549 int rev_conn[2] = { elem_verts[side_idx[1]], elem_verts[side_idx[0]] }; 00550 int result_side = -100, result_sense = -100, result_offset = -100; 00551 int err = CN::SideNumber( type, elem_verts, side_conn, 2, 1, result_side, result_sense, result_offset ); 00552 CHECK_EQUAL( 0, err ); 00553 CHECK_EQUAL( idx, result_side ); 00554 CHECK_EQUAL( 1, result_sense ); 00555 CHECK_EQUAL( 0, result_offset ); 00556 err = CN::SideNumber( type, elem_verts, rev_conn, 2, 1, result_side, result_sense, result_offset ); 00557 CHECK_EQUAL( 0, err ); 00558 CHECK_EQUAL( idx, result_side ); 00559 CHECK( result_offset == 1 || result_sense == -1 ); 00560 } 00561 00562 static void do_test_side_number_2d( EntityType type, int idx ) 00563 { 00564 // define a random handle list 00565 const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 }; 00566 // get side indices 00567 const int side_size = CN::VerticesPerEntity( CN::SubEntityType( type, 2, idx ) ); 00568 int side_idx[4] = { 0, 0, 0, 0 }; 00569 CN::SubEntityVertexIndices( type, 2, idx, side_idx ); 00570 00571 // for each possible forward or reverse offset 00572 for( int rev = -1; rev < 2; rev += 2 ) 00573 { 00574 for( int off = 0; off < side_size; ++off ) 00575 { 00576 int side_conn[4]; 00577 side_conn[3] = 0; 00578 for( int i = 0; i < side_size; ++i ) 00579 side_conn[( side_size + rev * i ) % side_size] = elem_verts[side_idx[( i + off ) % side_size]]; 00580 00581 int result_side = -100, result_sense = -100, result_offset = -100; 00582 int err = 00583 CN::SideNumber( type, elem_verts, side_conn, side_size, 2, result_side, result_sense, result_offset ); 00584 CHECK_EQUAL( 0, err ); 00585 CHECK_EQUAL( idx, result_side ); 00586 CHECK_EQUAL( rev, result_sense ); 00587 CHECK_EQUAL( off, result_offset ); 00588 } 00589 } 00590 } 00591 00592 void test_side_number_tri() 00593 { 00594 for( int side = 0; side < 3; ++side ) 00595 do_test_side_number_1d( MBTRI, side ); 00596 } 00597 00598 void test_side_number_quad() 00599 { 00600 for( int side = 0; side < 4; ++side ) 00601 do_test_side_number_1d( MBQUAD, side ); 00602 } 00603 00604 void test_side_number_tet() 00605 { 00606 for( int edge = 0; edge < 6; ++edge ) 00607 do_test_side_number_1d( MBTET, edge ); 00608 for( int face = 0; face < 4; ++face ) 00609 do_test_side_number_2d( MBTET, face ); 00610 } 00611 00612 void test_side_number_pyr() 00613 { 00614 for( int edge = 0; edge < 8; ++edge ) 00615 do_test_side_number_1d( MBPYRAMID, edge ); 00616 for( int face = 0; face < 5; ++face ) 00617 do_test_side_number_2d( MBPYRAMID, face ); 00618 } 00619 00620 void test_side_number_pri() 00621 { 00622 for( int edge = 0; edge < 9; ++edge ) 00623 do_test_side_number_1d( MBPRISM, edge ); 00624 for( int face = 0; face < 5; ++face ) 00625 do_test_side_number_2d( MBPRISM, face ); 00626 } 00627 00628 void test_side_number_hex() 00629 { 00630 for( int edge = 0; edge < 12; ++edge ) 00631 do_test_side_number_1d( MBHEX, edge ); 00632 for( int face = 0; face < 6; ++face ) 00633 do_test_side_number_2d( MBHEX, face ); 00634 } 00635 00636 void test_opposite_side_tri() 00637 { 00638 int idx, dim, err; 00639 err = CN::OppositeSide( MBTRI, 0, 0, idx, dim ); 00640 CHECK_EQUAL( 0, err ); 00641 CHECK_EQUAL( 1, dim ); 00642 CHECK_EQUAL( 1, idx ); 00643 err = CN::OppositeSide( MBTRI, 1, 0, idx, dim ); 00644 CHECK_EQUAL( 0, err ); 00645 CHECK_EQUAL( 1, dim ); 00646 CHECK_EQUAL( 2, idx ); 00647 err = CN::OppositeSide( MBTRI, 2, 0, idx, dim ); 00648 CHECK_EQUAL( 0, err ); 00649 CHECK_EQUAL( 1, dim ); 00650 CHECK_EQUAL( 0, idx ); 00651 err = CN::OppositeSide( MBTRI, 0, 1, idx, dim ); 00652 CHECK_EQUAL( 0, err ); 00653 CHECK_EQUAL( 0, dim ); 00654 CHECK_EQUAL( 2, idx ); 00655 err = CN::OppositeSide( MBTRI, 1, 1, idx, dim ); 00656 CHECK_EQUAL( 0, err ); 00657 CHECK_EQUAL( 0, dim ); 00658 CHECK_EQUAL( 0, idx ); 00659 err = CN::OppositeSide( MBTRI, 2, 1, idx, dim ); 00660 CHECK_EQUAL( 0, err ); 00661 CHECK_EQUAL( 0, dim ); 00662 CHECK_EQUAL( 1, idx ); 00663 } 00664 00665 void test_opposite_side_quad() 00666 { 00667 int idx, dim, err; 00668 err = CN::OppositeSide( MBQUAD, 0, 0, idx, dim ); 00669 CHECK_EQUAL( 0, err ); 00670 CHECK_EQUAL( 0, dim ); 00671 CHECK_EQUAL( 2, idx ); 00672 err = CN::OppositeSide( MBQUAD, 1, 0, idx, dim ); 00673 CHECK_EQUAL( 0, err ); 00674 CHECK_EQUAL( 0, dim ); 00675 CHECK_EQUAL( 3, idx ); 00676 err = CN::OppositeSide( MBQUAD, 2, 0, idx, dim ); 00677 CHECK_EQUAL( 0, err ); 00678 CHECK_EQUAL( 0, dim ); 00679 CHECK_EQUAL( 0, idx ); 00680 err = CN::OppositeSide( MBQUAD, 3, 0, idx, dim ); 00681 CHECK_EQUAL( 0, err ); 00682 CHECK_EQUAL( 0, dim ); 00683 CHECK_EQUAL( 1, idx ); 00684 00685 err = CN::OppositeSide( MBQUAD, 0, 1, idx, dim ); 00686 CHECK_EQUAL( 0, err ); 00687 CHECK_EQUAL( 1, dim ); 00688 CHECK_EQUAL( 2, idx ); 00689 err = CN::OppositeSide( MBQUAD, 1, 1, idx, dim ); 00690 CHECK_EQUAL( 0, err ); 00691 CHECK_EQUAL( 1, dim ); 00692 CHECK_EQUAL( 3, idx ); 00693 err = CN::OppositeSide( MBQUAD, 2, 1, idx, dim ); 00694 CHECK_EQUAL( 0, err ); 00695 CHECK_EQUAL( 1, dim ); 00696 CHECK_EQUAL( 0, idx ); 00697 err = CN::OppositeSide( MBQUAD, 3, 1, idx, dim ); 00698 CHECK_EQUAL( 0, err ); 00699 CHECK_EQUAL( 1, dim ); 00700 CHECK_EQUAL( 1, idx ); 00701 } 00702 00703 void test_opposite_side_tet() 00704 { 00705 int idx, dim, err; 00706 00707 err = CN::OppositeSide( MBTET, 0, 0, idx, dim ); 00708 CHECK_EQUAL( 0, err ); 00709 CHECK_EQUAL( 2, dim ); 00710 CHECK_EQUAL( 1, idx ); 00711 err = CN::OppositeSide( MBTET, 1, 0, idx, dim ); 00712 CHECK_EQUAL( 0, err ); 00713 CHECK_EQUAL( 2, dim ); 00714 CHECK_EQUAL( 2, idx ); 00715 err = CN::OppositeSide( MBTET, 2, 0, idx, dim ); 00716 CHECK_EQUAL( 0, err ); 00717 CHECK_EQUAL( 2, dim ); 00718 CHECK_EQUAL( 0, idx ); 00719 err = CN::OppositeSide( MBTET, 3, 0, idx, dim ); 00720 CHECK_EQUAL( 0, err ); 00721 CHECK_EQUAL( 2, dim ); 00722 CHECK_EQUAL( 3, idx ); 00723 00724 err = CN::OppositeSide( MBTET, 0, 2, idx, dim ); 00725 CHECK_EQUAL( 0, err ); 00726 CHECK_EQUAL( 0, dim ); 00727 CHECK_EQUAL( 2, idx ); 00728 err = CN::OppositeSide( MBTET, 1, 2, idx, dim ); 00729 CHECK_EQUAL( 0, err ); 00730 CHECK_EQUAL( 0, dim ); 00731 CHECK_EQUAL( 0, idx ); 00732 err = CN::OppositeSide( MBTET, 2, 2, idx, dim ); 00733 CHECK_EQUAL( 0, err ); 00734 CHECK_EQUAL( 0, dim ); 00735 CHECK_EQUAL( 1, idx ); 00736 err = CN::OppositeSide( MBTET, 3, 2, idx, dim ); 00737 CHECK_EQUAL( 0, err ); 00738 CHECK_EQUAL( 0, dim ); 00739 CHECK_EQUAL( 3, idx ); 00740 00741 err = CN::OppositeSide( MBTET, 0, 1, idx, dim ); 00742 CHECK_EQUAL( 0, err ); 00743 CHECK_EQUAL( 1, dim ); 00744 CHECK_EQUAL( 5, idx ); 00745 err = CN::OppositeSide( MBTET, 1, 1, idx, dim ); 00746 CHECK_EQUAL( 0, err ); 00747 CHECK_EQUAL( 1, dim ); 00748 CHECK_EQUAL( 3, idx ); 00749 err = CN::OppositeSide( MBTET, 2, 1, idx, dim ); 00750 CHECK_EQUAL( 0, err ); 00751 CHECK_EQUAL( 1, dim ); 00752 CHECK_EQUAL( 4, idx ); 00753 err = CN::OppositeSide( MBTET, 3, 1, idx, dim ); 00754 CHECK_EQUAL( 0, err ); 00755 CHECK_EQUAL( 1, dim ); 00756 CHECK_EQUAL( 1, idx ); 00757 err = CN::OppositeSide( MBTET, 4, 1, idx, dim ); 00758 CHECK_EQUAL( 0, err ); 00759 CHECK_EQUAL( 1, dim ); 00760 CHECK_EQUAL( 2, idx ); 00761 err = CN::OppositeSide( MBTET, 5, 1, idx, dim ); 00762 CHECK_EQUAL( 0, err ); 00763 CHECK_EQUAL( 1, dim ); 00764 CHECK_EQUAL( 0, idx ); 00765 } 00766 00767 void test_opposite_side_hex() 00768 { 00769 int idx, dim, err; 00770 00771 err = CN::OppositeSide( MBHEX, 0, 0, idx, dim ); 00772 CHECK_EQUAL( 0, err ); 00773 CHECK_EQUAL( 0, dim ); 00774 CHECK_EQUAL( 6, idx ); 00775 err = CN::OppositeSide( MBHEX, 1, 0, idx, dim ); 00776 CHECK_EQUAL( 0, err ); 00777 CHECK_EQUAL( 0, dim ); 00778 CHECK_EQUAL( 7, idx ); 00779 err = CN::OppositeSide( MBHEX, 2, 0, idx, dim ); 00780 CHECK_EQUAL( 0, err ); 00781 CHECK_EQUAL( 0, dim ); 00782 CHECK_EQUAL( 4, idx ); 00783 err = CN::OppositeSide( MBHEX, 3, 0, idx, dim ); 00784 CHECK_EQUAL( 0, err ); 00785 CHECK_EQUAL( 0, dim ); 00786 CHECK_EQUAL( 5, idx ); 00787 err = CN::OppositeSide( MBHEX, 4, 0, idx, dim ); 00788 CHECK_EQUAL( 0, err ); 00789 CHECK_EQUAL( 0, dim ); 00790 CHECK_EQUAL( 2, idx ); 00791 err = CN::OppositeSide( MBHEX, 5, 0, idx, dim ); 00792 CHECK_EQUAL( 0, err ); 00793 CHECK_EQUAL( 0, dim ); 00794 CHECK_EQUAL( 3, idx ); 00795 err = CN::OppositeSide( MBHEX, 6, 0, idx, dim ); 00796 CHECK_EQUAL( 0, err ); 00797 CHECK_EQUAL( 0, dim ); 00798 CHECK_EQUAL( 0, idx ); 00799 err = CN::OppositeSide( MBHEX, 7, 0, idx, dim ); 00800 CHECK_EQUAL( 0, err ); 00801 CHECK_EQUAL( 0, dim ); 00802 CHECK_EQUAL( 1, idx ); 00803 00804 err = CN::OppositeSide( MBHEX, 0, 1, idx, dim ); 00805 CHECK_EQUAL( 0, err ); 00806 CHECK_EQUAL( 1, dim ); 00807 CHECK_EQUAL( 10, idx ); 00808 err = CN::OppositeSide( MBHEX, 1, 1, idx, dim ); 00809 CHECK_EQUAL( 0, err ); 00810 CHECK_EQUAL( 1, dim ); 00811 CHECK_EQUAL( 11, idx ); 00812 err = CN::OppositeSide( MBHEX, 2, 1, idx, dim ); 00813 CHECK_EQUAL( 0, err ); 00814 CHECK_EQUAL( 1, dim ); 00815 CHECK_EQUAL( 8, idx ); 00816 err = CN::OppositeSide( MBHEX, 3, 1, idx, dim ); 00817 CHECK_EQUAL( 0, err ); 00818 CHECK_EQUAL( 1, dim ); 00819 CHECK_EQUAL( 9, idx ); 00820 err = CN::OppositeSide( MBHEX, 4, 1, idx, dim ); 00821 CHECK_EQUAL( 0, err ); 00822 CHECK_EQUAL( 1, dim ); 00823 CHECK_EQUAL( 6, idx ); 00824 err = CN::OppositeSide( MBHEX, 5, 1, idx, dim ); 00825 CHECK_EQUAL( 0, err ); 00826 CHECK_EQUAL( 1, dim ); 00827 CHECK_EQUAL( 7, idx ); 00828 err = CN::OppositeSide( MBHEX, 6, 1, idx, dim ); 00829 CHECK_EQUAL( 0, err ); 00830 CHECK_EQUAL( 1, dim ); 00831 CHECK_EQUAL( 4, idx ); 00832 err = CN::OppositeSide( MBHEX, 7, 1, idx, dim ); 00833 CHECK_EQUAL( 0, err ); 00834 CHECK_EQUAL( 1, dim ); 00835 CHECK_EQUAL( 5, idx ); 00836 err = CN::OppositeSide( MBHEX, 8, 1, idx, dim ); 00837 CHECK_EQUAL( 0, err ); 00838 CHECK_EQUAL( 1, dim ); 00839 CHECK_EQUAL( 2, idx ); 00840 err = CN::OppositeSide( MBHEX, 9, 1, idx, dim ); 00841 CHECK_EQUAL( 0, err ); 00842 CHECK_EQUAL( 1, dim ); 00843 CHECK_EQUAL( 3, idx ); 00844 err = CN::OppositeSide( MBHEX, 10, 1, idx, dim ); 00845 CHECK_EQUAL( 0, err ); 00846 CHECK_EQUAL( 1, dim ); 00847 CHECK_EQUAL( 0, idx ); 00848 err = CN::OppositeSide( MBHEX, 11, 1, idx, dim ); 00849 CHECK_EQUAL( 0, err ); 00850 CHECK_EQUAL( 1, dim ); 00851 CHECK_EQUAL( 1, idx ); 00852 00853 err = CN::OppositeSide( MBHEX, 0, 2, idx, dim ); 00854 CHECK_EQUAL( 0, err ); 00855 CHECK_EQUAL( 2, dim ); 00856 CHECK_EQUAL( 2, idx ); 00857 err = CN::OppositeSide( MBHEX, 1, 2, idx, dim ); 00858 CHECK_EQUAL( 0, err ); 00859 CHECK_EQUAL( 2, dim ); 00860 CHECK_EQUAL( 3, idx ); 00861 err = CN::OppositeSide( MBHEX, 2, 2, idx, dim ); 00862 CHECK_EQUAL( 0, err ); 00863 CHECK_EQUAL( 2, dim ); 00864 CHECK_EQUAL( 0, idx ); 00865 err = CN::OppositeSide( MBHEX, 3, 2, idx, dim ); 00866 CHECK_EQUAL( 0, err ); 00867 CHECK_EQUAL( 2, dim ); 00868 CHECK_EQUAL( 1, idx ); 00869 err = CN::OppositeSide( MBHEX, 4, 2, idx, dim ); 00870 CHECK_EQUAL( 0, err ); 00871 CHECK_EQUAL( 2, dim ); 00872 CHECK_EQUAL( 5, idx ); 00873 err = CN::OppositeSide( MBHEX, 5, 2, idx, dim ); 00874 CHECK_EQUAL( 0, err ); 00875 CHECK_EQUAL( 2, dim ); 00876 CHECK_EQUAL( 4, idx ); 00877 } 00878 00879 void test_has_mid_nodes( EntityType type ) 00880 { 00881 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00882 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00883 00884 const int dim = CN::Dimension( type ); 00885 // calculate number of valid combinations of ho node flags 00886 int num_comb = 1; 00887 for( int i = 0; i < dim; ++i ) 00888 num_comb *= 2; 00889 // for each valid combination 00890 for( int c = 0; c < num_comb; ++c ) 00891 { 00892 // calculate corresponding number of vertices in element 00893 const int* ho_nodes = combinations[c]; 00894 int num_vtx = CN::VerticesPerEntity( type ); 00895 switch( dim ) 00896 { 00897 case 3: 00898 if( ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 00899 case 2: 00900 if( ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 00901 } 00902 if( ho_nodes[dim] ) ++num_vtx; 00903 00904 CHECK_EQUAL( ho_nodes[1], (int)CN::HasMidEdgeNodes( type, num_vtx ) ); 00905 CHECK_EQUAL( ho_nodes[2], (int)CN::HasMidFaceNodes( type, num_vtx ) ); 00906 CHECK_EQUAL( ho_nodes[3], (int)CN::HasMidRegionNodes( type, num_vtx ) ); 00907 00908 int results[4] = { 0, -1, -1, -1 }; 00909 CN::HasMidNodes( type, num_vtx, results ); 00910 CHECK_EQUAL( 0, !!results[0] ); 00911 CHECK_EQUAL( ho_nodes[1], !!results[1] ); 00912 CHECK_EQUAL( ho_nodes[2], !!results[2] ); 00913 CHECK_EQUAL( ho_nodes[3], !!results[3] ); 00914 } 00915 } 00916 00917 void test_ho_node_parent() 00918 { 00919 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00920 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00921 00922 for( const EntityType* t = elem_types; *t != MBMAXTYPE; ++t ) 00923 { 00924 const EntityType type = *t; 00925 const int dim = CN::Dimension( type ); 00926 // calculate number of valid combinations of ho node flags 00927 int num_comb = 1; 00928 for( int i = 0; i < dim; ++i ) 00929 num_comb *= 2; 00930 // for each valid combination 00931 for( int c = 0; c < num_comb; ++c ) 00932 { 00933 // calculate corresponding number of vertices in element 00934 const int* ho_nodes = combinations[c]; 00935 int num_vtx = CN::VerticesPerEntity( type ); 00936 switch( dim ) 00937 { 00938 case 3: 00939 if( ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 00940 case 2: 00941 if( ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 00942 } 00943 if( ho_nodes[dim] ) ++num_vtx; 00944 00945 // start at first higher-order node 00946 int pos = CN::VerticesPerEntity( type ); 00947 00948 // check mid-edge 00949 if( dim > 1 && ho_nodes[1] ) 00950 { 00951 for( int i = 0; i < CN::NumSubEntities( type, 1 ); ++i ) 00952 { 00953 int pdim = -1, pidx = -1; 00954 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00955 CHECK_EQUAL( 1, pdim ); 00956 CHECK_EQUAL( i, pidx ); 00957 } 00958 } 00959 00960 // check mid-face 00961 if( dim > 2 && ho_nodes[2] ) 00962 { 00963 for( int i = 0; i < CN::NumSubEntities( type, 2 ); ++i ) 00964 { 00965 int pdim = -1, pidx = -1; 00966 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00967 CHECK_EQUAL( 2, pdim ); 00968 CHECK_EQUAL( i, pidx ); 00969 } 00970 } 00971 00972 // check mid-volume 00973 if( ho_nodes[dim] ) 00974 { 00975 int pdim = -1, pidx = -1; 00976 CN::HONodeParent( type, num_vtx, pos++, pdim, pidx ); 00977 CHECK_EQUAL( dim, pdim ); 00978 CHECK_EQUAL( 0, pidx ); 00979 } 00980 } // for ho_node combinatinos 00981 } // for each type 00982 } 00983 00984 void test_ho_node_index() 00985 { 00986 const int combinations[][4] = { { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, 00987 { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { 0, 0, 1, 1 }, { 0, 1, 1, 1 } }; 00988 00989 for( const EntityType* t = elem_types; *t != MBMAXTYPE; ++t ) 00990 { 00991 const EntityType type = *t; 00992 const int dim = CN::Dimension( type ); 00993 // calculate number of valid combinations of ho node flags 00994 int num_comb = 1; 00995 for( int i = 0; i < dim; ++i ) 00996 num_comb *= 2; 00997 // for each valid combination 00998 for( int c = 0; c < num_comb; ++c ) 00999 { 01000 // calculate corresponding number of vertices in element 01001 const int* ho_nodes = combinations[c]; 01002 int num_vtx = CN::VerticesPerEntity( type ); 01003 switch( dim ) 01004 { 01005 case 3: 01006 if( ho_nodes[2] ) num_vtx += CN::NumSubEntities( type, 2 ); 01007 case 2: 01008 if( ho_nodes[1] ) num_vtx += CN::NumSubEntities( type, 1 ); 01009 } 01010 if( ho_nodes[dim] ) ++num_vtx; 01011 01012 // start at first higher-order node 01013 int pos = CN::VerticesPerEntity( type ); 01014 01015 // check mid-edge 01016 if( dim > 1 && ho_nodes[1] ) 01017 { 01018 for( int i = 0; i < CN::NumSubEntities( type, 1 ); ++i ) 01019 { 01020 int idx = CN::HONodeIndex( type, num_vtx, 1, i ); 01021 CHECK_EQUAL( pos++, idx ); 01022 } 01023 } 01024 01025 // check mid-face 01026 if( dim > 2 && ho_nodes[2] ) 01027 { 01028 for( int i = 0; i < CN::NumSubEntities( type, 2 ); ++i ) 01029 { 01030 int idx = CN::HONodeIndex( type, num_vtx, 2, i ); 01031 CHECK_EQUAL( pos++, idx ); 01032 } 01033 } 01034 01035 // check mid-volume 01036 if( ho_nodes[dim] ) 01037 { 01038 int idx = CN::HONodeIndex( type, num_vtx, dim, 0 ); 01039 CHECK_EQUAL( pos++, idx ); 01040 } 01041 } // for ho_node combinatinos 01042 } // for each type 01043 } 01044 01045 void test_sub_entity_nodes( EntityType parent, int sub_dimension ) 01046 { 01047 const int num_corner = CN::VerticesPerEntity( parent ); 01048 const int num_edge = CN::NumSubEntities( parent, 1 ); 01049 const int num_face = CN::NumSubEntities( parent, 2 ); 01050 01051 switch( CN::Dimension( parent ) ) 01052 { 01053 case 3: 01054 test_sub_entity_nodes( parent, num_corner + num_face, sub_dimension ); 01055 test_sub_entity_nodes( parent, num_corner + num_edge + num_face, sub_dimension ); 01056 test_sub_entity_nodes( parent, num_corner + num_face + 1, sub_dimension ); 01057 test_sub_entity_nodes( parent, num_corner + num_edge + num_face + 1, sub_dimension ); 01058 case 2: 01059 test_sub_entity_nodes( parent, num_corner + num_edge, sub_dimension ); 01060 test_sub_entity_nodes( parent, num_corner + num_edge + 1, sub_dimension ); 01061 case 1: 01062 test_sub_entity_nodes( parent, num_corner, sub_dimension ); 01063 test_sub_entity_nodes( parent, num_corner + 1, sub_dimension ); 01064 break; 01065 default: 01066 CHECK( false ); 01067 } 01068 } 01069 01070 void test_sub_entity_nodes( EntityType parent, int num_nodes, int sub_dimension ) 01071 { 01072 const int num_sub = CN::NumSubEntities( parent, sub_dimension ); 01073 const int parent_ho = CN::HasMidNodes( parent, num_nodes ); 01074 int child_ho = 0; 01075 for( int d = 1; d <= sub_dimension; ++d ) 01076 child_ho |= ( parent_ho & ( 1 << d ) ); 01077 01078 // first test the types 01079 for( int i = 0; i < num_sub; ++i ) 01080 { 01081 int num, conn[moab::MAX_SUB_ENTITY_VERTICES]; 01082 EntityType type; 01083 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01084 CHECK_EQUAL( CN::SubEntityType( parent, sub_dimension, i ), type ); 01085 } 01086 01087 // now test that they have the correct number of higher-order node 01088 for( int i = 0; i < num_sub; ++i ) 01089 { 01090 int num, conn[moab::MAX_SUB_ENTITY_VERTICES]; 01091 EntityType type; 01092 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01093 const int ho = CN::HasMidNodes( type, num ); 01094 CHECK_EQUAL( child_ho, ho ); 01095 } 01096 01097 // now test the actual indices 01098 for( int i = 0; i < num_sub; ++i ) 01099 { 01100 int num, conn[moab::MAX_SUB_ENTITY_VERTICES], corners[moab::MAX_SUB_ENTITY_VERTICES]; 01101 EntityType type; 01102 CN::SubEntityNodeIndices( parent, num_nodes, sub_dimension, i, type, num, conn ); 01103 01104 // check corner indices against SubEntityVertexIndices 01105 const int num_corner = CN::VerticesPerEntity( type ); 01106 CHECK( num >= num_corner ); 01107 CN::SubEntityVertexIndices( parent, sub_dimension, i, corners ); 01108 for( int j = 0; j < num_corner; ++j ) 01109 CHECK_EQUAL( corners[j], conn[j] ); 01110 01111 // check mid-edge indices, if present 01112 int idx = num_corner; 01113 if( child_ho & CN::MID_EDGE_BIT ) 01114 { 01115 // for each edge in the sub-entity type 01116 const int num_edge = CN::NumSubEntities( type, 1 ); 01117 for( int j = 0; j < num_edge; ++j ) 01118 { 01119 // get edge indices for sub-entity connectivity 01120 int edge_ends[2]; 01121 CN::SubEntityVertexIndices( type, 1, j, edge_ends ); 01122 // convert to indices into parent type's connectivity 01123 CHECK( edge_ends[0] < num_corner ); 01124 edge_ends[0] = corners[edge_ends[0]]; 01125 CHECK( edge_ends[1] < num_corner ); 01126 edge_ends[1] = corners[edge_ends[1]]; 01127 // find edge index in parent element 01128 int side, sense, off; 01129 int result = CN::SideNumber( parent, edge_ends, 2, 1, side, sense, off ); 01130 CHECK_EQUAL( 0, result ); 01131 // get location in parent entity connectivity for mid-edge node 01132 int loc = CN::HONodeIndex( parent, num_nodes, 1, side ); 01133 CHECK_EQUAL( loc, conn[idx++] ); 01134 } 01135 } 01136 01137 // check mid-face indices, if present 01138 if( child_ho & CN::MID_FACE_BIT ) 01139 { 01140 CHECK_EQUAL( 2, CN::Dimension( type ) ); 01141 int loc = CN::HONodeIndex( parent, num_nodes, 2, i ); 01142 CHECK_EQUAL( loc, conn[idx++] ); 01143 } 01144 01145 // make sure there were no extra node indices returned 01146 CHECK_EQUAL( idx, num ); 01147 } 01148 }