MOAB: Mesh Oriented datABase  (version 5.3.0)
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) 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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines