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