MOAB: Mesh Oriented datABase  (version 5.2.1)
mbcn_test.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines