MOAB: Mesh Oriented datABase  (version 5.4.1)
CompositeMetricTest.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 CompositeMetricTest.cpp
00028  *  \brief unit tests for IdealWeightMeanRatio quality metric
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "IdealWeightInverseMeanRatio.hpp"
00034 #include "LocalSizeQualityMetric.hpp"
00035 #include "ConditionNumberQualityMetric.hpp"
00036 #include "cppunit/extensions/HelperMacros.h"
00037 #include "QualityMetricTester.hpp"
00038 #include "AddQualityMetric.hpp"
00039 #include "MultiplyQualityMetric.hpp"
00040 #include "PowerQualityMetric.hpp"
00041 #include "ScalarAddQualityMetric.hpp"
00042 #include "ScalarMultiplyQualityMetric.hpp"
00043 #include "MsqError.hpp"
00044 #include "PatchData.hpp"
00045 #include "UnitUtil.hpp"
00046 
00047 using namespace MBMesquite;
00048 
00049 class CompositeMetricTestBase : public CppUnit::TestFixture
00050 {
00051   private:
00052     void test_evaluate( bool ideal, EntityTopology type );
00053 
00054   protected:
00055     QualityMetricTester tester;
00056     QualityMetric* mMetric;
00057     virtual bool evaluate( PatchData&, size_t, double&, MsqError& ) = 0;
00058 
00059   public:
00060     CompositeMetricTestBase() : tester( QualityMetricTester::ALL_FE_EXCEPT_SEPTAHEDRON ), mMetric( 0 )
00061     {
00062         tester.ideal_pyramid_base_equals_height( true );
00063     }
00064 
00065     void test_supported_types()
00066     {
00067         tester.test_supported_element_types( mMetric );
00068     }
00069 
00070     void test_ideal_element_eval()
00071     {
00072         test_evaluate( true, TRIANGLE );
00073         test_evaluate( true, QUADRILATERAL );
00074         test_evaluate( true, TETRAHEDRON );
00075         test_evaluate( true, HEXAHEDRON );
00076         test_evaluate( true, PRISM );
00077         test_evaluate( true, PYRAMID );
00078     }
00079 
00080     void test_non_ideal_eval()
00081     {
00082         test_evaluate( false, TRIANGLE );
00083         test_evaluate( false, QUADRILATERAL );
00084         test_evaluate( false, TETRAHEDRON );
00085         test_evaluate( false, HEXAHEDRON );
00086         test_evaluate( false, PRISM );
00087         test_evaluate( false, PYRAMID );
00088     }
00089 
00090     void test_ideal_element_grad()
00091     {
00092         tester.test_ideal_element_zero_gradient( mMetric, false );
00093     }
00094 
00095     void test_ideal_element_hess()
00096     {
00097         tester.test_ideal_element_positive_definite_Hessian( mMetric, false );
00098     }
00099 
00100     void test_valid_hessian()
00101     {
00102         tester.test_symmetric_Hessian_diagonal_blocks( mMetric );
00103     }
00104 
00105     void test_measures_quality()
00106     {
00107         tester.test_measures_quality( mMetric );
00108     }
00109 
00110     void test_gradient_reflects_quality()
00111     {
00112         tester.test_gradient_reflects_quality( mMetric );
00113     }
00114 
00115     void test_domain_deviation()
00116     {
00117         tester.test_domain_deviation_quality( mMetric );
00118         tester.test_domain_deviation_gradient( mMetric );
00119     }
00120 
00121     void test_inverted_elements()
00122     {
00123         tester.test_evaluate_inverted_element( mMetric, false );
00124     }
00125 
00126     void test_degenerate_elements()
00127     {
00128         tester.test_evaluate_degenerate_element( mMetric, false );
00129     }
00130 
00131     void test_get_evaluations()
00132     {
00133         tester.test_get_element_evaluations( mMetric );
00134     }
00135 
00136     void test_get_element_indices()
00137     {
00138         tester.test_get_element_indices( mMetric );
00139     }
00140 
00141     void test_get_fixed_indices()
00142     {
00143         tester.test_get_indices_fixed( mMetric );
00144     }
00145 
00146     void test_eval_with_indices()
00147     {
00148         tester.compare_eval_and_eval_with_indices( mMetric );
00149     }
00150 
00151     void test_eval_with_gradient()
00152     {
00153         tester.compare_eval_with_indices_and_eval_with_gradient( mMetric );
00154         tester.compare_analytical_and_numerical_gradients( mMetric );
00155     }
00156 
00157     void test_eval_with_hessian()
00158     {
00159         tester.compare_eval_with_indices_and_eval_with_hessian( mMetric );
00160         tester.compare_eval_with_grad_and_eval_with_hessian( mMetric );
00161         tester.compare_analytical_and_numerical_hessians( mMetric );
00162     }
00163 
00164     void test_location_invariant()
00165     {
00166         tester.test_location_invariant( mMetric );
00167         tester.test_grad_location_invariant( mMetric );
00168         tester.test_hessian_location_invariant( mMetric );
00169     }
00170 
00171     void test_scale_invariant()
00172     {
00173         tester.test_scale_invariant( mMetric );
00174     }
00175 
00176     void test_orient_invariant()
00177     {
00178         tester.test_orient_invariant( mMetric );
00179         tester.test_grad_orient_invariant( mMetric );
00180     }
00181 };
00182 
00183 void CompositeMetricTestBase::test_evaluate( bool ideal, EntityTopology type )
00184 {
00185     MsqPrintError err( std::cout );
00186     PatchData pd;
00187     double act, ex;
00188     bool rval;
00189 
00190     if( ideal )
00191         tester.get_ideal_element( type, false, pd, false );
00192     else
00193         tester.get_nonideal_element( type, pd );
00194 
00195     rval = mMetric->evaluate( pd, 0, act, err );
00196     ASSERT_NO_ERROR( err );
00197     CPPUNIT_ASSERT( rval );
00198 
00199     rval = this->evaluate( pd, 0, ex, err );
00200     ASSERT_NO_ERROR( err );
00201     CPPUNIT_ASSERT( rval );
00202 
00203     CPPUNIT_ASSERT_DOUBLES_EQUAL( ex, act, 1e-6 );
00204 }
00205 
00206 class AddQualityMetricTest : public CompositeMetricTestBase
00207 {
00208 
00209     CPPUNIT_TEST_SUITE( AddQualityMetricTest );
00210     CPPUNIT_TEST( test_supported_types );
00211     CPPUNIT_TEST( test_ideal_element_eval );
00212     CPPUNIT_TEST( test_ideal_element_grad );
00213     CPPUNIT_TEST( test_ideal_element_hess );
00214     CPPUNIT_TEST( test_non_ideal_eval );
00215     CPPUNIT_TEST( test_valid_hessian );
00216     CPPUNIT_TEST( test_inverted_elements );
00217     CPPUNIT_TEST( test_degenerate_elements );
00218     CPPUNIT_TEST( test_get_evaluations );
00219     CPPUNIT_TEST( test_get_element_indices );
00220     CPPUNIT_TEST( test_get_fixed_indices );
00221     CPPUNIT_TEST( test_eval_with_indices );
00222     CPPUNIT_TEST( test_eval_with_gradient );
00223     CPPUNIT_TEST( test_eval_with_hessian );
00224     CPPUNIT_TEST_SUITE_END();
00225 
00226   private:
00227     MsqError mErr;
00228     IdealWeightInverseMeanRatio m1;
00229     IdealWeightInverseMeanRatio m2;
00230     AddQualityMetric m;
00231 
00232   protected:
00233     virtual bool evaluate( PatchData&, size_t, double&, MsqError& );
00234 
00235   public:
00236     AddQualityMetricTest() : m2( mErr, 2.0 ), m( &m1, &m2, mErr )
00237     {
00238         mMetric = &m;
00239     }
00240     void setUp()
00241     {
00242         CPPUNIT_ASSERT( !mErr );
00243     }
00244 };
00245 
00246 bool AddQualityMetricTest::evaluate( PatchData& pd, size_t h, double& val, MsqError& err )
00247 {
00248     double v1, v2;
00249     bool rval = true, rval1;
00250 
00251     rval1 = m1.evaluate( pd, h, v1, err );
00252     MSQ_ERRFALSE( err );
00253     if( !rval1 ) rval = false;
00254 
00255     rval1 = m2.evaluate( pd, h, v2, err );
00256     MSQ_ERRFALSE( err );
00257     if( !rval1 ) rval = false;
00258 
00259     val = v1 + v2;
00260     return rval;
00261 }
00262 
00263 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AddQualityMetricTest, "CompositeMetricTest" );
00264 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AddQualityMetricTest, "AddQualityMetricTest" );
00265 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AddQualityMetricTest, "Unit" );
00266 
00267 class MultiplyQualityMetricTest : public CompositeMetricTestBase
00268 {
00269   private:
00270     CPPUNIT_TEST_SUITE( MultiplyQualityMetricTest );
00271     CPPUNIT_TEST( test_supported_types );
00272     CPPUNIT_TEST( test_ideal_element_eval );
00273     CPPUNIT_TEST( test_ideal_element_grad );
00274     CPPUNIT_TEST( test_ideal_element_hess );
00275     CPPUNIT_TEST( test_non_ideal_eval );
00276     CPPUNIT_TEST( test_valid_hessian );
00277     CPPUNIT_TEST( test_inverted_elements );
00278     CPPUNIT_TEST( test_degenerate_elements );
00279     CPPUNIT_TEST( test_get_evaluations );
00280     CPPUNIT_TEST( test_get_element_indices );
00281     CPPUNIT_TEST( test_get_fixed_indices );
00282     CPPUNIT_TEST( test_eval_with_indices );
00283     CPPUNIT_TEST( test_eval_with_gradient );
00284     CPPUNIT_TEST( test_eval_with_hessian );
00285     CPPUNIT_TEST_SUITE_END();
00286 
00287     MsqError mErr;
00288     IdealWeightInverseMeanRatio m1;
00289     IdealWeightInverseMeanRatio m2;
00290     MultiplyQualityMetric m;
00291 
00292   protected:
00293     virtual bool evaluate( PatchData&, size_t, double&, MsqError& );
00294 
00295   public:
00296     MultiplyQualityMetricTest() : m2( mErr, 2.0 ), m( &m1, &m2, mErr )
00297     {
00298         mMetric = &m;
00299     }
00300     void setUp()
00301     {
00302         CPPUNIT_ASSERT( !mErr );
00303     }
00304 };
00305 
00306 bool MultiplyQualityMetricTest::evaluate( PatchData& pd, size_t h, double& val, MsqError& err )
00307 {
00308     double v1, v2;
00309     bool rval = true, rval1;
00310 
00311     rval1 = m1.evaluate( pd, h, v1, err );
00312     MSQ_ERRFALSE( err );
00313     if( !rval1 ) rval = false;
00314 
00315     rval1 = m2.evaluate( pd, h, v2, err );
00316     MSQ_ERRFALSE( err );
00317     if( !rval1 ) rval = false;
00318 
00319     val = v1 * v2;
00320     return rval;
00321 }
00322 
00323 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MultiplyQualityMetricTest, "CompositeMetricTest" );
00324 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MultiplyQualityMetricTest, "MultiplyQualityMetricTest" );
00325 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MultiplyQualityMetricTest, "Unit" );
00326 
00327 template < int POWER >
00328 class PowerQualityMetricTest : public CompositeMetricTestBase
00329 {
00330   private:
00331     CPPUNIT_TEST_SUITE( PowerQualityMetricTest< POWER > );
00332     CPPUNIT_TEST( test_supported_types );
00333     CPPUNIT_TEST( test_ideal_element_eval );
00334     CPPUNIT_TEST( test_ideal_element_grad );
00335     // CPPUNIT_TEST (test_ideal_element_hess);
00336     CPPUNIT_TEST( test_non_ideal_eval );
00337     CPPUNIT_TEST( test_valid_hessian );
00338     CPPUNIT_TEST( test_inverted_elements );
00339     CPPUNIT_TEST( test_degenerate_elements );
00340     CPPUNIT_TEST( test_get_evaluations );
00341     CPPUNIT_TEST( test_get_element_indices );
00342     CPPUNIT_TEST( test_get_fixed_indices );
00343     CPPUNIT_TEST( test_eval_with_indices );
00344     CPPUNIT_TEST( test_eval_with_gradient );
00345     CPPUNIT_TEST( test_eval_with_hessian );
00346     CPPUNIT_TEST_SUITE_END();
00347 
00348     IdealWeightInverseMeanRatio m1;
00349     PowerQualityMetric m;
00350 
00351   protected:
00352     virtual bool evaluate( PatchData&, size_t, double&, MsqError& );
00353 
00354   public:
00355     PowerQualityMetricTest() : m( &m1, POWER )
00356     {
00357         mMetric = &m;
00358     }
00359 };
00360 
00361 template < int POWER >
00362 bool PowerQualityMetricTest< POWER >::evaluate( PatchData& pd, size_t h, double& val, MsqError& err )
00363 {
00364     bool rval = m1.evaluate( pd, h, val, err );
00365     MSQ_ERRFALSE( err );
00366     val = std::pow( val, POWER );
00367     return rval;
00368 }
00369 
00370 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 1 >, "CompositeMetricTest" );
00371 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 2 >, "CompositeMetricTest" );
00372 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 1 >, "PowerQualityMetricTest" );
00373 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 2 >, "PowerQualityMetricTest" );
00374 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 1 >, "Unit" );
00375 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( PowerQualityMetricTest< 2 >, "Unit" );
00376 
00377 template < int OFFSET >
00378 class ScalarAddMetricTest : public CompositeMetricTestBase
00379 {
00380   private:
00381     CPPUNIT_TEST_SUITE( ScalarAddMetricTest< OFFSET > );
00382     CPPUNIT_TEST( test_supported_types );
00383     CPPUNIT_TEST( test_ideal_element_eval );
00384     CPPUNIT_TEST( test_ideal_element_grad );
00385     CPPUNIT_TEST( test_ideal_element_hess );
00386     CPPUNIT_TEST( test_non_ideal_eval );
00387     CPPUNIT_TEST( test_valid_hessian );
00388     CPPUNIT_TEST( test_inverted_elements );
00389     CPPUNIT_TEST( test_degenerate_elements );
00390     CPPUNIT_TEST( test_get_evaluations );
00391     CPPUNIT_TEST( test_get_element_indices );
00392     CPPUNIT_TEST( test_get_fixed_indices );
00393     CPPUNIT_TEST( test_eval_with_indices );
00394     CPPUNIT_TEST( test_eval_with_gradient );
00395     CPPUNIT_TEST( test_eval_with_hessian );
00396     CPPUNIT_TEST_SUITE_END();
00397 
00398     IdealWeightInverseMeanRatio m1;
00399     ScalarAddQualityMetric m;
00400 
00401   protected:
00402     virtual bool evaluate( PatchData&, size_t, double&, MsqError& );
00403 
00404   public:
00405     ScalarAddMetricTest() : m( &m1, OFFSET )
00406     {
00407         mMetric = &m;
00408     }
00409 };
00410 
00411 template < int OFFSET >
00412 bool ScalarAddMetricTest< OFFSET >::evaluate( PatchData& pd, size_t h, double& val, MsqError& err )
00413 {
00414     bool rval = m1.evaluate( pd, h, val, err );
00415     MSQ_ERRFALSE( err );
00416     val += OFFSET;
00417     return rval;
00418 }
00419 
00420 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 0 >, "CompositeMetricTest" );
00421 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 2 >, "CompositeMetricTest" );
00422 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 0 >, "ScalarAddMetricTest" );
00423 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 2 >, "ScalarAddMetricTest" );
00424 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 0 >, "Unit" );
00425 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarAddMetricTest< 2 >, "Unit" );
00426 
00427 template < int SCALE >
00428 class ScalarMultiplyMetricTest : public CompositeMetricTestBase
00429 {
00430   private:
00431     CPPUNIT_TEST_SUITE( ScalarMultiplyMetricTest< SCALE > );
00432     CPPUNIT_TEST( test_supported_types );
00433     CPPUNIT_TEST( test_ideal_element_eval );
00434     CPPUNIT_TEST( test_ideal_element_grad );
00435     CPPUNIT_TEST( test_ideal_element_hess );
00436     CPPUNIT_TEST( test_non_ideal_eval );
00437     CPPUNIT_TEST( test_valid_hessian );
00438     CPPUNIT_TEST( test_inverted_elements );
00439     CPPUNIT_TEST( test_degenerate_elements );
00440     CPPUNIT_TEST( test_get_evaluations );
00441     CPPUNIT_TEST( test_get_element_indices );
00442     CPPUNIT_TEST( test_get_fixed_indices );
00443     CPPUNIT_TEST( test_eval_with_indices );
00444     CPPUNIT_TEST( test_eval_with_gradient );
00445     CPPUNIT_TEST( test_eval_with_hessian );
00446     CPPUNIT_TEST_SUITE_END();
00447 
00448     IdealWeightInverseMeanRatio m1;
00449     ScalarMultiplyQualityMetric m;
00450 
00451   protected:
00452     virtual bool evaluate( PatchData&, size_t, double&, MsqError& );
00453 
00454   public:
00455     ScalarMultiplyMetricTest() : m( &m1, SCALE )
00456     {
00457         mMetric = &m;
00458     }
00459 };
00460 
00461 template < int SCALE >
00462 bool ScalarMultiplyMetricTest< SCALE >::evaluate( PatchData& pd, size_t h, double& val, MsqError& err )
00463 {
00464     bool rval = m1.evaluate( pd, h, val, err );
00465     MSQ_ERRFALSE( err );
00466     val *= SCALE;
00467     return rval;
00468 }
00469 
00470 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 1 >, "CompositeMetricTest" );
00471 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 3 >, "CompositeMetricTest" );
00472 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 1 >, "ScalarMultiplyMetricTest" );
00473 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 3 >, "ScalarMultiplyMetricTest" );
00474 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 1 >, "Unit" );
00475 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ScalarMultiplyMetricTest< 3 >, "Unit" );
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines