MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "Mesquite.hpp" 00002 #include "PatchData.hpp" 00003 #include "SphericalDomain.hpp" 00004 #include "BoundedCylinderDomain.hpp" 00005 #include <cppunit/extensions/HelperMacros.h> 00006 #include <iostream> 00007 00008 const double EPSILON = 1e-6; 00009 #define ASSERT_VECTORS_EQUAL( A, B ) CPPUNIT_ASSERT( ( ( A ) - ( B ) ).length() < EPSILON ) 00010 00011 using namespace MBMesquite; 00012 00013 using std::cerr; 00014 using std::cout; 00015 using std::endl; 00016 00017 class PatchDataTestNormals : public CppUnit::TestFixture 00018 { 00019 private: 00020 CPPUNIT_TEST_SUITE( PatchDataTestNormals ); 00021 // CPPUNIT_TEST (test_get_vertex_normals_infinite_domain); 00022 // CPPUNIT_TEST (test_get_vertex_normals_bounded_domain); 00023 CPPUNIT_TEST( test_get_corner_normals_infinite_domain ); 00024 CPPUNIT_TEST( test_get_corner_normals_bounded_domain ); 00025 CPPUNIT_TEST( test_get_element_normals_infinite_domain ); 00026 CPPUNIT_TEST( test_get_element_normals_bounded_domain ); 00027 CPPUNIT_TEST_SUITE_END(); 00028 00029 PatchData boundedMesh, unboundedMesh; 00030 BoundedCylinderDomain boundedDomain; 00031 SphericalDomain unboundedDomain; 00032 00033 public: 00034 PatchDataTestNormals() : boundedDomain( 1 ), unboundedDomain( Vector3D( 0, 0, 0 ), 1 ) {} 00035 00036 void setUp(); 00037 00038 void tearDown() {} 00039 00040 // void test_get_vertex_normals_infinite_domain(); 00041 // void test_get_vertex_normals_bounded_domain(); 00042 void test_get_corner_normals_infinite_domain(); 00043 void test_get_corner_normals_bounded_domain(); 00044 void test_get_element_normals_infinite_domain(); 00045 void test_get_element_normals_bounded_domain(); 00046 }; 00047 00048 void PatchDataTestNormals::setUp() 00049 { 00050 MsqPrintError err( cout ); 00051 00052 // Define a mesh on the unit sphere 00053 // Make six quads corresponding to the six faces 00054 // of a cube inscribed in the sphere 00055 const double T = 1.0 / sqrt( 3.0 ); 00056 double ucoords[] = { T, -T, -T, T, T, -T, -T, T, -T, -T, -T, -T, T, -T, T, T, T, T, -T, T, T, -T, -T, T }; 00057 size_t uconn[] = { 00058 3, 2, 1, 0, // -Z face 00059 4, 5, 6, 7, // +Z face 00060 0, 1, 5, 4, // +X face 00061 1, 2, 6, 5, // +Y face 00062 2, 3, 7, 6, // -X face 00063 3, 0, 4, 7 // -Y face 00064 }; 00065 unboundedMesh.fill( 8, ucoords, 6, QUADRILATERAL, uconn, 0, err ); 00066 CPPUNIT_ASSERT( !err ); 00067 unboundedMesh.set_domain( &unboundedDomain ); 00068 00069 // Define a mesh on a cylinder with a radius of 00070 // one that is capped at z = +/- 2. Define the 00071 // mesh as the 8 quads defining the sides of a pair of cubes 00072 // stacked axially in the cylinder 00073 const double V = 1.0 / sqrt( 2.0 ); 00074 double bcoords[] = { V, -V, -2, V, V, -2, -V, V, -2, -V, -V, -2, 00075 00076 V, -V, 0, V, V, 0, -V, V, 0, -V, -V, 0, 00077 00078 V, -V, 2, V, V, 2, -V, V, 2, -V, -V, 2 }; 00079 size_t bconn[] = { 00080 // lower cube side faces 00081 0, 1, 5, 4, // +X face 00082 1, 2, 6, 5, // +Y face 00083 2, 3, 7, 6, // -X face 00084 3, 0, 4, 7, // -Y face 00085 // upper cube side faces 00086 4, 5, 9, 8, // +X face 00087 5, 6, 10, 9, // +Y face 00088 6, 7, 11, 10, // -X face 00089 7, 4, 8, 11, // -Y face 00090 }; 00091 boundedMesh.fill( 12, bcoords, 8, QUADRILATERAL, bconn, 0, err ); 00092 CPPUNIT_ASSERT( !err ); 00093 boundedMesh.set_domain( &boundedDomain ); 00094 00095 // set element and vertex handles arrays 00096 size_t i = 0; 00097 for( i = 0; i < 12; ++i ) 00098 boundedMesh.get_vertex_handles_array()[i] = (Mesh::VertexHandle)i; 00099 for( i = 0; i < 8; ++i ) 00100 boundedMesh.get_element_handles_array()[i] = (Mesh::ElementHandle)i; 00101 00102 // Bound the unit cylinder at +/- 1 on the z axis 00103 std::vector< Mesh::VertexHandle > upper_curve( 4 ), lower_curve( 4 ); 00104 for( i = 0; i < 4; ++i ) 00105 { 00106 lower_curve[i] = (Mesh::VertexHandle)i; 00107 upper_curve[i] = ( Mesh::VertexHandle )( i + 8 ); 00108 } 00109 boundedDomain.create_curve( -2, lower_curve ); 00110 boundedDomain.create_curve( 2, upper_curve ); 00111 } 00112 /* 00113 void PatchDataTestNormals::test_get_vertex_normals_infinite_domain() 00114 { 00115 MsqPrintError err(cout); 00116 00117 for (size_t i = 0; i < unboundedMesh.num_nodes(); ++i) 00118 { 00119 Vector3D pos = unboundedMesh.vertex_by_index( i ); 00120 Vector3D norm; 00121 unboundedMesh.get_domain_normal_at_vertex( i, false, norm, err ); 00122 CPPUNIT_ASSERT(!err); 00123 // all points are on unit sphere centered at origin, so 00124 // the normal should be the same as the point. 00125 ASSERT_VECTORS_EQUAL( pos, norm ); 00126 } 00127 } 00128 00129 void PatchDataTestNormals::test_get_vertex_normals_bounded_domain() 00130 { 00131 MsqPrintError err(cout); 00132 Vector3D norm; 00133 00134 // Vertices 0 to 3 and 8 to 11 should lie on the end 00135 // curves of the cylinder. There is no single valid normal 00136 // for a vertex on a curve, so it should fail for each 00137 // of these. 00138 size_t indices[] = { 0, 1, 2, 3, 8, 9, 10, 11 }; 00139 for (size_t i = 0; i < (sizeof(indices)/sizeof(indices[0])); ++i) 00140 { 00141 boundedMesh.get_domain_normal_at_vertex( indices[i], false, norm, err ); 00142 CPPUNIT_ASSERT( err ); 00143 err.clear(); 00144 } 00145 00146 // The remaining for vertices lie in the Z plane and the 00147 // cylinder's axis is the Z axis, so the normal should 00148 // be the same as the point coordinates. 00149 for (size_t j = 4; j < 8; ++j) 00150 { 00151 Vector3D pos = unboundedMesh.vertex_by_index( j ); 00152 unboundedMesh.get_domain_normal_at_vertex( j, false, norm, err ); 00153 CPPUNIT_ASSERT(!err); 00154 // all points are on unit sphere centered at origin, so 00155 // the normal should be the same as the point. 00156 ASSERT_VECTORS_EQUAL( pos, norm ); 00157 } 00158 } 00159 */ 00160 00161 void PatchDataTestNormals::test_get_corner_normals_infinite_domain() 00162 { 00163 MsqPrintError err( cout ); 00164 00165 // Element 0 is a quad parallel to and below the Z plane. 00166 // All corners of the element lie on the unit sphere and 00167 // thus the normal should be the same as the location. 00168 const size_t elem_index = 0; 00169 std::vector< Vector3D > coords; 00170 Vector3D normals[4]; 00171 unboundedMesh.get_element_vertex_coordinates( elem_index, coords, err ); 00172 CPPUNIT_ASSERT( !err ); 00173 CPPUNIT_ASSERT( coords.size() == 4 /*quad*/ ); 00174 unboundedMesh.get_domain_normals_at_corners( elem_index, normals, err ); 00175 CPPUNIT_ASSERT( !err ); 00176 for( size_t i = 0; i < 4; ++i ) 00177 { 00178 ASSERT_VECTORS_EQUAL( coords[i], normals[i] ); 00179 } 00180 } 00181 00182 void PatchDataTestNormals::test_get_corner_normals_bounded_domain() 00183 { 00184 MsqPrintError err( cout ); 00185 std::vector< Vector3D > coords; 00186 Vector3D normals[4]; 00187 00188 // Element 0 is a quad in the plane X=1/sqrt(2). Two of 00189 // the vertices of this element lie on the lower bounding 00190 // curve of the cylinder, and the other two lie in the 00191 // Z=0 plane 00192 const size_t elem_index = 0; 00193 boundedMesh.get_element_vertex_coordinates( elem_index, coords, err ); 00194 CPPUNIT_ASSERT( !err ); 00195 CPPUNIT_ASSERT( coords.size() == 4 /*quad*/ ); 00196 boundedMesh.get_domain_normals_at_corners( elem_index, normals, err ); 00197 CPPUNIT_ASSERT( !err ); 00198 for( size_t i = 0; i < 4; ++i ) 00199 { 00200 coords[i][2] = 0; // project into Z plane 00201 ASSERT_VECTORS_EQUAL( coords[i], normals[i] ); 00202 } 00203 } 00204 00205 void PatchDataTestNormals::test_get_element_normals_infinite_domain() 00206 { 00207 MsqPrintError err( cout ); 00208 Vector3D expected_normals[] = { Vector3D( 0, 0, -1 ), Vector3D( 0, 0, 1 ), Vector3D( 1, 0, 0 ), 00209 Vector3D( 0, 1, 0 ), Vector3D( -1, 0, 0 ), Vector3D( 0, -1, 0 ) }; 00210 00211 CPPUNIT_ASSERT( unboundedMesh.num_elements() == 6u ); 00212 for( size_t i = 0; i < 6u; ++i ) 00213 { 00214 Vector3D norm; 00215 unboundedMesh.get_domain_normal_at_element( i, norm, err ); 00216 CPPUNIT_ASSERT( !err ); 00217 ASSERT_VECTORS_EQUAL( expected_normals[i], norm ); 00218 } 00219 } 00220 00221 void PatchDataTestNormals::test_get_element_normals_bounded_domain() 00222 { 00223 MsqPrintError err( cout ); 00224 Vector3D expected_normals[] = { Vector3D( 1, 0, 0 ), Vector3D( 0, 1, 0 ), Vector3D( -1, 0, 0 ), 00225 Vector3D( 0, -1, 0 ), Vector3D( 1, 0, 0 ), Vector3D( 0, 1, 0 ), 00226 Vector3D( -1, 0, 0 ), Vector3D( 0, -1, 0 ) }; 00227 00228 CPPUNIT_ASSERT( boundedMesh.num_elements() == 8u ); 00229 for( size_t i = 0; i < 8u; ++i ) 00230 { 00231 Vector3D norm; 00232 boundedMesh.get_domain_normal_at_element( i, norm, err ); 00233 CPPUNIT_ASSERT( !err ); 00234 ASSERT_VECTORS_EQUAL( expected_normals[i], norm ); 00235 } 00236 } 00237 00238 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PatchDataTestNormals, "PatchDataTestNormals" ); 00239 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PatchDataTestNormals, "Unit" );