MOAB: Mesh Oriented datABase  (version 5.3.0)
CachingTargetTest.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2006 Lawrence Livermore National Laboratory.  Under
00005     the terms of Contract B545069 with the University of Wisconsin --
00006     Madison, Lawrence Livermore National Laboratory retains certain
00007     rights in 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 CachingTargetTest.cpp
00028  *  \brief Unit tests for CachingTargetCalculator class
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "CachingTargetCalculator.hpp"
00034 #include "PatchData.hpp"
00035 #include "UnitUtil.hpp"
00036 #include "PatchDataInstances.hpp"
00037 #include <cppunit/extensions/HelperMacros.h>
00038 #include <algorithm>
00039 
00040 using namespace MBMesquite;
00041 
00042 class CachedTargetCalculator;
00043 
00044 class CachingTargetTest : public CppUnit::TestFixture
00045 {
00046   private:
00047     CPPUNIT_TEST_SUITE( CachingTargetTest );
00048     CPPUNIT_TEST( test_surface_orient_flag );
00049     CPPUNIT_TEST( test_3d_targets_cached );
00050     CPPUNIT_TEST( test_2d_targets_cached );
00051     CPPUNIT_TEST( test_surface_targets_cached );
00052     CPPUNIT_TEST( test_3d_target_values );
00053     CPPUNIT_TEST( test_2d_target_values );
00054     CPPUNIT_TEST( test_surface_target_values );
00055     CPPUNIT_TEST( test_3d_target_subpatch );
00056     CPPUNIT_TEST( test_2d_target_subpatch );
00057     CPPUNIT_TEST( test_surface_target_subpatch );
00058     CPPUNIT_TEST( test_cache_cleared );
00059     CPPUNIT_TEST_SUITE_END();
00060 
00061     PatchData patch_3d, patch_2d;
00062     CachedTargetCalculator* cached;
00063     CachingTargetCalculator* cacher;
00064 
00065     unsigned request_all_targets_3d();
00066     unsigned request_all_targets_2d();
00067     unsigned request_all_targets_surf();
00068 
00069   public:
00070     void setUp();
00071     void tearDown();
00072 
00073     void test_surface_orient_flag();
00074     void test_3d_targets_cached();
00075     void test_2d_targets_cached();
00076     void test_surface_targets_cached();
00077     void test_3d_target_values();
00078     void test_2d_target_values();
00079     void test_surface_target_values();
00080     void test_3d_target_subpatch();
00081     void test_2d_target_subpatch();
00082     void test_surface_target_subpatch();
00083     void test_cache_cleared();
00084 };
00085 
00086 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CachingTargetTest, "CachingTargetTest" );
00087 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CachingTargetTest, "Unit" );
00088 
00089 class CachedTargetCalculator : public TargetCalculator
00090 {
00091   private:
00092     unsigned called_3d, called_2d, called_surf;
00093     bool surfOrientFlag;
00094 
00095   public:
00096     static MsqMatrix< 3, 3 > make_3d( size_t elem, Sample sample );
00097     static MsqMatrix< 2, 2 > make_2d( size_t elem, Sample sample );
00098     static MsqMatrix< 3, 2 > make_surf( size_t elem, Sample sample );
00099 
00100     CachedTargetCalculator() : called_3d( 0 ), called_2d( 0 ), called_surf( 0 ), surfOrientFlag( true ) {}
00101 
00102     virtual bool get_3D_target( PatchData&, size_t elem, Sample sample, MsqMatrix< 3, 3 >& result, MsqError& )
00103     {
00104         ++called_3d;
00105         result = make_3d( elem, sample );
00106         return true;
00107     }
00108 
00109     virtual bool get_2D_target( PatchData&, size_t elem, Sample sample, MsqMatrix< 2, 2 >& result, MsqError& )
00110     {
00111         ++called_2d;
00112         result = make_2d( elem, sample );
00113         return true;
00114     }
00115 
00116     virtual bool get_surface_target( PatchData&, size_t elem, Sample sample, MsqMatrix< 3, 2 >& result, MsqError& )
00117     {
00118         ++called_surf;
00119         result = make_surf( elem, sample );
00120         return true;
00121     }
00122 
00123     void clear()
00124     {
00125         called_3d   = 0;
00126         called_2d   = 0;
00127         called_surf = 0;
00128     }
00129 
00130     unsigned calls_3d() const
00131     {
00132         return called_3d;
00133     }
00134 
00135     unsigned calls_2d() const
00136     {
00137         return called_2d;
00138     }
00139 
00140     unsigned calls_surf() const
00141     {
00142         return called_surf;
00143     }
00144 
00145     void surf_orient( bool value )
00146     {
00147         surfOrientFlag = value;
00148     }
00149 
00150     virtual bool have_surface_orient() const
00151     {
00152         return surfOrientFlag;
00153     }
00154 };
00155 
00156 MsqMatrix< 3, 3 > CachedTargetCalculator::make_3d( size_t elem, Sample sample )
00157 {
00158     double v              = 100. * elem + 4 * sample.number + sample.dimension + 1;
00159     const double values[] = { v, 0, 0, 0, v, 0, 0, 0, 1 / v };
00160     return MsqMatrix< 3, 3 >( values );
00161 }
00162 
00163 MsqMatrix< 2, 2 > CachedTargetCalculator::make_2d( size_t elem, Sample sample )
00164 {
00165     double v              = 100. * elem + 4 * sample.number + sample.dimension + 1;
00166     const double values[] = { v, 0, 0, 1 / v };
00167     return MsqMatrix< 2, 2 >( values );
00168 }
00169 
00170 MsqMatrix< 3, 2 > CachedTargetCalculator::make_surf( size_t elem, Sample sample )
00171 {
00172     double v              = 100. * elem + 4 * sample.number + sample.dimension + 1;
00173     const double values[] = { v, 0, 0, v, 0.5 * v, 0.5 * v };
00174     return MsqMatrix< 3, 2 >( values );
00175 }
00176 
00177 void CachingTargetTest::setUp()
00178 {
00179     // make sure these are null so that if we fail within setUp,
00180     // tearDown doesn't try to delete stale pointers
00181     cached = 0;
00182     cacher = 0;
00183 
00184     MsqError err;
00185     create_four_quads_patch( patch_2d, err );
00186     CPPUNIT_ASSERT( !err );
00187     create_qm_two_hex_patch( patch_3d, err );
00188     CPPUNIT_ASSERT( !err );
00189 
00190     cached = new CachedTargetCalculator();
00191     cacher = new CachingTargetCalculator( cached );
00192 }
00193 
00194 unsigned CachingTargetTest::request_all_targets_3d()
00195 {
00196     unsigned total = 0;
00197     MsqMatrix< 3, 3 > W;
00198     MsqPrintError err( std::cout );
00199     std::vector< Sample > locations;
00200 
00201     for( size_t i = 0; i < patch_3d.num_elements(); ++i )
00202     {
00203         patch_3d.get_samples( i, locations, err );
00204         ASSERT_NO_ERROR( err );
00205         total += locations.size();
00206         for( unsigned j = 0; j < locations.size(); ++j )
00207         {
00208             bool rval = cacher->get_3D_target( patch_3d, i, locations[j], W, err );
00209             CPPUNIT_ASSERT( rval );
00210             CPPUNIT_ASSERT( !err );
00211         }
00212     }
00213     return total;
00214 }
00215 
00216 unsigned CachingTargetTest::request_all_targets_2d()
00217 {
00218     unsigned total = 0;
00219     MsqMatrix< 2, 2 > W;
00220     MsqPrintError err( std::cout );
00221     std::vector< Sample > locations;
00222 
00223     for( size_t i = 0; i < patch_2d.num_elements(); ++i )
00224     {
00225         patch_2d.get_samples( i, locations, err );
00226         ASSERT_NO_ERROR( err );
00227         total += locations.size();
00228         for( unsigned j = 0; j < locations.size(); ++j )
00229         {
00230             bool rval = cacher->get_2D_target( patch_2d, i, locations[j], W, err );
00231             CPPUNIT_ASSERT( rval );
00232             CPPUNIT_ASSERT( !err );
00233         }
00234     }
00235     return total;
00236 }
00237 
00238 unsigned CachingTargetTest::request_all_targets_surf()
00239 {
00240     unsigned total = 0;
00241     MsqMatrix< 3, 2 > W;
00242     MsqPrintError err( std::cout );
00243     std::vector< Sample > locations;
00244 
00245     for( size_t i = 0; i < patch_2d.num_elements(); ++i )
00246     {
00247         patch_2d.get_samples( i, locations, err );
00248         ASSERT_NO_ERROR( err );
00249         total += locations.size();
00250         for( unsigned j = 0; j < locations.size(); ++j )
00251         {
00252             bool rval = cacher->get_surface_target( patch_2d, i, locations[j], W, err );
00253             CPPUNIT_ASSERT( rval );
00254             CPPUNIT_ASSERT( !err );
00255         }
00256     }
00257     return total;
00258 }
00259 
00260 void CachingTargetTest::tearDown()
00261 {
00262     delete cacher;
00263     delete cached;
00264 }
00265 
00266 void CachingTargetTest::test_surface_orient_flag()
00267 {
00268     cached->surf_orient( true );
00269     CPPUNIT_ASSERT( cacher->have_surface_orient() );
00270     cached->surf_orient( false );
00271     CPPUNIT_ASSERT( !cacher->have_surface_orient() );
00272 }
00273 
00274 void CachingTargetTest::test_3d_targets_cached()
00275 {
00276     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00277     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00278     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00279     unsigned count = request_all_targets_3d();
00280     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), count );
00281     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00282     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00283     cached->clear();
00284     request_all_targets_3d();
00285     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00286 }
00287 
00288 void CachingTargetTest::test_2d_targets_cached()
00289 {
00290     cached->surf_orient( false );
00291     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00292     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00293     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00294     unsigned count = request_all_targets_2d();
00295     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), count );
00296     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00297     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00298     cached->clear();
00299     request_all_targets_2d();
00300     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00301 }
00302 
00303 void CachingTargetTest::test_surface_targets_cached()
00304 {
00305     cached->surf_orient( true );
00306     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00307     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00308     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00309     unsigned count = request_all_targets_surf();
00310     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00311     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), count );
00312     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00313     cached->clear();
00314     request_all_targets_surf();
00315     CPPUNIT_ASSERT_EQUAL( cached->calls_surf(), 0u );
00316 }
00317 
00318 void CachingTargetTest::test_3d_target_values()
00319 {
00320     MsqPrintError err( std::cout );
00321     std::vector< Sample > locations;
00322 
00323     // evaluate all once to make sure we test the cached values
00324     request_all_targets_3d();
00325 
00326     // test each value
00327     for( size_t i = 0; i < patch_3d.num_elements(); ++i )
00328     {
00329         patch_3d.get_samples( i, locations, err );
00330         ASSERT_NO_ERROR( err );
00331         for( unsigned j = 0; j < locations.size(); ++j )
00332         {
00333             MsqMatrix< 3, 3 > W;
00334             bool rval = cacher->get_3D_target( patch_3d, i, locations[j], W, err );
00335             CPPUNIT_ASSERT( rval && !err );
00336 
00337             MsqMatrix< 3, 3 > M = CachedTargetCalculator::make_3d( i, locations[j] );
00338             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00339         }
00340     }
00341 }
00342 
00343 void CachingTargetTest::test_2d_target_values()
00344 {
00345     MsqPrintError err( std::cout );
00346     std::vector< Sample > locations;
00347 
00348     // evaluate all once to make sure we test the cached values
00349     cached->surf_orient( false );
00350     request_all_targets_2d();
00351 
00352     // test each value
00353     for( size_t i = 0; i < patch_2d.num_elements(); ++i )
00354     {
00355         patch_2d.get_samples( i, locations, err );
00356         ASSERT_NO_ERROR( err );
00357         for( unsigned j = 0; j < locations.size(); ++j )
00358         {
00359             MsqMatrix< 2, 2 > W;
00360             bool rval = cacher->get_2D_target( patch_2d, i, locations[j], W, err );
00361             CPPUNIT_ASSERT( rval && !err );
00362 
00363             MsqMatrix< 2, 2 > M = CachedTargetCalculator::make_2d( i, locations[j] );
00364             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00365         }
00366     }
00367 }
00368 
00369 void CachingTargetTest::test_surface_target_values()
00370 {
00371     MsqPrintError err( std::cout );
00372     std::vector< Sample > locations;
00373 
00374     // evaluate all once to make sure we test the cached values
00375     cached->surf_orient( true );
00376     request_all_targets_surf();
00377 
00378     // test each value
00379     for( size_t i = 0; i < patch_2d.num_elements(); ++i )
00380     {
00381         patch_2d.get_samples( i, locations, err );
00382         ASSERT_NO_ERROR( err );
00383         for( unsigned j = 0; j < locations.size(); ++j )
00384         {
00385             MsqMatrix< 3, 2 > W;
00386             bool rval = cacher->get_surface_target( patch_2d, i, locations[j], W, err );
00387             CPPUNIT_ASSERT( rval && !err );
00388 
00389             MsqMatrix< 3, 2 > M = CachedTargetCalculator::make_surf( i, locations[j] );
00390             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00391         }
00392     }
00393 }
00394 
00395 void CachingTargetTest::test_3d_target_subpatch()
00396 {
00397     MsqPrintError err( std::cout );
00398     std::vector< Sample > locations;
00399 
00400     // cache some values on the main patch
00401     request_all_targets_3d();
00402 
00403     // clear the count so we know if any additional
00404     // evalutions of the base target calculator are
00405     // done during subpatch creation.
00406     cached->clear();
00407 
00408     // create a sub-patch
00409     CPPUNIT_ASSERT( patch_3d.num_nodes() > 1 );
00410     PatchData subpatch;
00411     patch_3d.get_subpatch( 1, 1, subpatch, err );
00412     CPPUNIT_ASSERT( !err );
00413 
00414     // make sure we copied the cached values onto the subpatch
00415     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), 0u );
00416 
00417     // Test the values for each cached matrix on the subpatch
00418     // NOTE:  This test takes advantange of the fact that the
00419     // "handles" in the subpatch are indices into the main patch.
00420 
00421     // test each value
00422     for( size_t i = 0; i < subpatch.num_elements(); ++i )
00423     {
00424         subpatch.get_samples( i, locations, err );
00425         ASSERT_NO_ERROR( err );
00426         for( unsigned j = 0; j < locations.size(); ++j )
00427         {
00428             MsqMatrix< 3, 3 > W;
00429             bool rval = cacher->get_3D_target( subpatch, i, locations[j], W, err );
00430             CPPUNIT_ASSERT( rval && !err );
00431 
00432             Mesh::ElementHandle h      = subpatch.get_element_handles_array()[i];
00433             Mesh::ElementHandle* old_h = patch_3d.get_element_handles_array();
00434             size_t old_idx             = std::find( old_h, old_h + patch_3d.num_elements(), h ) - old_h;
00435             CPPUNIT_ASSERT( old_idx < patch_3d.num_elements() );
00436             MsqMatrix< 3, 3 > M = CachedTargetCalculator::make_3d( old_idx, locations[j] );
00437             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00438         }
00439     }
00440 }
00441 
00442 void CachingTargetTest::test_2d_target_subpatch()
00443 {
00444     MsqPrintError err( std::cout );
00445     std::vector< Sample > locations;
00446 
00447     // cache some values on the main patch
00448     cached->surf_orient( false );
00449     request_all_targets_2d();
00450 
00451     // clear the count so we know if any additional
00452     // evalutions of the base target calculator are
00453     // done during subpatch creation.
00454     cached->clear();
00455 
00456     // create a sub-patch
00457     CPPUNIT_ASSERT( patch_2d.num_nodes() > 1 );
00458     PatchData subpatch;
00459     patch_2d.get_subpatch( 1, 1, subpatch, err );
00460     CPPUNIT_ASSERT( !err );
00461 
00462     // make sure we copied the cached values onto the subpatch
00463     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00464 
00465     // Test the values for each cached matrix on the subpatch
00466     // NOTE:  This test takes advantange of the fact that the
00467     // "handles" in the subpatch are indices into the main patch.
00468 
00469     // test each value
00470     for( size_t i = 0; i < subpatch.num_elements(); ++i )
00471     {
00472         subpatch.get_samples( i, locations, err );
00473         ASSERT_NO_ERROR( err );
00474         for( unsigned j = 0; j < locations.size(); ++j )
00475         {
00476             MsqMatrix< 2, 2 > W;
00477             bool rval = cacher->get_2D_target( subpatch, i, locations[j], W, err );
00478             CPPUNIT_ASSERT( rval && !err );
00479 
00480             Mesh::ElementHandle h      = subpatch.get_element_handles_array()[i];
00481             Mesh::ElementHandle* old_h = patch_2d.get_element_handles_array();
00482             size_t old_idx             = std::find( old_h, old_h + patch_2d.num_elements(), h ) - old_h;
00483             CPPUNIT_ASSERT( old_idx < patch_2d.num_elements() );
00484             MsqMatrix< 2, 2 > M = CachedTargetCalculator::make_2d( old_idx, locations[j] );
00485             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00486         }
00487     }
00488 }
00489 
00490 void CachingTargetTest::test_surface_target_subpatch()
00491 {
00492     MsqPrintError err( std::cout );
00493     std::vector< Sample > locations;
00494 
00495     // cache some values on the main patch
00496     cached->surf_orient( true );
00497     request_all_targets_surf();
00498 
00499     // clear the count so we know if any additional
00500     // evalutions of the base target calculator are
00501     // done during subpatch creation.
00502     cached->clear();
00503 
00504     // create a sub-patch
00505     CPPUNIT_ASSERT( patch_2d.num_nodes() > 1 );
00506     PatchData subpatch;
00507     patch_2d.get_subpatch( 1, 1, subpatch, err );
00508     CPPUNIT_ASSERT( !err );
00509 
00510     // make sure we copied the cached values onto the subpatch
00511     CPPUNIT_ASSERT_EQUAL( cached->calls_2d(), 0u );
00512 
00513     // Test the values for each cached matrix on the subpatch
00514     // NOTE:  This test takes advantange of the fact that the
00515     // "handles" in the subpatch are indices into the main patch.
00516 
00517     // test each value
00518     for( size_t i = 0; i < subpatch.num_elements(); ++i )
00519     {
00520         subpatch.get_samples( i, locations, err );
00521         ASSERT_NO_ERROR( err );
00522         for( unsigned j = 0; j < locations.size(); ++j )
00523         {
00524             MsqMatrix< 3, 2 > W;
00525             bool rval = cacher->get_surface_target( subpatch, i, locations[j], W, err );
00526             CPPUNIT_ASSERT( rval && !err );
00527 
00528             Mesh::ElementHandle h      = subpatch.get_element_handles_array()[i];
00529             Mesh::ElementHandle* old_h = patch_2d.get_element_handles_array();
00530             size_t old_idx             = std::find( old_h, old_h + patch_2d.num_elements(), h ) - old_h;
00531             CPPUNIT_ASSERT( old_idx < patch_2d.num_elements() );
00532             MsqMatrix< 3, 2 > M = CachedTargetCalculator::make_surf( old_idx, locations[j] );
00533             ASSERT_MATRICES_EQUAL( W, M, DBL_EPSILON );
00534         }
00535     }
00536 }
00537 
00538 void CachingTargetTest::test_cache_cleared()
00539 {
00540     MsqPrintError err( std::cout );
00541 
00542     // cache some values on the main patch
00543     request_all_targets_3d();
00544 
00545     // clear the count so we know if any additional
00546     // evalutions of the base target calculator are
00547     // done.
00548     cached->clear();
00549 
00550     // now re-create the patch, which should result in the
00551     // cached data being notified that the mesh has changed
00552     create_twelve_hex_patch( patch_3d, err );
00553     CPPUNIT_ASSERT( !err );
00554 
00555     // now get cached values for each element
00556     unsigned count = request_all_targets_3d();
00557 
00558     // and check that they were all re-calculated
00559     CPPUNIT_ASSERT_EQUAL( cached->calls_3d(), count );
00560 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines