MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 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 retian 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 (2006) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file LVQDTargetTest.cpp 00028 * \brief unit tests for LVQDTargetCalculator class 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "LVQDTargetCalculator.hpp" 00034 #include "MsqError.hpp" 00035 #include "PatchData.hpp" 00036 #include "UnitUtil.hpp" 00037 #include "PatchDataInstances.hpp" 00038 00039 #include <iostream> 00040 00041 using namespace MBMesquite; 00042 00043 class LVQDTargetTest : public CppUnit::TestFixture 00044 { 00045 private: 00046 CPPUNIT_TEST_SUITE( LVQDTargetTest ); 00047 00048 // Test that LVQDTargetCalculator accepts a NULL component 00049 // and treats the corresponding value as I 00050 CPPUNIT_TEST( test_LVQD_default_is_I_2D ); 00051 CPPUNIT_TEST( test_LVQD_default_is_I_surface ); 00052 CPPUNIT_TEST( test_LVQD_default_is_I_3D ); 00053 // Test that LVQDTargetCalculator returns the product of 00054 // its components. 00055 CPPUNIT_TEST( test_LVQD_product_2D ); 00056 CPPUNIT_TEST( test_LVQD_product_surface ); 00057 CPPUNIT_TEST( test_LVQD_product_3D ); 00058 00059 CPPUNIT_TEST_SUITE_END(); 00060 00061 // Define a few pre-factored matrices to use in tests. 00062 // Initialized by SetUp() method. 00063 MsqMatrix< 3, 3 > V3D_Z45, V3D_X90, Q3D_45, D3D_123, I33; 00064 MsqMatrix< 3, 2 > V2D_Z45, V2D_X90, I32; 00065 MsqMatrix< 2, 2 > Q2D_45, D2D_21, I22; 00066 // PatchDatas for use in calls to 2D or 3D versions of functions. 00067 PatchData pd2D, pd3D; 00068 00069 // Use LVQDTargetCalculator to calculate the product of the passed values. 00070 MsqMatrix< 3, 2 > target( const double* L, 00071 const MsqMatrix< 3, 2 >* V, 00072 const MsqMatrix< 2, 2 >* Q, 00073 const MsqMatrix< 2, 2 >* D ); 00074 // Use LVQDTargetCalculator to calculate the product of the passed values. 00075 MsqMatrix< 2, 2 > target( const double* L, const MsqMatrix< 2, 2 >* Q, const MsqMatrix< 2, 2 >* D ); 00076 // Use LVQDTargetCalculator to calculate the product of the passed values. 00077 MsqMatrix< 3, 3 > target( const double* L, 00078 const MsqMatrix< 3, 3 >* V, 00079 const MsqMatrix< 3, 3 >* Q, 00080 const MsqMatrix< 3, 3 >* D ); 00081 00082 public: 00083 void setUp(); 00084 00085 // Test that LVQDTargetCalculator accepts a NULL component 00086 // and treats the corresponding value as I 00087 void test_LVQD_default_is_I_2D(); 00088 void test_LVQD_default_is_I_3D(); 00089 void test_LVQD_default_is_I_surface(); 00090 // Test that LVQDTargetCalculator returns the product of 00091 // its components. 00092 void test_LVQD_product_2D(); 00093 void test_LVQD_product_3D(); 00094 void test_LVQD_product_surface(); 00095 00096 // Helper class: return constant values for target matrices. 00097 class ConstantTarget : public TargetCalculator 00098 { 00099 private: 00100 MsqMatrix< 3, 3 > target3D; 00101 MsqMatrix< 3, 2 > targetSurf; 00102 MsqMatrix< 2, 2 > target2D; 00103 bool have3D, haveSurf, have2D; 00104 bool flagError; 00105 00106 public: 00107 ConstantTarget( MsqMatrix< 3, 3 > val3D, MsqMatrix< 3, 2 > val2D ) 00108 : target3D( val3D ), targetSurf( val2D ), have3D( true ), haveSurf( true ), have2D( false ) 00109 { 00110 } 00111 ConstantTarget( MsqMatrix< 3, 3 > val3D, MsqMatrix< 2, 2 > val2D ) 00112 : target3D( val3D ), target2D( val2D ), have3D( true ), haveSurf( false ), have2D( true ) 00113 { 00114 } 00115 ConstantTarget( double C, bool surf ) 00116 : target3D( C ), targetSurf( C ), target2D( C ), have3D( true ), haveSurf( surf ), have2D( !surf ) 00117 { 00118 } 00119 ConstantTarget( MsqMatrix< 3, 3 > val3D ) 00120 : target3D( val3D ), target2D( 0.0 ), have3D( true ), haveSurf( false ), have2D( false ) 00121 { 00122 } 00123 ConstantTarget( MsqMatrix< 3, 2 > val2D ) 00124 : targetSurf( val2D ), have3D( false ), haveSurf( true ), have2D( false ) 00125 { 00126 } 00127 ConstantTarget( MsqMatrix< 2, 2 > val2D ) 00128 : target2D( val2D ), have3D( false ), haveSurf( false ), have2D( true ) 00129 { 00130 } 00131 00132 virtual bool get_3D_target( PatchData&, size_t, Sample, MsqMatrix< 3, 3 >& result, MsqError& err ) 00133 { 00134 CPPUNIT_ASSERT( have3D ); 00135 result = target3D; 00136 return have3D; 00137 } 00138 00139 virtual bool get_surface_target( PatchData&, size_t, Sample, MsqMatrix< 3, 2 >& result, MsqError& err ) 00140 { 00141 CPPUNIT_ASSERT( haveSurf ); 00142 result = targetSurf; 00143 return haveSurf; 00144 } 00145 00146 virtual bool get_2D_target( PatchData&, size_t, Sample, MsqMatrix< 2, 2 >& result, MsqError& err ) 00147 { 00148 CPPUNIT_ASSERT( have2D ); 00149 result = target2D; 00150 return have2D; 00151 } 00152 00153 virtual bool have_surface_orient() const 00154 { 00155 return haveSurf; 00156 } 00157 }; 00158 00159 // Helper class: return 'invalid' for target matrices, and 00160 // optionally flag an error. 00161 class TargetError : public TargetCalculator 00162 { 00163 bool flagError; 00164 bool surfOrient; 00165 00166 public: 00167 TargetError( bool flag_error = true, bool orient = false ) : flagError( flag_error ), surfOrient( orient ) {} 00168 00169 bool get_3D_target( PatchData&, size_t, Sample, MsqMatrix< 3, 3 >&, MsqError& err ) 00170 { 00171 if( flagError ) MSQ_SETERR( err )( MsqError::INVALID_MESH ); 00172 return false; 00173 } 00174 00175 bool get_2D_target( PatchData&, size_t, Sample, MsqMatrix< 2, 2 >&, MsqError& err ) 00176 { 00177 if( flagError ) MSQ_SETERR( err )( MsqError::INVALID_MESH ); 00178 return false; 00179 } 00180 00181 bool get_surface_target( PatchData&, size_t, Sample, MsqMatrix< 3, 2 >&, MsqError& err ) 00182 { 00183 if( flagError ) MSQ_SETERR( err )( MsqError::INVALID_MESH ); 00184 return false; 00185 } 00186 00187 virtual bool have_surface_orient() const 00188 { 00189 return surfOrient; 00190 } 00191 }; 00192 }; 00193 00194 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LVQDTargetTest, "LVQDTargetTest" ); 00195 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LVQDTargetTest, "Unit" ); 00196 00197 void LVQDTargetTest::setUp() 00198 { 00199 const double cos45 = MSQ_SQRT_TWO / 2.0; 00200 const double rotation_3D_Z45[9] = { cos45, -cos45, 0, cos45, cos45, 0, 0, 0, 1 }; 00201 const double rotation_2D_Z45[6] = { cos45, -cos45, cos45, cos45, 0, 0 }; 00202 00203 const double rotation_3D_X90[9] = { 1, 0, 0, 0, 0, -1, 0, 1, 0 }; 00204 const double rotation_2D_X90[6] = { 1, 0, 0, 0, 0, 1 }; 00205 00206 const double rc45 = sqrt( cos45 ); 00207 const double skew_2D_45[4] = { 1 / rc45, rc45, 0, rc45 }; 00208 const double skew_3D_45[9] = { 1, cos45, cos45, 0, cos45, 1 - cos45, 0, 0, sqrt( MSQ_SQRT_TWO - 1 ) }; 00209 00210 const double aspect_2D_2x[4] = { MSQ_SQRT_TWO, 0, 0, MSQ_SQRT_TWO / 2 }; 00211 const double r6 = MBMesquite::cbrt( 1.0 / 6.0 ); 00212 const double aspect_3D_123[9] = { r6, 0, 0, 0, 2 * r6, 0, 0, 0, 3 * r6 }; 00213 00214 V3D_Z45 = MsqMatrix< 3, 3 >( rotation_3D_Z45 ); 00215 V3D_X90 = MsqMatrix< 3, 3 >( rotation_3D_X90 ); 00216 Q3D_45 = MsqMatrix< 3, 3 >( skew_3D_45 ); 00217 Q3D_45 *= 1 / Mesquite::cbrt( det( Q3D_45 ) ); 00218 D3D_123 = MsqMatrix< 3, 3 >( aspect_3D_123 ); 00219 00220 V2D_Z45 = MsqMatrix< 3, 2 >( rotation_2D_Z45 ); 00221 V2D_X90 = MsqMatrix< 3, 2 >( rotation_2D_X90 ); 00222 Q2D_45 = MsqMatrix< 2, 2 >( skew_2D_45 ); 00223 D2D_21 = MsqMatrix< 2, 2 >( aspect_2D_2x ); 00224 00225 I33 = MsqMatrix< 3, 3 >( 1.0 ); 00226 I32 = MsqMatrix< 3, 2 >( 1.0 ); 00227 I22 = MsqMatrix< 2, 2 >( 1.0 ); 00228 00229 MsqError err; 00230 create_one_tet_patch( pd3D, err ); 00231 ASSERT_NO_ERROR( err ); 00232 create_one_tri_patch( pd2D, err ); 00233 ASSERT_NO_ERROR( err ); 00234 }; 00235 00236 MsqMatrix< 3, 2 > LVQDTargetTest::target( const double* L, 00237 const MsqMatrix< 3, 2 >* V, 00238 const MsqMatrix< 2, 2 >* Q, 00239 const MsqMatrix< 2, 2 >* D ) 00240 { 00241 ConstantTarget W_size( L ? *L : 1.0, true ); 00242 ConstantTarget W_orient( V ? *V : I32 ); 00243 ConstantTarget W_skew( Q ? *Q : I22 ); 00244 ConstantTarget W_aspect( D ? *D : I22 ); 00245 LVQDTargetCalculator LVQD( L ? &W_size : NULL, V ? &W_orient : NULL, Q ? &W_skew : NULL, D ? &W_aspect : NULL ); 00246 MsqError err; 00247 MsqMatrix< 3, 2 > W; 00248 bool v; 00249 if( !V ) 00250 { 00251 MsqMatrix< 2, 2 > W_2D; 00252 v = LVQD.get_2D_target( pd2D, 0, Sample( 0, 0 ), W_2D, err ); 00253 W.set_row( 0, W_2D.row( 0 ) ); 00254 W.set_row( 1, W_2D.row( 1 ) ); 00255 W.set_row( 2, MsqMatrix< 1, 2 >( 0.0 ) ); 00256 } 00257 else 00258 { 00259 v = LVQD.get_surface_target( pd2D, 0, Sample( 0, 0 ), W, err ); 00260 } 00261 ASSERT_NO_ERROR( err ); 00262 CPPUNIT_ASSERT( v ); 00263 return W; 00264 } 00265 00266 MsqMatrix< 2, 2 > LVQDTargetTest::target( const double* L, const MsqMatrix< 2, 2 >* Q, const MsqMatrix< 2, 2 >* D ) 00267 { 00268 ConstantTarget W_size( L ? *L : 1.0, false ); 00269 ConstantTarget W_skew( Q ? *Q : I22 ); 00270 ConstantTarget W_aspect( D ? *D : I22 ); 00271 LVQDTargetCalculator LVQD( L ? &W_size : NULL, NULL, Q ? &W_skew : NULL, D ? &W_aspect : NULL ); 00272 MsqError err; 00273 MsqMatrix< 2, 2 > W; 00274 bool v = LVQD.get_2D_target( pd2D, 0, Sample( 0, 0 ), W, err ); 00275 ASSERT_NO_ERROR( err ); 00276 CPPUNIT_ASSERT( v ); 00277 return W; 00278 } 00279 00280 MsqMatrix< 3, 3 > LVQDTargetTest::target( const double* L, 00281 const MsqMatrix< 3, 3 >* V, 00282 const MsqMatrix< 3, 3 >* Q, 00283 const MsqMatrix< 3, 3 >* D ) 00284 { 00285 ConstantTarget W_size( L ? *L : 1.0, true ); 00286 ConstantTarget W_orient( V ? *V : I33 ); 00287 ConstantTarget W_skew( Q ? *Q : I33 ); 00288 ConstantTarget W_aspect( D ? *D : I33 ); 00289 LVQDTargetCalculator LVQD( L ? &W_size : NULL, V ? &W_orient : NULL, Q ? &W_skew : NULL, D ? &W_aspect : NULL ); 00290 MsqError err; 00291 MsqMatrix< 3, 3 > W; 00292 bool v = LVQD.get_3D_target( pd3D, 0, Sample( 0, 0 ), W, err ); 00293 ASSERT_NO_ERROR( err ); 00294 CPPUNIT_ASSERT( v ); 00295 return W; 00296 } 00297 00298 void LVQDTargetTest::test_LVQD_default_is_I_2D() 00299 { 00300 double s = 3.2; 00301 ASSERT_MATRICES_EQUAL( I22, target( 0, 0, 0 ), 1e-8 ); 00302 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 2, 2 >( s ) ), target( &s, 0, 0 ), 1e-8 ); 00303 ASSERT_MATRICES_EQUAL( Q2D_45, target( 0, &Q2D_45, 0 ), 1e-8 ); 00304 ASSERT_MATRICES_EQUAL( D2D_21, target( 0, 0, &D2D_21 ), 1e-8 ); 00305 } 00306 00307 void LVQDTargetTest::test_LVQD_default_is_I_surface() 00308 { 00309 double s = 3.2; 00310 MsqMatrix< 3, 2 >* null_V = 0; 00311 ASSERT_MATRICES_EQUAL( I32, target( 0, null_V, 0, 0 ), 1e-8 ); 00312 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 3, 2 >( s ) ), target( &s, null_V, 0, 0 ), 1e-8 ); 00313 ASSERT_MATRICES_EQUAL( V2D_Z45, target( 0, &V2D_Z45, 0, 0 ), 1e-8 ); 00314 ASSERT_MATRICES_EQUAL( s * V2D_Z45, target( &s, &V2D_Z45, 0, 0 ), 1e-8 ); 00315 ASSERT_MATRICES_EQUAL( V2D_Z45 * Q2D_45, target( 0, &V2D_Z45, &Q2D_45, 0 ), 1e-8 ); 00316 ASSERT_MATRICES_EQUAL( V2D_Z45 * D2D_21, target( 0, &V2D_Z45, 0, &D2D_21 ), 1e-8 ); 00317 } 00318 00319 void LVQDTargetTest::test_LVQD_default_is_I_3D() 00320 { 00321 double s = 2.6; 00322 MsqMatrix< 3, 3 >* null_V = 0; 00323 ASSERT_MATRICES_EQUAL( I33, target( 0, null_V, 0, 0 ), 1e-8 ); 00324 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 3, 3 >( s ) ), target( &s, null_V, 0, 0 ), 1e-8 ); 00325 ASSERT_MATRICES_EQUAL( V3D_Z45, target( 0, &V3D_Z45, 0, 0 ), 1e-8 ); 00326 ASSERT_MATRICES_EQUAL( s * V3D_Z45, target( &s, &V3D_Z45, 0, 0 ), 1e-8 ); 00327 ASSERT_MATRICES_EQUAL( V3D_Z45 * Q3D_45, target( 0, &V3D_Z45, &Q3D_45, 0 ), 1e-8 ); 00328 ASSERT_MATRICES_EQUAL( V3D_Z45 * D3D_123, target( 0, &V3D_Z45, 0, &D3D_123 ), 1e-8 ); 00329 } 00330 00331 void LVQDTargetTest::test_LVQD_product_2D() 00332 { 00333 double s = 3.2; 00334 double o = 1.0; 00335 ASSERT_MATRICES_EQUAL( I22, target( &o, &I22, &I22 ), 1e-8 ); 00336 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 2, 2 >( s ) ), target( &s, &I22, &I22 ), 1e-8 ); 00337 ASSERT_MATRICES_EQUAL( Q2D_45, target( &o, &Q2D_45, &I22 ), 1e-8 ); 00338 ASSERT_MATRICES_EQUAL( D2D_21, target( &o, &I22, &D2D_21 ), 1e-8 ); 00339 ASSERT_MATRICES_EQUAL( s * Q2D_45 * D2D_21, target( &s, &Q2D_45, &D2D_21 ), 1e-8 ); 00340 } 00341 00342 void LVQDTargetTest::test_LVQD_product_surface() 00343 { 00344 double s = 3.2; 00345 double o = 1.0; 00346 ASSERT_MATRICES_EQUAL( I32, target( &o, &I32, &I22, &I22 ), 1e-8 ); 00347 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 3, 2 >( s ) ), target( &s, &I32, &I22, &I22 ), 1e-8 ); 00348 ASSERT_MATRICES_EQUAL( V2D_Z45, target( &o, &V2D_Z45, &I22, &I22 ), 1e-8 ); 00349 ASSERT_MATRICES_EQUAL( s * V2D_Z45, target( &s, &V2D_Z45, &I22, &I22 ), 1e-8 ); 00350 ASSERT_MATRICES_EQUAL( V2D_Z45 * Q2D_45, target( &o, &V2D_Z45, &Q2D_45, &I22 ), 1e-8 ); 00351 ASSERT_MATRICES_EQUAL( V2D_Z45 * D2D_21, target( &o, &V2D_Z45, &I22, &D2D_21 ), 1e-8 ); 00352 ASSERT_MATRICES_EQUAL( s * V2D_Z45 * Q2D_45 * D2D_21, target( &s, &V2D_Z45, &Q2D_45, &D2D_21 ), 1e-8 ); 00353 } 00354 00355 void LVQDTargetTest::test_LVQD_product_3D() 00356 { 00357 double s = 2.6; 00358 double o = 1.0; 00359 ASSERT_MATRICES_EQUAL( I33, target( &o, &I33, &I33, &I33 ), 1e-8 ); 00360 ASSERT_MATRICES_EQUAL( ( MsqMatrix< 3, 3 >( s ) ), target( &s, &I33, &I33, &I33 ), 1e-8 ); 00361 ASSERT_MATRICES_EQUAL( V3D_Z45, target( &o, &V3D_Z45, &I33, &I33 ), 1e-8 ); 00362 ASSERT_MATRICES_EQUAL( s * V3D_Z45, target( &s, &V3D_Z45, &I33, &I33 ), 1e-8 ); 00363 ASSERT_MATRICES_EQUAL( V3D_Z45 * Q3D_45, target( &o, &V3D_Z45, &Q3D_45, &I33 ), 1e-8 ); 00364 ASSERT_MATRICES_EQUAL( V3D_Z45 * D3D_123, target( &o, &V3D_Z45, &I33, &D3D_123 ), 1e-8 ); 00365 ASSERT_MATRICES_EQUAL( s * V3D_Z45 * Q3D_45 * D3D_123, target( &s, &V3D_Z45, &Q3D_45, &D3D_123 ), 1e-8 ); 00366 }