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