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