MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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) [email protected] 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 }