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