MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2010 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2010) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file SphericalDomainTest.cpp 00028 * \brief Unit tests for SphericalDomain class 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "UnitUtil.hpp" 00034 #include "SphericalDomain.hpp" 00035 #include "ArrayMesh.hpp" 00036 00037 using namespace MBMesquite; 00038 00039 class SphericalDomainTest : public CppUnit::TestFixture 00040 { 00041 CPPUNIT_TEST_SUITE( SphericalDomainTest ); 00042 CPPUNIT_TEST( test_construct ); 00043 CPPUNIT_TEST( test_fit_vertices ); 00044 CPPUNIT_TEST( test_snap_to ); 00045 CPPUNIT_TEST( test_normal_at ); 00046 CPPUNIT_TEST( test_closest_point ); 00047 CPPUNIT_TEST( test_domain_DoF ); 00048 CPPUNIT_TEST_SUITE_END(); 00049 00050 public: 00051 void test_construct(); 00052 void test_fit_vertices(); 00053 void test_snap_to(); 00054 void test_normal_at(); 00055 void test_closest_point(); 00056 void test_domain_DoF(); 00057 00058 private: 00059 void check_closest_pt( const SphericalDomain& dom, const Vector3D& input_pt, const Vector3D& output_pt ); 00060 00061 void check_normal( const SphericalDomain& dom, const Vector3D& point, const Vector3D& normal ); 00062 }; 00063 00064 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SphericalDomainTest, "SphericalDomainTest" ); 00065 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SphericalDomainTest, "Unit" ); 00066 00067 void SphericalDomainTest::check_closest_pt( const SphericalDomain& dom, 00068 const Vector3D& input_pt, 00069 const Vector3D& output_pt ) 00070 { 00071 Vector3D vo = output_pt - dom.center(); 00072 Vector3D vi = input_pt - dom.center(); 00073 CPPUNIT_ASSERT_DOUBLES_EQUAL( dom.radius(), vo.length(), 1e-6 ); 00074 vi *= dom.radius() / vi.length(); 00075 CPPUNIT_ASSERT_VECTORS_EQUAL( vo, vi, 1e-6 ); 00076 } 00077 void SphericalDomainTest::check_normal( const SphericalDomain& dom, const Vector3D& point, const Vector3D& normal ) 00078 { 00079 Vector3D vi = point - dom.center(); 00080 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, normal.length(), 1e-6 ); 00081 vi /= vi.length(); 00082 CPPUNIT_ASSERT_VECTORS_EQUAL( vi, normal, 1e-6 ); 00083 } 00084 00085 void SphericalDomainTest::test_construct() 00086 { 00087 Vector3D cen( 1, 2, -1 ); 00088 double rad = 3.14159; 00089 SphericalDomain sph( cen, rad ); 00090 CPPUNIT_ASSERT_VECTORS_EQUAL( cen, sph.center(), 1e-18 ); 00091 CPPUNIT_ASSERT_DOUBLES_EQUAL( rad, sph.radius(), 1e-18 ); 00092 00093 cen = Vector3D( 5, 6, 1.14 ); 00094 rad = 1 / rad; 00095 sph.set_sphere( cen, rad ); 00096 CPPUNIT_ASSERT_VECTORS_EQUAL( cen, sph.center(), 1e-18 ); 00097 CPPUNIT_ASSERT_DOUBLES_EQUAL( rad, sph.radius(), 1e-18 ); 00098 } 00099 00100 static void sphere_point( Vector3D cen, double rad, double theta, double phi, double pt[3] ) 00101 { 00102 Vector3D pdir( cos( phi ) * cos( theta ), cos( phi ) * sin( theta ), sin( phi ) ); 00103 Vector3D rslt = cen + rad * pdir; 00104 pt[0] = rslt[0]; 00105 pt[1] = rslt[1]; 00106 pt[2] = rslt[2]; 00107 } 00108 00109 void SphericalDomainTest::test_fit_vertices() 00110 { 00111 Vector3D cen( 1, 2, 3 ); 00112 double rad = 2.5; 00113 00114 // point locations on a expected sphere 00115 const int num_pt = 6; 00116 double coords[3 * num_pt]; 00117 sphere_point( cen, rad, 0.1, 0.2, coords ); 00118 sphere_point( cen, rad, 2.0, 2.0, coords + 3 ); 00119 sphere_point( cen, rad, -1.0, 0.0, coords + 6 ); 00120 sphere_point( cen, rad, 3.1, -0.5, coords + 9 ); 00121 sphere_point( cen, rad, -1.5, -1.0, coords + 12 ); 00122 sphere_point( cen, rad, 0.2, 0.1, coords + 15 ); 00123 00124 // make sure our setup is valid 00125 for( int i = 0; i < num_pt; ++i ) 00126 { 00127 Vector3D pt( coords + 3 * i ); 00128 CPPUNIT_ASSERT_DOUBLES_EQUAL( rad, ( pt - cen ).length(), 1e-6 ); 00129 } 00130 00131 std::vector< int > fixed( num_pt, 0 ); 00132 ArrayMesh mesh( 3, num_pt, coords, arrptr( fixed ), 0, TRIANGLE, 0 ); 00133 SphericalDomain sph; 00134 MsqError err; 00135 sph.fit_vertices( &mesh, err ); 00136 ASSERT_NO_ERROR( err ); 00137 CPPUNIT_ASSERT_VECTORS_EQUAL( cen, sph.center(), 1e-6 ); 00138 CPPUNIT_ASSERT_DOUBLES_EQUAL( rad, sph.radius(), 1e-6 ); 00139 } 00140 00141 void SphericalDomainTest::test_snap_to() 00142 { 00143 Vector3D cen( 3.14, 15, 0.91 ); 00144 double rad = 6.02; 00145 SphericalDomain dom( cen, rad ); 00146 00147 const int num_pts = 5; 00148 double points[num_pts][3] = { { 0, 0, 0 }, { 10, 11, 8 }, { 1, 2, 3 }, { -5, 1, 1 }, { -1, 0, -2 } }; 00149 for( int i = 0; i < num_pts; ++i ) 00150 { 00151 Vector3D v( points[i] ); 00152 dom.snap_to( 0, v ); 00153 check_closest_pt( dom, Vector3D( points[i] ), v ); 00154 } 00155 } 00156 00157 void SphericalDomainTest::test_normal_at() 00158 { 00159 Vector3D cen( -3.14, 0, 0.91 ); 00160 double rad = 2; 00161 SphericalDomain dom( cen, rad ); 00162 00163 const int num_pts = 5; 00164 double points[num_pts][3] = { { 0, 0, 0 }, { 10, 11, 8 }, { 1, 2, 3 }, { -5, 1, 1 }, { -1, 0, -2 } }; 00165 for( int i = 0; i < num_pts; ++i ) 00166 { 00167 Vector3D v( points[i] ); 00168 dom.vertex_normal_at( 0, v ); 00169 check_normal( dom, Vector3D( points[i] ), v ); 00170 00171 v = Vector3D( points[i] ); 00172 dom.element_normal_at( 0, v ); 00173 check_normal( dom, Vector3D( points[i] ), v ); 00174 } 00175 } 00176 00177 void SphericalDomainTest::test_closest_point() 00178 { 00179 Vector3D cen( -1, -1, -2 ); 00180 double rad = 1.4; 00181 SphericalDomain dom( cen, rad ); 00182 MsqPrintError err( std::cout ); 00183 00184 const int num_pts = 5; 00185 double points[num_pts][3] = { { 0, 0, 0 }, { 10, 11, 8 }, { 1, 2, 3 }, { -5, 1, 1 }, { -1, 0, -2 } }; 00186 for( int i = 0; i < num_pts; ++i ) 00187 { 00188 Vector3D p( points[i] ), c, n; 00189 dom.closest_point( 0, p, c, n, err ); 00190 ASSERT_NO_ERROR( err ); 00191 check_closest_pt( dom, p, c ); 00192 check_normal( dom, p, n ); 00193 } 00194 } 00195 00196 void SphericalDomainTest::test_domain_DoF() 00197 { 00198 std::vector< Mesh::VertexHandle > junk( 10 ); 00199 std::vector< unsigned short > dof( junk.size() ); 00200 std::vector< unsigned short > expected( dof.size(), 2 ); 00201 SphericalDomain dom; 00202 MsqPrintError err( std::cout ); 00203 dom.domain_DoF( arrptr( junk ), arrptr( dof ), junk.size(), err ); 00204 ASSERT_NO_ERROR( err ); 00205 CPPUNIT_ASSERT( expected == dof ); 00206 }