[MOAB-dev] r2555 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Thu Jan 15 16:55:04 CST 2009
Author: kraftche
Date: 2009-01-15 16:55:03 -0600 (Thu, 15 Jan 2009)
New Revision: 2555
Added:
MOAB/trunk/mbcn_test.cc
Modified:
MOAB/trunk/Makefile.am
Log:
Add unit tests for MBCN. Coverage is not complete:
- missing tests for some more obscure functions
- doesn't test many things for MBKNIFE because I don't know what the
connectivity is supposed to be
- doesn't test correct handling of invalid input
Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am 2009-01-15 22:53:32 UTC (rev 2554)
+++ MOAB/trunk/Makefile.am 2009-01-15 22:55:03 UTC (rev 2555)
@@ -33,7 +33,8 @@
var_len_test var_len_test_no_template \
tag_test \
mesh_set_test \
- cub_file_test
+ cub_file_test \
+ mbcn_test
# merge_test \ # input files no longer exist?
# test_tag_server \ # fails
@@ -346,6 +347,8 @@
cub_file_test_LDADD = $(top_builddir)/libMOAB.la
cub_file_test_DEPENDENCIES = $(tag_test_LDADD)
+mbcn_test_SOURCES = MBCN.hpp MBCN.cpp mbcn_test.cc
+mbcn_test_CPPFLAGS = -DSRCDIR=$(srcdir) # define anything to work around build issue
EXTRA_DIST = test.cub quad9.cub hex27.cub
Added: MOAB/trunk/mbcn_test.cc
===================================================================
--- MOAB/trunk/mbcn_test.cc (rev 0)
+++ MOAB/trunk/mbcn_test.cc 2009-01-15 22:55:03 UTC (rev 2555)
@@ -0,0 +1,987 @@
+#include "TestUtil.hpp"
+#include "MBCN.hpp"
+
+void test_dimension_pair();
+void test_type_names();
+void test_dimension();
+void test_vertices_per_entity();
+void test_num_sub_entities();
+
+void test_sub_entity_type_vtx();
+void test_sub_entity_type_edge();
+void test_sub_entity_type_tri();
+void test_sub_entity_type_quad();
+void test_sub_entity_type_tet();
+void test_sub_entity_type_pyr();
+void test_sub_entity_type_pri();
+void test_sub_entity_type_knife();
+void test_sub_entity_type_hex();
+
+void test_sub_entity_indices_vtx();
+void test_sub_entity_indices_edge();
+void test_sub_entity_indices_tri();
+void test_sub_entity_indices_quad();
+void test_sub_entity_indices_tet();
+void test_sub_entity_indices_pyr();
+void test_sub_entity_indices_pri();
+void test_sub_entity_indices_hex();
+
+void test_side_number_tri();
+void test_side_number_quad();
+void test_side_number_tet();
+void test_side_number_pyr();
+void test_side_number_pri();
+void test_side_number_hex();
+
+void test_opposite_side_tri();
+void test_opposite_side_quad();
+void test_opposite_side_tet();
+void test_opposite_side_hex();
+
+void test_has_mid_nodes();
+void test_ho_node_parent();
+void test_ho_node_index();
+
+int main()
+{
+ int result = 0;
+ result += RUN_TEST(test_dimension_pair);
+ result += RUN_TEST(test_type_names);
+ result += RUN_TEST(test_dimension);
+ result += RUN_TEST(test_vertices_per_entity);
+ result += RUN_TEST(test_num_sub_entities);
+
+ result += RUN_TEST(test_sub_entity_type_vtx);
+ result += RUN_TEST(test_sub_entity_type_edge);
+ result += RUN_TEST(test_sub_entity_type_tri);
+ result += RUN_TEST(test_sub_entity_type_quad);
+ result += RUN_TEST(test_sub_entity_type_tet);
+ result += RUN_TEST(test_sub_entity_type_pyr);
+ result += RUN_TEST(test_sub_entity_type_pri);
+ result += RUN_TEST(test_sub_entity_type_knife);
+ result += RUN_TEST(test_sub_entity_type_hex);
+
+ result += RUN_TEST(test_sub_entity_indices_vtx);
+ result += RUN_TEST(test_sub_entity_indices_edge);
+ result += RUN_TEST(test_sub_entity_indices_tri);
+ result += RUN_TEST(test_sub_entity_indices_quad);
+ result += RUN_TEST(test_sub_entity_indices_tet);
+ result += RUN_TEST(test_sub_entity_indices_pyr);
+ result += RUN_TEST(test_sub_entity_indices_pri);
+ result += RUN_TEST(test_sub_entity_indices_hex);
+
+ result += RUN_TEST(test_side_number_tri);
+ result += RUN_TEST(test_side_number_quad);
+ result += RUN_TEST(test_side_number_tet);
+ result += RUN_TEST(test_side_number_pyr);
+ result += RUN_TEST(test_side_number_pri);
+ result += RUN_TEST(test_side_number_hex);
+
+ result += RUN_TEST(test_opposite_side_tri);
+ result += RUN_TEST(test_opposite_side_quad);
+ result += RUN_TEST(test_opposite_side_tet);
+ result += RUN_TEST(test_opposite_side_hex);
+
+ result += RUN_TEST(test_has_mid_nodes);
+ result += RUN_TEST(test_ho_node_parent);
+ result += RUN_TEST(test_ho_node_index);
+ return result;
+}
+
+const MBEntityType elem_types[] = { MBTRI,
+ MBQUAD,
+ MBTET,
+ MBPYRAMID,
+ MBPRISM,
+ MBHEX,
+ MBMAXTYPE };
+const int num_elem_types = sizeof(elem_types)/sizeof(elem_types[0]) - 1;
+
+void test_dimension_pair()
+{
+ MBDimensionPair dp;
+
+ dp = MBCN::TypeDimensionMap[0];
+ CHECK_EQUAL( MBVERTEX, dp.first );
+ CHECK_EQUAL( MBVERTEX, dp.second );
+
+ dp = MBCN::TypeDimensionMap[1];
+ CHECK_EQUAL( MBEDGE, dp.first );
+ CHECK_EQUAL( MBEDGE, dp.second );
+
+ dp = MBCN::TypeDimensionMap[2];
+ CHECK_EQUAL( MBTRI, dp.first );
+ CHECK_EQUAL( MBPOLYGON, dp.second );
+
+ dp = MBCN::TypeDimensionMap[3];
+ CHECK_EQUAL( MBTET, dp.first );
+ CHECK_EQUAL( MBPOLYHEDRON, dp.second );
+}
+
+void test_type_names()
+{
+ for (MBEntityType t = MBVERTEX; t != MBMAXTYPE; ++t) {
+ const char* name = MBCN::EntityTypeName(t);
+ CHECK_EQUAL( t, MBCN::EntityTypeFromName(name) );
+ }
+}
+
+void test_dimension()
+{
+ CHECK_EQUAL( 0, MBCN::Dimension(MBVERTEX) );
+ CHECK_EQUAL( 1, MBCN::Dimension(MBEDGE) );
+ CHECK_EQUAL( 2, MBCN::Dimension(MBTRI) );
+ CHECK_EQUAL( 2, MBCN::Dimension(MBQUAD) );
+ CHECK_EQUAL( 2, MBCN::Dimension(MBPOLYGON) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBTET) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBPYRAMID) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBPRISM) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBKNIFE) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBHEX) );
+ CHECK_EQUAL( 3, MBCN::Dimension(MBPOLYHEDRON) );
+}
+
+void test_vertices_per_entity()
+{
+ CHECK_EQUAL( 1, MBCN::VerticesPerEntity(MBVERTEX) );
+ CHECK_EQUAL( 2, MBCN::VerticesPerEntity(MBEDGE) );
+ CHECK_EQUAL( 3, MBCN::VerticesPerEntity(MBTRI) );
+ CHECK_EQUAL( 4, MBCN::VerticesPerEntity(MBQUAD) );
+ CHECK_EQUAL( 4, MBCN::VerticesPerEntity(MBTET) );
+ CHECK_EQUAL( 5, MBCN::VerticesPerEntity(MBPYRAMID) );
+ CHECK_EQUAL( 6, MBCN::VerticesPerEntity(MBPRISM) );
+ CHECK_EQUAL( 7, MBCN::VerticesPerEntity(MBKNIFE) );
+ CHECK_EQUAL( 8, MBCN::VerticesPerEntity(MBHEX) );
+}
+
+void test_num_sub_entities()
+{
+ CHECK_EQUAL( 1, MBCN::NumSubEntities(MBVERTEX, 0));
+
+ CHECK_EQUAL( 2, MBCN::NumSubEntities(MBEDGE, 0));
+ CHECK_EQUAL( 1, MBCN::NumSubEntities(MBEDGE, 1));
+
+ CHECK_EQUAL( 3, MBCN::NumSubEntities(MBTRI, 0));
+ CHECK_EQUAL( 3, MBCN::NumSubEntities(MBTRI, 1));
+ CHECK_EQUAL( 1, MBCN::NumSubEntities(MBTRI, 2));
+
+ CHECK_EQUAL( 4, MBCN::NumSubEntities(MBQUAD, 0));
+ CHECK_EQUAL( 4, MBCN::NumSubEntities(MBQUAD, 1));
+ CHECK_EQUAL( 1, MBCN::NumSubEntities(MBQUAD, 2));
+
+ CHECK_EQUAL( 4, MBCN::NumSubEntities(MBTET, 0));
+ CHECK_EQUAL( 6, MBCN::NumSubEntities(MBTET, 1));
+ CHECK_EQUAL( 4, MBCN::NumSubEntities(MBTET, 2));
+
+ CHECK_EQUAL( 5, MBCN::NumSubEntities(MBPYRAMID, 0));
+ CHECK_EQUAL( 8, MBCN::NumSubEntities(MBPYRAMID, 1));
+ CHECK_EQUAL( 5, MBCN::NumSubEntities(MBPYRAMID, 2));
+
+ CHECK_EQUAL( 6, MBCN::NumSubEntities(MBPRISM, 0));
+ CHECK_EQUAL( 9, MBCN::NumSubEntities(MBPRISM, 1));
+ CHECK_EQUAL( 5, MBCN::NumSubEntities(MBPRISM, 2));
+
+ CHECK_EQUAL( 7, MBCN::NumSubEntities(MBKNIFE, 0));
+ CHECK_EQUAL( 8, MBCN::NumSubEntities(MBKNIFE, 1));
+ CHECK_EQUAL( 5, MBCN::NumSubEntities(MBKNIFE, 2));
+
+ CHECK_EQUAL( 8, MBCN::NumSubEntities(MBHEX, 0));
+ CHECK_EQUAL( 12, MBCN::NumSubEntities(MBHEX, 1));
+ CHECK_EQUAL( 6, MBCN::NumSubEntities(MBHEX, 2));
+}
+
+void do_test_sub_entity_type_2d( MBEntityType type )
+{
+ for (int j = 0; j < MBCN::VerticesPerEntity(type); ++j) {
+ CHECK_EQUAL( MBVERTEX, MBCN::SubEntityType(type, 0, j ) );
+ CHECK_EQUAL( MBEDGE, MBCN::SubEntityType(type, 1, j ) );
+ }
+ CHECK_EQUAL( type, MBCN::SubEntityType(type, 2, 0) );
+}
+
+void do_test_sub_entity_type_3d( MBEntityType type,
+ int num_faces,
+ const MBEntityType* face_types )
+{
+ for (int j = 0; j < MBCN::VerticesPerEntity(type); ++j) {
+ CHECK_EQUAL( MBVERTEX, MBCN::SubEntityType(type, 0, j ) );
+ }
+
+ for (int j = 0; j < MBCN::NumSubEntities(type,1); ++j) {
+ CHECK_EQUAL( MBEDGE, MBCN::SubEntityType(type, 1, j ) );
+ }
+
+ for (int j = 0; j < num_faces; ++j) {
+ MBEntityType sub_type = MBCN::SubEntityType( type, 2, j );
+ CHECK_EQUAL( face_types[j], sub_type );
+ }
+
+ CHECK_EQUAL( type, MBCN::SubEntityType(type, 3, 0) );
+}
+
+void test_sub_entity_type_vtx()
+{
+ CHECK_EQUAL( MBVERTEX, MBCN::SubEntityType(MBVERTEX, 0, 0 ));
+}
+
+void test_sub_entity_type_edge()
+{
+ CHECK_EQUAL( MBVERTEX, MBCN::SubEntityType(MBEDGE, 0, 0 ));
+ CHECK_EQUAL( MBVERTEX, MBCN::SubEntityType(MBEDGE, 0, 1 ));
+ CHECK_EQUAL( MBEDGE , MBCN::SubEntityType(MBEDGE, 1, 0 ));
+}
+
+void test_sub_entity_type_tri()
+{
+ do_test_sub_entity_type_2d(MBTRI);
+}
+
+void test_sub_entity_type_quad()
+{
+ do_test_sub_entity_type_2d(MBQUAD);
+}
+
+void test_sub_entity_type_tet()
+{
+ const MBEntityType types[] = { MBTRI, MBTRI, MBTRI, MBTRI };
+ do_test_sub_entity_type_3d( MBTET, sizeof(types)/sizeof(types[0]), types );
+}
+
+void test_sub_entity_type_pyr()
+{
+ const MBEntityType types[] = { MBQUAD, MBTRI, MBTRI, MBTRI, MBTRI };
+ do_test_sub_entity_type_3d( MBPYRAMID, sizeof(types)/sizeof(types[0]), types );
+}
+
+void test_sub_entity_type_pri()
+{
+ const MBEntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBTRI, MBTRI };
+ do_test_sub_entity_type_3d( MBPRISM, sizeof(types)/sizeof(types[0]), types );
+}
+
+void test_sub_entity_type_knife()
+{
+ const MBEntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD };
+ do_test_sub_entity_type_3d( MBKNIFE, sizeof(types)/sizeof(types[0]), types );
+}
+
+void test_sub_entity_type_hex()
+{
+ const MBEntityType types[] = { MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD, MBQUAD };
+ do_test_sub_entity_type_3d( MBHEX, sizeof(types)/sizeof(types[0]), types );
+}
+
+
+void test_0d_sub_entity_indices( MBEntityType type, int num_vtx )
+{
+ for (int i = 0; i < num_vtx; ++i) {
+ // zero input array
+ int indices[2] = { 0, -100 };
+ // check correct results
+ MBCN::SubEntityVertexIndices( type, 0, i, indices );
+ CHECK_EQUAL( i, indices[0] );
+ // check didn't write past end of array
+ CHECK_EQUAL( -100, indices[1] );
+ }
+}
+
+void test_1d_sub_entity_indices( MBEntityType type, int num_edges,
+ const int (*edge_indices)[2] )
+{
+ for (int i = 0; i < num_edges; ++i) {
+ // zero input array
+ int indices[3] = { 0, 0, -99 };
+ // check correct results
+ MBCN::SubEntityVertexIndices( type, 1, i, indices );
+ if (edge_indices[i][0] == indices[0]) {
+ CHECK_EQUAL( edge_indices[i][1], indices[1] );
+ }
+ else {
+ CHECK_EQUAL( edge_indices[i][0], indices[1] );
+ CHECK_EQUAL( edge_indices[i][1], indices[0] );
+ }
+ // check didn't write past end of array
+ CHECK_EQUAL( -99, indices[2] );
+ }
+}
+
+void test_2d_sub_entity_indices( MBEntityType type, int num_faces,
+ const int (*face_indices)[5] )
+{
+ for (int i = 0; i < num_faces; ++i) {
+ // zero input array
+ int indices[5] = { 0, 0, 0, -99, -99 };
+ // check correct results
+ MBCN::SubEntityVertexIndices( type, 2, i, indices );
+ const int num_vtx = face_indices[i][0];
+ if (num_vtx != 3) CHECK_EQUAL( 4, num_vtx );
+ const int* exp_index = face_indices[i] + 1;
+ int off = std::find( indices, indices+num_vtx, exp_index[0] ) - indices;
+ CHECK( off < num_vtx );
+ /* Expect faces to be ordered such that CCW normal is outwards
+ *
+ bool reverse = indices[(off+num_vtx-1)%num_vtx] == exp_index[1];
+ if (reverse) {
+ CHECK_EQUAL( exp_index[1], indices[(off+num_vtx-1)%num_vtx] );
+ CHECK_EQUAL( exp_index[2], indices[(off+num_vtx-2)%num_vtx] );
+ if (num_vtx == 4)
+ CHECK_EQUAL( exp_index[3], indices[(off+num_vtx-3)%num_vtx] );
+ }
+ else {
+ */
+ CHECK_EQUAL( exp_index[1], indices[(off+1)%num_vtx] );
+ CHECK_EQUAL( exp_index[2], indices[(off+2)%num_vtx] );
+ if (num_vtx == 4)
+ CHECK_EQUAL( exp_index[3], indices[(off+3)%num_vtx] );
+ /*
+ }
+ */
+
+ // check didn't write past end of array
+ if (num_vtx == 3)
+ CHECK_EQUAL( -99, indices[3] );
+ CHECK_EQUAL( -99, indices[4] );
+ }
+}
+
+void test_elem_as_sub_entity( MBEntityType type, int dim, int num_vertices )
+{
+ int indices[9] = { -2, -2, -2, -2, -2, -2, -2, -2, -2 };
+ MBCN::SubEntityVertexIndices( type, dim, 0, indices );
+ for (int i = 0; i < num_vertices; ++i)
+ CHECK_EQUAL( i, indices[i] );
+ // make sure didn't write past end
+ CHECK_EQUAL( -2, indices[num_vertices] );
+}
+
+void test_sub_entity_indices_vtx()
+{
+ test_elem_as_sub_entity( MBVERTEX, 0, 1 );
+}
+
+void test_sub_entity_indices_edge()
+{
+ test_0d_sub_entity_indices( MBEDGE, 2 );
+ test_elem_as_sub_entity( MBEDGE, 1, 2 );
+}
+
+void test_sub_entity_indices_tri()
+{
+ const int edges[3][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 0 } };
+ test_0d_sub_entity_indices( MBTRI, 3 );
+ test_1d_sub_entity_indices( MBTRI, 3, edges );
+ test_elem_as_sub_entity( MBTRI, 2, 3 );
+}
+
+void test_sub_entity_indices_quad()
+{
+ const int edges[4][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 3 },
+ { 3, 0 } };
+ test_0d_sub_entity_indices( MBQUAD, 4 );
+ test_1d_sub_entity_indices( MBQUAD, 4, edges );
+ test_elem_as_sub_entity( MBQUAD, 2, 4 );
+}
+
+void test_sub_entity_indices_tet()
+{
+ const MBEntityType type = MBTET;
+ const int num_vtx = 4;
+ const int edges[][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 0 },
+ { 0, 3 },
+ { 1, 3 },
+ { 2, 3 } };
+ const int faces[][5] = { { 3, 0, 1, 3, 0 },
+ { 3, 1, 2, 3, 0 },
+ { 3, 2, 0, 3, 0 },
+ { 3, 2, 1, 0, 0 } };
+ test_0d_sub_entity_indices( type, num_vtx );
+ test_1d_sub_entity_indices( type, sizeof(edges)/sizeof(edges[0]), edges );
+ test_2d_sub_entity_indices( type, sizeof(faces)/sizeof(faces[0]), faces );
+ test_elem_as_sub_entity( type, 3, num_vtx );
+}
+
+void test_sub_entity_indices_pyr()
+{
+ const MBEntityType type = MBPYRAMID;
+ const int num_vtx = 5;
+ const int edges[][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 3 },
+ { 3, 0 },
+ { 0, 4 },
+ { 1, 4 },
+ { 2, 4 },
+ { 3, 4 } };
+ const int faces[][5] = { { 4, 3, 2, 1, 0 },
+ { 3, 0, 1, 4, 0 },
+ { 3, 1, 2, 4, 0 },
+ { 3, 2, 3, 4, 0 },
+ { 3, 3, 0, 4, 0 } };
+ test_0d_sub_entity_indices( type, num_vtx );
+ test_1d_sub_entity_indices( type, sizeof(edges)/sizeof(edges[0]), edges );
+ test_2d_sub_entity_indices( type, sizeof(faces)/sizeof(faces[0]), faces );
+ test_elem_as_sub_entity( type, 3, num_vtx );
+}
+
+void test_sub_entity_indices_pri()
+{
+ const MBEntityType type = MBPRISM;
+ const int num_vtx = 6;
+ const int edges[][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 0 },
+ { 0, 3 },
+ { 1, 4 },
+ { 2, 5 },
+ { 3, 4 },
+ { 4, 5 },
+ { 5, 3 } };
+ const int faces[][5] = { { 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 } };
+ test_0d_sub_entity_indices( type, num_vtx );
+ test_1d_sub_entity_indices( type, sizeof(edges)/sizeof(edges[0]), edges );
+ test_2d_sub_entity_indices( type, sizeof(faces)/sizeof(faces[0]), faces );
+ test_elem_as_sub_entity( type, 3, num_vtx );
+}
+
+void test_sub_entity_indices_hex()
+{
+ const MBEntityType type = MBHEX;
+ const int num_vtx = 8;
+ const int edges[][2] = { { 0, 1 },
+ { 1, 2 },
+ { 2, 3 },
+ { 3, 0 },
+ { 0, 4 },
+ { 1, 5 },
+ { 2, 6 },
+ { 3, 7 },
+ { 4, 5 },
+ { 5, 6 },
+ { 6, 7 },
+ { 7, 4 } };
+ const int faces[][5] = { { 4, 0, 1, 5, 4 },
+ { 4, 1, 2, 6, 5 },
+ { 4, 2, 3, 7, 6 },
+ { 4, 3, 0, 4, 7 },
+ { 4, 3, 2, 1, 0 },
+ { 4, 4, 5, 6, 7 } };
+ test_0d_sub_entity_indices( type, num_vtx );
+ test_1d_sub_entity_indices( type, sizeof(edges)/sizeof(edges[0]), edges );
+ test_2d_sub_entity_indices( type, sizeof(faces)/sizeof(faces[0]), faces );
+ test_elem_as_sub_entity( type, 3, num_vtx );
+}
+
+static void do_test_side_number_1d( MBEntityType type, int idx )
+{
+ // define a random handle list
+ const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 };
+ // get side indices
+ int side_idx[4] = { 0, 0 };
+ MBCN::SubEntityVertexIndices( type, 1, idx, side_idx );
+
+ // "reversed" and "offset" are the same thing for edges.
+ int side_conn[2] = { elem_verts[side_idx[0]], elem_verts[side_idx[1]] };
+ int rev_conn[2] = { elem_verts[side_idx[1]], elem_verts[side_idx[0]] };
+ int result_side = -100, result_sense = -100, result_offset = -100;
+ int err= MBCN::SideNumber( type, elem_verts, side_conn, 2, 1,
+ result_side, result_sense, result_offset );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( idx, result_side );
+ CHECK_EQUAL( 1, result_sense );
+ CHECK_EQUAL( 0, result_offset);
+ err= MBCN::SideNumber( type, elem_verts, rev_conn, 2, 1,
+ result_side, result_sense, result_offset );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( idx, result_side );
+ CHECK(result_offset == 1 || result_sense == -1);
+}
+
+static void do_test_side_number_2d( MBEntityType type, int idx )
+{
+ // define a random handle list
+ const int elem_verts[] = { 7400, 6233, 3027, 0454, 6839, 5391, 7735, 3603 };
+ // get side indices
+ const int side_size = MBCN::VerticesPerEntity( MBCN::SubEntityType( type, 2, idx ) );
+ int side_idx[4] = { 0, 0, 0, 0 };
+ MBCN::SubEntityVertexIndices( type, 2, idx, side_idx );
+
+ // for each possible forward or reverse offset
+ for (int rev = -1; rev < 2; rev += 2) {
+ for (int off = 0; off < side_size; ++off) {
+ int side_conn[4]; side_conn[3] = 0;
+ for (int i = 0; i < side_size; ++i)
+ side_conn[(i+side_size-rev*off)%side_size] = elem_verts[side_idx[i]];
+
+ int result_side = -100, result_sense = -100, result_offset = -100;
+ int err = MBCN::SideNumber( type, elem_verts, side_conn, side_size, 2,
+ result_side, result_sense, result_offset );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( idx, result_side );
+ CHECK_EQUAL( 1-2*rev, result_sense );
+ CHECK_EQUAL( off, result_offset );
+ }
+ }
+}
+
+void test_side_number_tri()
+{
+ for (int side = 0; side < 3; ++side)
+ do_test_side_number_1d( MBTRI, side );
+}
+
+void test_side_number_quad()
+{
+ for (int side = 0; side < 4; ++side)
+ do_test_side_number_1d( MBQUAD, side );
+}
+
+void test_side_number_tet()
+{
+ for (int edge = 0; edge < 6; ++edge)
+ do_test_side_number_1d( MBTET, edge );
+ for (int face = 0; face < 4; ++face)
+ do_test_side_number_1d( MBTET, face );
+}
+
+void test_side_number_pyr()
+{
+ for (int edge = 0; edge < 8; ++edge)
+ do_test_side_number_1d( MBPYRAMID, edge );
+ for (int face = 0; face < 5; ++face)
+ do_test_side_number_1d( MBPYRAMID, face );
+}
+
+void test_side_number_pri()
+{
+ for (int edge = 0; edge < 9; ++edge)
+ do_test_side_number_1d( MBPRISM, edge );
+ for (int face = 0; face < 5; ++face)
+ do_test_side_number_1d( MBPRISM, face );
+}
+
+void test_side_number_hex()
+{
+ for (int edge = 0; edge < 12; ++edge)
+ do_test_side_number_1d( MBHEX, edge );
+ for (int face = 0; face < 8; ++face)
+ do_test_side_number_1d( MBHEX, face );
+}
+
+
+void test_opposite_side_tri()
+{
+ int idx, dim, err;
+ err = MBCN::OppositeSide( MBTRI, 0, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 1, idx );
+ err = MBCN::OppositeSide( MBTRI, 1, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBTRI, 2, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBTRI, 0, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBTRI, 1, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBTRI, 2, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 1, idx );
+}
+
+void test_opposite_side_quad()
+{
+ int idx, dim, err;
+ err = MBCN::OppositeSide( MBQUAD, 0, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBQUAD, 1, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBQUAD, 2, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBQUAD, 3, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 1, idx );
+
+ err = MBCN::OppositeSide( MBQUAD, 0, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBQUAD, 1, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBQUAD, 2, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBQUAD, 3, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 1, idx );
+}
+
+void test_opposite_side_tet()
+{
+ int idx, dim, err;
+
+ err = MBCN::OppositeSide( MBTET, 0, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 1, idx );
+ err = MBCN::OppositeSide( MBTET, 1, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBTET, 2, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBTET, 3, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 3, idx );
+
+ err = MBCN::OppositeSide( MBTET, 0, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBTET, 1, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBTET, 2, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 1, idx );
+ err = MBCN::OppositeSide( MBTET, 3, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 3, idx );
+
+ err = MBCN::OppositeSide( MBTET, 0, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 5, idx );
+ err = MBCN::OppositeSide( MBTET, 1, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBTET, 2, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 4, idx );
+ err = MBCN::OppositeSide( MBTET, 3, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 1, idx );
+ err = MBCN::OppositeSide( MBTET, 4, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBTET, 5, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 0, idx );
+
+}
+
+void test_opposite_side_hex()
+{
+ int idx, dim, err;
+
+ err = MBCN::OppositeSide( MBHEX, 0, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 6, idx );
+ err = MBCN::OppositeSide( MBHEX, 1, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 7, idx );
+ err = MBCN::OppositeSide( MBHEX, 2, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 4, idx );
+ err = MBCN::OppositeSide( MBHEX, 3, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 5, idx );
+ err = MBCN::OppositeSide( MBHEX, 4, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBHEX, 5, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBHEX, 6, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBHEX, 7, 0, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 0, dim );
+ CHECK_EQUAL( 1, idx );
+
+ err = MBCN::OppositeSide( MBHEX, 0, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 10, idx );
+ err = MBCN::OppositeSide( MBHEX, 1, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 11, idx );
+ err = MBCN::OppositeSide( MBHEX, 2, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 8, idx );
+ err = MBCN::OppositeSide( MBHEX, 3, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 9, idx );
+ err = MBCN::OppositeSide( MBHEX, 4, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 6, idx );
+ err = MBCN::OppositeSide( MBHEX, 5, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 7, idx );
+ err = MBCN::OppositeSide( MBHEX, 6, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 4, idx );
+ err = MBCN::OppositeSide( MBHEX, 7, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 5, idx );
+ err = MBCN::OppositeSide( MBHEX, 8, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBHEX, 9, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBHEX, 10, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBHEX, 11, 1, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 1, dim );
+ CHECK_EQUAL( 1, idx );
+
+ err = MBCN::OppositeSide( MBHEX, 0, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 2, idx );
+ err = MBCN::OppositeSide( MBHEX, 1, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 3, idx );
+ err = MBCN::OppositeSide( MBHEX, 2, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 0, idx );
+ err = MBCN::OppositeSide( MBHEX, 3, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 1, idx );
+ err = MBCN::OppositeSide( MBHEX, 4, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 5, idx );
+ err = MBCN::OppositeSide( MBHEX, 5, 2, idx, dim );
+ CHECK_EQUAL( 0, err );
+ CHECK_EQUAL( 2, dim );
+ CHECK_EQUAL( 4, idx );
+}
+
+void test_has_mid_nodes()
+{
+ const int combinations[][4] = { { 0, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 1, 1, 0 },
+ { 0, 0, 0, 1 },
+ { 0, 1, 0, 1 },
+ { 0, 0, 1, 1 },
+ { 0, 1, 1, 1 } };
+
+ for (const MBEntityType* t = elem_types; *t != MBMAXTYPE; ++t) {
+ const MBEntityType type = *t;
+ const int dim = MBCN::Dimension(type);
+ // calculate number of valid combinations of ho node flags
+ int num_comb = 1;
+ for (int i = 0; i < dim; ++i)
+ num_comb *= 2;
+ // for each valid combination
+ for (int c = 0; c < num_comb; ++c) {
+ // calculate corresponding number of vertices in element
+ const int* ho_nodes = combinations[c];
+ int num_vtx = MBCN::VerticesPerEntity(type);
+ switch (dim) {
+ case 3: if (ho_nodes[2]) num_vtx += MBCN::NumSubEntities(type,2);
+ case 2: if (ho_nodes[1]) num_vtx += MBCN::NumSubEntities(type,1);
+ }
+ if (ho_nodes[dim]) ++num_vtx;
+
+ CHECK_EQUAL( ho_nodes[1], (int)MBCN::HasMidEdgeNodes( type, num_vtx ) );
+ CHECK_EQUAL( ho_nodes[2], (int)MBCN::HasMidFaceNodes( type, num_vtx ) );
+ CHECK_EQUAL( ho_nodes[3], (int)MBCN::HasMidRegionNodes( type, num_vtx ) );
+
+ int results[4] = { 0, -1, -1, -1 };
+ MBCN::HasMidNodes( type, num_vtx, results );
+ CHECK_EQUAL( 0, results[0] );
+ CHECK_EQUAL( ho_nodes[1], results[1] );
+ CHECK_EQUAL( ho_nodes[2], results[2] );
+ CHECK_EQUAL( ho_nodes[3], results[3] );
+ }
+ }
+}
+
+void test_ho_node_parent()
+{
+ const int combinations[][4] = { { 0, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 1, 1, 0 },
+ { 0, 0, 0, 1 },
+ { 0, 1, 0, 1 },
+ { 0, 0, 1, 1 },
+ { 0, 1, 1, 1 } };
+
+ for (const MBEntityType* t = elem_types; *t != MBMAXTYPE; ++t) {
+ const MBEntityType type = *t;
+ const int dim = MBCN::Dimension(type);
+ // calculate number of valid combinations of ho node flags
+ int num_comb = 1;
+ for (int i = 0; i < dim; ++i)
+ num_comb *= 2;
+ // for each valid combination
+ for (int c = 0; c < num_comb; ++c) {
+ // calculate corresponding number of vertices in element
+ const int* ho_nodes = combinations[c];
+ int num_vtx = MBCN::VerticesPerEntity(type);
+ switch (dim) {
+ case 3: if (ho_nodes[2]) num_vtx += MBCN::NumSubEntities(type,2);
+ case 2: if (ho_nodes[1]) num_vtx += MBCN::NumSubEntities(type,1);
+ }
+ if (ho_nodes[dim]) ++num_vtx;
+
+ // start at first higher-order node
+ int pos = MBCN::VerticesPerEntity(type);
+
+ // check mid-edge
+ if (dim > 1 && ho_nodes[1]) {
+ for (int i = 0; i < MBCN::NumSubEntities(type,1); ++i) {
+ int pdim = -1, pidx = -1;
+ MBCN::HONodeParent( type, num_vtx, pos++, pdim, pidx );
+ CHECK_EQUAL( 1, pdim );
+ CHECK_EQUAL( i, pidx );
+ }
+ }
+
+ // check mid-face
+ if (dim > 2 && ho_nodes[2]) {
+ for (int i = 0; i < MBCN::NumSubEntities(type,2); ++i) {
+ int pdim = -1, pidx = -1;
+ MBCN::HONodeParent( type, num_vtx, pos++, pdim, pidx );
+ CHECK_EQUAL( 2, pdim );
+ CHECK_EQUAL( i, pidx );
+ }
+ }
+
+ // check mid-volume
+ if (ho_nodes[dim]) {
+ int pdim = -1, pidx = -1;
+ MBCN::HONodeParent( type, num_vtx, pos++, pdim, pidx );
+ CHECK_EQUAL( dim, pdim );
+ CHECK_EQUAL( 0, pidx );
+ }
+ } // for ho_node combinatinos
+ } // for each type
+}
+
+void test_ho_node_index()
+{
+ const int combinations[][4] = { { 0, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 1, 1, 0 },
+ { 0, 0, 0, 1 },
+ { 0, 1, 0, 1 },
+ { 0, 0, 1, 1 },
+ { 0, 1, 1, 1 } };
+
+ for (const MBEntityType* t = elem_types; *t != MBMAXTYPE; ++t) {
+ const MBEntityType type = *t;
+ const int dim = MBCN::Dimension(type);
+ // calculate number of valid combinations of ho node flags
+ int num_comb = 1;
+ for (int i = 0; i < dim; ++i)
+ num_comb *= 2;
+ // for each valid combination
+ for (int c = 0; c < num_comb; ++c) {
+ // calculate corresponding number of vertices in element
+ const int* ho_nodes = combinations[c];
+ int num_vtx = MBCN::VerticesPerEntity(type);
+ switch (dim) {
+ case 3: if (ho_nodes[2]) num_vtx += MBCN::NumSubEntities(type,2);
+ case 2: if (ho_nodes[1]) num_vtx += MBCN::NumSubEntities(type,1);
+ }
+ if (ho_nodes[dim]) ++num_vtx;
+
+ // start at first higher-order node
+ int pos = MBCN::VerticesPerEntity(type);
+
+ // check mid-edge
+ if (dim > 1 && ho_nodes[1]) {
+ for (int i = 0; i < MBCN::NumSubEntities(type,1); ++i) {
+ int idx = MBCN::HONodeIndex( type, num_vtx, 1, i );
+ CHECK_EQUAL( pos++, idx );
+ }
+ }
+
+ // check mid-face
+ if (dim > 2 && ho_nodes[2]) {
+ for (int i = 0; i < MBCN::NumSubEntities(type,2); ++i) {
+ int idx = MBCN::HONodeIndex( type, num_vtx, 2, i );
+ CHECK_EQUAL( pos++, idx );
+ }
+ }
+
+ // check mid-volume
+ if (ho_nodes[dim]) {
+ int idx = MBCN::HONodeIndex( type, num_vtx, dim, 0 );
+ CHECK_EQUAL( pos++, idx );
+ }
+ } // for ho_node combinatinos
+ } // for each type
+}
+
More information about the moab-dev
mailing list