|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <sstream> 00010 #include <stdexcept> 00011 00012 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00013 00014 #include <stk_util/parallel/Parallel.hpp> 00015 00016 #include <stk_mesh/fem/FEMMetaData.hpp> 00017 #include <stk_mesh/fem/FEMHelpers.hpp> 00018 00019 #include <stk_mesh/base/MetaData.hpp> 00020 #include <stk_mesh/base/Part.hpp> 00021 #include <stk_mesh/baseImpl/PartRepository.hpp> 00022 #include <stk_mesh/base/FieldRelation.hpp> 00023 #include <stk_mesh/base/PartRelation.hpp> 00024 00025 using stk_classic::mesh::MetaData; 00026 using stk_classic::mesh::Part; 00027 using stk_classic::mesh::PartVector; 00028 using stk_classic::mesh::PartRelation; 00029 using stk_classic::mesh::impl::PartRepository; 00030 00031 namespace { 00032 00033 STKUNIT_UNIT_TEST(UnitTestPart, testUnit) 00034 { 00035 const int spatial_dimension = 3; 00036 MetaData m(stk_classic::mesh::fem::entity_rank_names(spatial_dimension)); 00037 PartRepository partRepo(&m); 00038 PartRepository partRepo2(&m); 00039 PartRepository partRepo3(&m); 00040 PartRepository partRepo4(&m); 00041 Part & universal = *partRepo.universal_part(); 00042 PartVector intersection; 00043 PartVector intersection2; 00044 PartVector intersection4; 00045 PartVector intersection5; 00046 m.commit(); 00047 00048 STKUNIT_ASSERT( universal.supersets().empty() ); 00049 STKUNIT_ASSERT( 1u == partRepo.get_all_parts().size() ); 00050 00051 //-------------------------------------------------------------------- 00052 // Test multiple part creation 00053 00054 enum { NPARTS = 100 }; 00055 00056 Part * parts[NPARTS]; 00057 00058 parts[0] = & universal ; 00059 00060 for ( int i = 1 ; i < NPARTS-1 ; ++i ) { 00061 std::ostringstream name ; 00062 name << "Part_" << i ; 00063 parts[i] = partRepo.declare_part( name.str() , 0 ); 00064 } 00065 parts[99] = partRepo.declare_part( "Part_99" , 1 ); 00066 00067 STKUNIT_ASSERT( universal.supersets().empty() ); 00068 STKUNIT_ASSERT( NPARTS == partRepo.get_all_parts().size() ); 00069 STKUNIT_ASSERT_EQUAL( partRepo.get_all_parts()[0] , & universal ); 00070 00071 for ( unsigned i = 1 ; i < NPARTS ; ++i ) { 00072 STKUNIT_ASSERT( parts[i]->subsets().empty() ); 00073 STKUNIT_ASSERT( parts[i]->intersection_of().empty() ); 00074 STKUNIT_ASSERT( parts[i]->mesh_meta_data_ordinal() == i ); 00075 STKUNIT_ASSERT( 1u == parts[i]->supersets().size() ); 00076 STKUNIT_ASSERT( & universal == parts[i]->supersets()[0] ); 00077 STKUNIT_ASSERT_EQUAL( parts[i] , universal.subsets()[i-1] ); 00078 STKUNIT_ASSERT_EQUAL( parts[i] , find( universal.subsets() , parts[i]->name() ) ); 00079 } 00080 00081 //-------------------------------------------------------------------- 00082 // Test multiple parts and transitive subset declarations: 00083 00084 partRepo.declare_subset( * parts[3], * parts[4] ); 00085 partRepo.declare_subset( * parts[4], * parts[5] ); 00086 00087 partRepo.declare_subset( * parts[1], * parts[2] ); 00088 // 1 and 2 pick up 4 and 5 via transitive relationship: 00089 partRepo.declare_subset( * parts[2], * parts[3] ); 00090 00091 STKUNIT_ASSERT( 4u == parts[1]->subsets().size() ); 00092 STKUNIT_ASSERT( 3u == parts[2]->subsets().size() ); 00093 STKUNIT_ASSERT( 2u == parts[3]->subsets().size() ); 00094 STKUNIT_ASSERT( 1u == parts[4]->subsets().size() ); 00095 STKUNIT_ASSERT( 0u == parts[5]->subsets().size() ); 00096 00097 STKUNIT_ASSERT( contain( parts[1]->subsets() , * parts[2] ) ); 00098 STKUNIT_ASSERT( contain( parts[1]->subsets() , * parts[3] ) ); 00099 STKUNIT_ASSERT( contain( parts[1]->subsets() , * parts[4] ) ); 00100 STKUNIT_ASSERT( contain( parts[1]->subsets() , * parts[5] ) ); 00101 00102 STKUNIT_ASSERT( contain( parts[5]->supersets() , * parts[1] ) ); 00103 STKUNIT_ASSERT( contain( parts[5]->supersets() , * parts[2] ) ); 00104 STKUNIT_ASSERT( contain( parts[5]->supersets() , * parts[3] ) ); 00105 STKUNIT_ASSERT( contain( parts[5]->supersets() , * parts[4] ) ); 00106 00107 //-------------------------------------------------------------------- 00108 // Test declaration of an intersection part 00109 00110 intersection.push_back( parts[1] ); 00111 intersection.push_back( parts[2] ); 00112 intersection.push_back( parts[3] ); 00113 intersection.push_back( parts[4] ); // Smallest subset of 1..4 00114 00115 // Test filtering of trivial intersection 00116 00117 STKUNIT_ASSERT( parts[4] == partRepo.declare_part( intersection ) ); 00118 00119 // Test non-trivial intersection: 00120 00121 intersection.push_back( parts[6] ); 00122 intersection.push_back( parts[7] ); 00123 00124 Part & pint_4_6_7 = * partRepo.declare_part( intersection ); 00125 00126 STKUNIT_ASSERT( 3u == pint_4_6_7.intersection_of().size() ); 00127 STKUNIT_ASSERT( contain( pint_4_6_7.intersection_of() , * parts[4] ) ); 00128 STKUNIT_ASSERT( contain( pint_4_6_7.intersection_of() , * parts[6] ) ); 00129 STKUNIT_ASSERT( contain( pint_4_6_7.intersection_of() , * parts[7] ) ); 00130 00131 STKUNIT_ASSERT( 7u == pint_4_6_7.supersets().size() ); 00132 00133 // Test redeclaration of intersection, should give the same part back: 00134 00135 STKUNIT_ASSERT( pint_4_6_7 == * partRepo.declare_part( intersection ) ); 00136 00137 partRepo.declare_subset( pint_4_6_7, * parts[8] ); 00138 00139 //-------------------------------------------------------------------- 00140 // Test intersection-induced subset relationship 00141 00142 partRepo.declare_subset( * parts[7], * parts[10] ); 00143 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[10] ) ); 00144 00145 partRepo.declare_subset( * parts[6], * parts[10] ); 00146 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[10] ) ); 00147 00148 partRepo.declare_subset( * parts[3], * parts[10] ); 00149 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[10] ) ); 00150 00151 partRepo.declare_subset( * parts[4], * parts[10] ); 00152 STKUNIT_ASSERT( contain( pint_4_6_7.subsets() , * parts[10] ) ); 00153 00154 // Test intersection-induced subset relationship triggered from a subset 00155 00156 partRepo.declare_subset( * parts[7], * parts[11] ); 00157 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[11] ) ); 00158 00159 partRepo.declare_subset( * parts[6], * parts[11] ); 00160 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[11] ) ); 00161 00162 partRepo.declare_subset( * parts[3], * parts[11] ); 00163 STKUNIT_ASSERT( ! contain( pint_4_6_7.subsets() , * parts[11] ) ); 00164 00165 partRepo.declare_subset( * parts[5], * parts[11] ); 00166 STKUNIT_ASSERT( contain( pint_4_6_7.subsets() , * parts[11] ) ); 00167 00168 std::cout << std::endl << "Part: test intersection generated" << std::endl ; 00169 print( std::cout , " " , pint_4_6_7 ); 00170 print( std::cout , " " , * parts[10] ); 00171 print( std::cout , " " , * parts[11] ); 00172 00173 std::cout << std::endl ; 00174 00175 //Test to cover assert_same_universe in PartRepository - Part is not in the same universe 00176 { 00177 std::vector< std::string > dummy_names(1); 00178 dummy_names[0].assign("dummy"); 00179 00180 stk_classic::mesh::MetaData meta2( dummy_names ); 00181 00182 stk_classic::mesh::Part &part_not_in_same_universe = meta2.declare_part ( "part_not_in_same_universe"); 00183 meta2.commit(); 00184 00185 intersection4.push_back( &part_not_in_same_universe ); 00186 00187 PartVector::const_iterator i = intersection4.begin() ; 00188 Part * const p = *i ; 00189 STKUNIT_ASSERT_THROW( 00190 partRepo3.declare_subset(*parts[5], *p), 00191 std::runtime_error 00192 ); 00193 } 00194 00195 //Test to cover assert_not_superset in PartRepository - parts[11] is not a superset of parts[7] 00196 { 00197 STKUNIT_ASSERT_THROW( 00198 partRepo.declare_subset(*parts[11], *parts[7] ), 00199 std::runtime_error 00200 ); 00201 } 00202 00203 //Test to cover assert_not_superset in PartRepository - parts[99] is not the same rank of parts[11] 00204 { 00205 STKUNIT_ASSERT_THROW( 00206 partRepo.declare_subset(*parts[11], *parts[99] ), 00207 std::runtime_error 00208 ); 00209 } 00210 00211 //Test to cover declare_part(arg_name, arg_rank) - Part_99 of rank 1 already exists.. 00212 { 00213 STKUNIT_ASSERT_THROW( 00214 partRepo.declare_part("Part_99", 0 ), 00215 std::runtime_error 00216 ); 00217 } 00218 00219 //Test to cover declare_part(const PartVector & part_intersect) in PartRepository - failed from malicious abuse 00220 { 00221 int ok = 0 ; 00222 try { 00223 //create part with intersection 00224 00225 // Test declaration of an intersection part 00226 00227 enum { NPARTS = 100 }; 00228 00229 Part * parts2[ NPARTS ] ; 00230 00231 parts2[0] = & universal ; 00232 00233 for ( int i = 1 ; i < NPARTS-1 ; ++i ) { 00234 std::ostringstream name ; 00235 name << "Part_" << i ; 00236 parts2[i] = partRepo4.declare_part( name.str() , 0 ); 00237 } 00238 00239 partRepo4.declare_subset( * parts2[3], * parts2[4] ); 00240 partRepo4.declare_subset( * parts2[4], * parts2[5] ); 00241 00242 partRepo4.declare_subset( * parts2[1], * parts2[2] ); 00243 // 1 and 2 pick up 4 and 5 via transitive relationship: 00244 partRepo4.declare_subset( * parts2[2], * parts2[3] ); 00245 00246 intersection5.push_back( parts2[1] ); 00247 intersection5.push_back( parts2[2] ); 00248 intersection5.push_back( parts2[3] ); 00249 intersection5.push_back( parts2[4] ); // Smallest subset of 1..4 00250 intersection5.push_back( parts2[6] ); 00251 intersection5.push_back( parts2[7] ); 00252 00253 Part & partB = * partRepo2.declare_part("{Part_4^Part_6^Part_7}", 0); 00254 00255 std::cout << "UnitTestPart name of partB is " << partB.name() << std::endl ; 00256 00257 Part & pintersect_4_6_7 = * partRepo2.declare_part( intersection5 ); 00258 00259 std::cout << "UnitTestPart name of intersection part, pintersect_4_6_7 is " << pintersect_4_6_7.name() << std::endl ; 00260 } 00261 catch( const std::exception & x ) { 00262 ok = 1 ; 00263 std::cout << "UnitTestPart CORRECTLY caught error for : " 00264 << x.what() 00265 << std::endl ; 00266 } 00267 00268 if ( ! ok ) { 00269 throw std::runtime_error("UnitTestPart FAILED to catch error for declare_part in PartRepository"); 00270 } 00271 } 00272 } 00273 00274 STKUNIT_UNIT_TEST(UnitTestPart, testPartNotaSubset) 00275 { 00276 //Test to cover assert_contain in PartRepository - Part is not a subset 00277 const int spatial_dimension = 3; 00278 MetaData m(stk_classic::mesh::fem::entity_rank_names(spatial_dimension)); 00279 PartVector intersection; 00280 PartRepository partRepo(&m); 00281 00282 stk_classic::mesh::Part &part_not_a_subset = m.declare_part ( "part_not_a_subset"); 00283 m.commit(); 00284 00285 intersection.push_back( &part_not_a_subset ); 00286 00287 STKUNIT_ASSERT_THROW( 00288 partRepo.declare_part(intersection), 00289 std::runtime_error 00290 ); 00291 } 00292 00293 //---------------------------------------------------------------------- 00294 00295 STKUNIT_UNIT_TEST(UnitTestPart, testPartVector) 00296 { 00297 const int spatial_dimension = 3; 00298 MetaData m(stk_classic::mesh::fem::entity_rank_names(spatial_dimension)); 00299 PartRepository partRepo(&m); 00300 00301 Part * const pa = partRepo.declare_part( std::string("a") , 0 ); 00302 Part * const pb = partRepo.declare_part( std::string("b") , 0 ); 00303 Part * const pc = partRepo.declare_part( std::string("c") , 0 ); 00304 Part * const pd = partRepo.declare_part( std::string("d") , 0 ); 00305 Part * const pe = partRepo.declare_part( std::string("e") , 0 ); 00306 Part * const pf = partRepo.declare_part( std::string("f") , 0 ); 00307 00308 STKUNIT_ASSERT( ! intersect( *pa , *pb ) ); 00309 STKUNIT_ASSERT( ! intersect( *pb , *pc ) ); 00310 STKUNIT_ASSERT( ! intersect( *pc , *pd ) ); 00311 STKUNIT_ASSERT( ! intersect( *pd , *pe ) ); 00312 STKUNIT_ASSERT( ! intersect( *pe , *pf ) ); 00313 STKUNIT_ASSERT( ! intersect( *pf , *pa ) ); 00314 00315 PartVector vabc , vbcd , vdef , vresult ; 00316 00317 vabc.push_back( pa ); 00318 vabc.push_back( pb ); 00319 vabc.push_back( pc ); 00320 00321 vbcd.push_back( pb ); 00322 vbcd.push_back( pc ); 00323 vbcd.push_back( pd ); 00324 00325 vdef.push_back( pd ); 00326 vdef.push_back( pe ); 00327 vdef.push_back( pf ); 00328 00329 order( vabc ); 00330 order( vbcd ); 00331 order( vdef ); 00332 00333 vresult.clear(); 00334 STKUNIT_ASSERT_EQUAL( size_t(2) , intersect( vabc , vbcd ) ); 00335 size_t intersect_size = intersect( vabc , vbcd , vresult ); 00336 STKUNIT_ASSERT_EQUAL( size_t(2) , intersect_size ); 00337 STKUNIT_ASSERT_EQUAL( pb , vresult[0] ); 00338 STKUNIT_ASSERT_EQUAL( pc , vresult[1] ); 00339 00340 vresult.clear(); 00341 STKUNIT_ASSERT_EQUAL( size_t(1) , intersect( vdef , vbcd ) ); 00342 intersect_size = intersect( vdef , vbcd , vresult ); 00343 STKUNIT_ASSERT_EQUAL( size_t(1) , intersect_size ); 00344 STKUNIT_ASSERT_EQUAL( pd , vresult[0] ); 00345 00346 vresult.clear(); 00347 STKUNIT_ASSERT_EQUAL( size_t(0) , intersect( vdef , vabc ) ); 00348 intersect_size = intersect( vdef , vabc , vresult ); 00349 STKUNIT_ASSERT_EQUAL( size_t(0) , intersect_size ); 00350 STKUNIT_ASSERT_EQUAL( size_t(0) , vresult.size() ); 00351 00352 Part * const pabc = partRepo.declare_part( std::string("abc") , 0 ); 00353 Part * const pbcd = partRepo.declare_part( std::string("bcd") , 0 ); 00354 Part * const pdef = partRepo.declare_part( std::string("def") , 0 ); 00355 00356 partRepo.declare_subset( * pabc, *pa ); 00357 partRepo.declare_subset( * pabc, *pb ); 00358 partRepo.declare_subset( * pabc, *pc ); 00359 00360 partRepo.declare_subset( * pbcd, *pb ); 00361 partRepo.declare_subset( * pbcd, *pc ); 00362 partRepo.declare_subset( * pbcd, *pd ); 00363 00364 partRepo.declare_subset( * pdef, *pd ); 00365 partRepo.declare_subset( * pdef, *pe ); 00366 partRepo.declare_subset( * pdef, *pf ); 00367 00368 STKUNIT_ASSERT( intersect( *pabc , *pa ) ); 00369 STKUNIT_ASSERT( intersect( *pabc , *pb ) ); 00370 STKUNIT_ASSERT( intersect( *pabc , *pc ) ); 00371 STKUNIT_ASSERT( intersect( *pa , *pabc ) ); 00372 STKUNIT_ASSERT( intersect( *pb , *pabc ) ); 00373 STKUNIT_ASSERT( intersect( *pc , *pabc ) ); 00374 00375 STKUNIT_ASSERT( intersect( *pabc , *pbcd ) ); 00376 STKUNIT_ASSERT( ! intersect( *pabc , *pdef ) ); 00377 } 00378 00379 // Unit test the PartRelation copy constructor: 00380 STKUNIT_UNIT_TEST(UnitTestPart, testPartRelation) 00381 { 00382 PartRelation rA; 00383 PartRelation rB( rA); 00384 00385 rA = rB; 00386 } 00387 00388 } // empty namespace