|
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 00010 #include <sstream> 00011 #include <stdexcept> 00012 00013 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00014 00015 #include <stk_util/parallel/Parallel.hpp> 00016 00017 #include <stk_mesh/base/MetaData.hpp> 00018 #include <stk_mesh/base/BulkData.hpp> 00019 #include <stk_mesh/base/GetEntities.hpp> 00020 #include <stk_mesh/base/Field.hpp> 00021 #include <stk_mesh/base/FieldData.hpp> 00022 #include <stk_mesh/base/Comm.hpp> 00023 #include <stk_mesh/base/EntityComm.hpp> 00024 #include <stk_mesh/base/Part.hpp> 00025 #include <stk_mesh/base/Entity.hpp> 00026 #include <stk_mesh/base/GetBuckets.hpp> 00027 #include <stk_mesh/base/Bucket.hpp> 00028 #include <stk_mesh/base/BulkModification.hpp> 00029 #include <stk_mesh/base/Entity.hpp> 00030 #include <stk_mesh/base/Bucket.hpp> 00031 #include <stk_mesh/base/Ghosting.hpp> 00032 00033 #include <stk_mesh/fem/FEMMetaData.hpp> 00034 #include <stk_mesh/fem/FEMHelpers.hpp> 00035 00036 #include <stk_mesh/baseImpl/BucketImpl.hpp> 00037 00038 #include <stk_mesh/fixtures/BoxFixture.hpp> 00039 00040 #include <Shards_BasicTopologies.hpp> 00041 00042 using stk_classic::mesh::fem::FEMMetaData; 00043 using stk_classic::mesh::MetaData; 00044 using stk_classic::mesh::BulkData; 00045 using stk_classic::mesh::Part; 00046 using stk_classic::mesh::PartVector; 00047 using stk_classic::mesh::EntityRank; 00048 using stk_classic::mesh::EntityId; 00049 using stk_classic::mesh::PairIterEntityComm; 00050 using stk_classic::mesh::Entity; 00051 using stk_classic::mesh::Bucket; 00052 using stk_classic::mesh::BucketIterator; 00053 using stk_classic::mesh::Selector; 00054 using stk_classic::mesh::Field; 00055 using stk_classic::mesh::FieldBase; 00056 using stk_classic::mesh::put_field; 00057 00058 typedef Field<double> ScalarFieldType; 00059 00060 namespace { 00061 00062 const EntityRank NODE_RANK = FEMMetaData::NODE_RANK; 00063 00064 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testBucket) 00065 { 00066 // Unit test the Part functionality in isolation: 00067 00068 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00069 MPI_Barrier( pm ); 00070 00071 // Create a mesh for testing buckets... 00072 00073 // Create dummy names for entity ranks to be given to MetaData 00074 std::vector<std::string> entity_names(10); 00075 for ( size_t i = 0 ; i < 10 ; ++i ) { 00076 std::ostringstream name ; 00077 name << "EntityRank" << i ; 00078 entity_names[i] = name.str(); 00079 } 00080 00081 // Create MetaData, BulkData 00082 unsigned max_bucket_size = 4; 00083 stk_classic::mesh::fixtures::BoxFixture fixture(pm, max_bucket_size, entity_names); 00084 FEMMetaData& meta = fixture.fem_meta(); 00085 BulkData& bulk = fixture.bulk_data(); 00086 const EntityRank element_rank = meta.element_rank(); 00087 // Create two scalar fields, temperature and volume. Put temperature 00088 // on all the nodes and put volume on all the elements. 00089 unsigned number_of_states = 4; 00090 00091 ScalarFieldType & temperature = 00092 meta.declare_field < ScalarFieldType > ( "temperature" , number_of_states ); 00093 ScalarFieldType & volume = 00094 00095 meta.declare_field < ScalarFieldType > ( "volume" , number_of_states ); 00096 Part & universal = meta.universal_part (); 00097 put_field ( temperature , NODE_RANK , universal ); 00098 put_field ( volume , element_rank , universal ); 00099 meta.commit(); 00100 00101 // Generate the mesh 00102 int root_box[3][2] = { { 0,4 } , { 0,5 } , { 0,6 } }; 00103 int local_box[3][2] = { { 0,0 } , { 0,0 } , { 0,0 } }; 00104 bulk.modification_begin(); 00105 fixture.generate_boxes( root_box, local_box ); 00106 STKUNIT_ASSERT(bulk.modification_end()); 00107 00108 // First, test for streaming IO; 00109 { 00110 std::string gold1; 00111 // Parallel and Serial runs have different part intersections for the first 00112 // bucket 00113 if ( bulk.parallel_size() == 1 ) 00114 gold1 = "Bucket( EntityRank0 : {UNIVERSAL} {OWNS} )"; 00115 else 00116 gold1 = "Bucket( EntityRank0 : {UNIVERSAL} )"; 00117 Bucket *b1 = bulk.buckets(0)[0]; 00118 std::stringstream out1_str; 00119 out1_str << (*b1); 00120 bool equal = (gold1 == out1_str.str()); 00121 STKUNIT_ASSERT_EQUAL ( equal, true ); 00122 } 00123 00124 // Second, update state of bucket until circular cue is filled 00125 { 00126 /* Need to set some data in state, rotate look for it, rotate 3 more times 00127 and look for it again */ 00128 for ( size_t i = 0 ; i != 10 ; ++i ) 00129 bulk.update_field_data_states (); 00130 } 00131 00132 // Third, checking field_data_valid (...) 00133 { 00134 const std::vector< FieldBase * > &field_bases = meta.get_fields(); 00135 STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases[0] , *bulk.buckets(3)[0] , 1 , "error" ) , std::runtime_error); 00136 STKUNIT_ASSERT_EQUAL(field_data_valid ( *field_bases[0] , *bulk.buckets(0)[0] , 1 , "no_error" ) , true); 00137 STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases[0] , *bulk.buckets(3)[0] , 99 , "error" ) , std::runtime_error); 00138 00139 // Set up a second mesh 00140 00141 MetaData meta2 ( entity_names ); 00142 BulkData bulk2( meta2 , pm , max_bucket_size ); 00143 00144 ScalarFieldType & temperature2 = 00145 meta2.declare_field < ScalarFieldType > ( "temperature2" , number_of_states ); 00146 ScalarFieldType & volume2 = 00147 meta2.declare_field < ScalarFieldType > ( "volume2" , number_of_states ); 00148 Part & universal2 = meta2.universal_part (); 00149 put_field ( temperature2 , NODE_RANK , universal2 ); 00150 put_field ( volume2 , element_rank , universal2 ); 00151 meta2.commit(); 00152 00153 // Cover line containing messsage for wrong MetaData used 00154 const std::vector< FieldBase * > &field_bases2 = meta2.get_fields(); 00155 STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases2[0] , *bulk.buckets(0)[0] , 1 , "error" ) , std::runtime_error); 00156 } 00157 00158 // Fourth, check has_superset (...) and membership functions 00159 { 00160 PartVector tmp(2) ; 00161 tmp[0] = & meta.universal_part(); 00162 tmp[1] = & meta.locally_owned_part(); 00163 STKUNIT_ASSERT_EQUAL ( has_superset ( *bulk.buckets(0)[0] , tmp ) , bulk.parallel_size() == 1 ); 00164 STKUNIT_ASSERT ( bulk.buckets(0)[0]->member_any ( tmp ) ); 00165 STKUNIT_ASSERT_EQUAL ( bulk.buckets(0)[0]->member_all ( tmp ) , bulk.parallel_size() == 1 ); 00166 STKUNIT_ASSERT ( bulk.buckets(0)[0]->member ( **meta.get_parts().begin() ) ); 00167 } 00168 } 00169 00170 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testGetInvolvedParts) 00171 { 00172 // Tests to cover get_involved_parts for GetBuckets.cpp - C.Brickley - 12 May 2010 00173 00174 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00175 MPI_Barrier( pm ); 00176 00177 const int spatial_dimension = 3; 00178 00179 FEMMetaData meta( spatial_dimension ); 00180 const EntityRank element_rank = meta.element_rank(); 00181 const EntityRank edge_rank = meta.edge_rank(); 00182 00183 PartVector involved_parts(2) ; 00184 involved_parts[0] = & meta.universal_part(); 00185 involved_parts[1] = & meta.locally_owned_part(); 00186 00187 Part & partLeft_1 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_1" ); 00188 00189 Part & partLeft_2 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_2" ); 00190 00191 meta.commit(); 00192 00193 PartVector union_parts; 00194 union_parts.push_back(&partLeft_1); 00195 union_parts.push_back(&partLeft_2); 00196 00197 BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 ); 00198 PartVector add_part4, no_part; 00199 add_part4.push_back ( &partLeft_1 ); 00200 00201 bulk.modification_begin(); 00202 int size , rank; 00203 rank = stk_classic::parallel_machine_rank( pm ); 00204 size = stk_classic::parallel_machine_size( pm ); 00205 00206 for ( int id_base = 0 ; id_base < 99 ; ++id_base ) 00207 { 00208 int new_id = size * id_base + rank + 1; 00209 bulk.declare_entity( 3 , new_id , add_part4 ); 00210 bulk.declare_entity( NODE_RANK , new_id , no_part ); 00211 } 00212 00213 bulk.modification_end(); 00214 00215 const std::vector<Bucket*> & buckets = bulk.buckets( element_rank ); 00216 00217 std::vector<Bucket*>::const_iterator k; 00218 00219 k = buckets.begin(); 00220 00221 //test 1 covers aecond section of "if" statement in while loop 00222 get_involved_parts( union_parts, **k, involved_parts); 00223 00224 //test 2 covers union_parts.size() = 0 00225 PartVector union_parts2(0) ; 00226 get_involved_parts( union_parts2, **k, involved_parts); 00227 00228 //test 3 covers first section of "if" statement in while loop 00229 const std::vector<Bucket*> & buckets2 = bulk.buckets( NODE_RANK ); 00230 std::vector<Bucket*>::const_iterator k2; 00231 00232 k2 = buckets2.begin(); 00233 get_involved_parts( union_parts, **k2, involved_parts); 00234 00235 // tests on throw_error and BucketIterator in bucket.cpp/hpp 00236 00237 FEMMetaData meta2 (spatial_dimension); 00238 BulkData bulk2( FEMMetaData::get_meta_data(meta2) , pm , 4 ); 00239 00240 unsigned number_of_states = 4; 00241 00242 ScalarFieldType & temperature2 = 00243 meta2.declare_field < ScalarFieldType >("temperature2" , number_of_states); 00244 ScalarFieldType & volume2 = 00245 00246 meta2.declare_field < ScalarFieldType >("volume2", number_of_states); 00247 Part & universal = meta2.universal_part (); 00248 put_field ( temperature2 , NODE_RANK , universal ); 00249 put_field ( volume2 , element_rank , universal ); 00250 00251 meta2.commit(); 00252 00253 bulk2.modification_begin(); 00254 bulk2.declare_entity( edge_rank, rank+1 , no_part ); 00255 bulk2.modification_end(); 00256 } 00257 00258 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testBucket2) 00259 { 00260 // Tests to cover print, has_superset and BucketLess::operator() for Buckets.cpp - C.Brickley - 2nd June 2010 00261 00262 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00263 MPI_Barrier( pm ); 00264 00265 const int spatial_dimension = 3; 00266 FEMMetaData meta( spatial_dimension ); 00267 const EntityRank element_rank = meta.element_rank(); 00268 00269 PartVector involved_parts(2) ; 00270 involved_parts[0] = & meta.universal_part(); 00271 involved_parts[1] = & meta.locally_owned_part(); 00272 00273 Part & partLeft_1 = meta.declare_part("block_left_1", element_rank); 00274 00275 Part & partLeft_3 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_3" ); 00276 00277 meta.commit(); 00278 00279 BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 ); 00280 std::vector<Part *> add_part4; 00281 add_part4.push_back ( &partLeft_1 ); 00282 00283 bulk.modification_begin(); 00284 int size , rank; 00285 rank = stk_classic::parallel_machine_rank( pm ); 00286 size = stk_classic::parallel_machine_size( pm ); 00287 00288 for ( int id_base = 0 ; id_base < 99 ; ++id_base ) 00289 { 00290 int new_id = size * id_base + rank; 00291 bulk.declare_entity( 3 , new_id+1 , add_part4 ); 00292 } 00293 00294 bulk.modification_end(); 00295 00296 const std::vector<Bucket*> & buckets2 = bulk.buckets( element_rank ); 00297 00298 std::vector<Bucket*>::const_iterator k2; 00299 00300 k2 = buckets2.begin(); 00301 00302 Bucket& b2 = **k2; 00303 00304 //define a new meta and bulkdata 00305 std::vector<std::string> entity_names(10); 00306 00307 for ( size_t i = 0 ; i < 10 ; ++i ) { 00308 std::ostringstream name ; 00309 name << "EntityRank" << i ; 00310 entity_names[i] = name.str(); 00311 } 00312 00313 MetaData meta2 ( entity_names ); 00314 BulkData bulk2( meta2 , pm , 4 ); 00315 00316 unsigned number_of_states = 4; 00317 00318 ScalarFieldType & temperature2 = 00319 meta2.declare_field < ScalarFieldType >("temperature2" , number_of_states); 00320 ScalarFieldType & volume2 = 00321 meta2.declare_field < ScalarFieldType >("volume2", number_of_states); 00322 Part & universal = meta2.universal_part (); 00323 put_field ( temperature2 , NODE_RANK , universal ); 00324 put_field ( volume2 , element_rank , universal ); 00325 00326 typedef Field<double> VectorFieldType; 00327 typedef Field<double> ElementNodePointerFieldType; 00328 00329 meta2.commit(); 00330 00331 //Test to cover print function in Bucket.cpp 00332 std::ostringstream oss; 00333 print(oss, " ", b2); 00334 00335 //Test to cover has_superset function in Bucket.cpp 00336 STKUNIT_ASSERT_EQUAL ( has_superset ( b2 , partLeft_3 ) , false ); 00337 00338 //Test on BucketLess::operator() in Bucket.cpp/hpp 00339 00340 enum { KEY_TMP_BUFFER_SIZE = 64 }; 00341 00342 const unsigned max = ~(0u); 00343 00344 unsigned key_tmp_buffer[ KEY_TMP_BUFFER_SIZE ]; 00345 00346 std::vector<unsigned> key_tmp_vector ; 00347 00348 const unsigned key_size = 2 + 3 ; 00349 00350 unsigned * const key = 00351 ( key_size <= KEY_TMP_BUFFER_SIZE ) 00352 ? key_tmp_buffer 00353 : ( key_tmp_vector.resize( key_size ) , & key_tmp_vector[0] ); 00354 00355 00356 key[ key[0] = 3 + 1 ] = max; 00357 00358 { 00359 unsigned * const k = key + 1 ; 00360 for ( unsigned i = 0 ; i < 3 ; ++i ) { k[i] = 1 ; } 00361 } 00362 00363 // FIXME: The code below needs to be fixed or removed 00364 /* 00365 impl::BucketImpl::last_bucket_in_family( *k2 ); 00366 00367 const unsigned * t = key; 00368 const Bucket * u = last_bucket; 00369 00370 BucketLess Buck; 00371 00372 bool res = Buck( &t[0], &u[0] ); 00373 00374 STKUNIT_EXPECT_EQUAL( res, false ); 00375 */ 00376 } 00377 00378 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testEntityComm) 00379 { 00380 // FIXME: With so much code commented out, this unit-test does 00381 // not appear to be testing anything. 00382 00383 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00384 MPI_Barrier( pm ); 00385 00386 const int spatial_dimension = 3; 00387 FEMMetaData meta( spatial_dimension ); 00388 00389 BulkData bulk ( FEMMetaData::get_meta_data(meta) , pm , 100 ); 00390 std::vector<Part *> add_part4; 00391 00392 Part & partLeft_1 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_1" ); 00393 meta.commit(); 00394 00395 add_part4.push_back ( &partLeft_1 ); 00396 00397 //int rank = stk_classic::parallel_machine_rank( pm ); 00398 // int size = stk_classic::parallel_machine_size( pm ); 00399 PartVector tmp(1); 00400 00401 bulk.modification_begin(); 00402 00403 //int id_base = 0; 00404 //int new_id = size * id_base + rank; 00405 // for ( id_base = 0 ; id_base < 93 ; ++id_base ) 00406 // { 00407 // int new_id = size * id_base + rank; 00408 // bulk.declare_entity( 0 , new_id+1 , add_part4 ); 00409 // } 00410 00411 bulk.modification_end(); 00412 00413 /* cout << endl << "Bucket test line 3" << endl ; 00414 bool result = in_shared(elem); 00415 if( result) { 00416 STKUNIT_ASSERT_EQUAL( result , true ); 00417 } 00418 cout << endl << "Bucket test line 4" << endl ; 00419 00420 result = in_receive_ghost(elem); 00421 if( result) { 00422 STKUNIT_ASSERT_EQUAL( result , true ); 00423 } 00424 00425 for ( unsigned p = 0 ; p < p_size ; ++p ) if ( p != p_rank ) { 00426 cout << endl << "in relation h and p =" << p << endl ; 00427 00428 STKUNIT_ASSERT_EQUAL( in_send_ghost( *elem , p ), false ); 00429 cout << endl << "in relation ii =" << endl 00430 } 00431 00432 cout << endl << "Bucket test line 5" << endl ; 00433 result = in_send_ghost(elem); 00434 if( result) { 00435 STKUNIT_ASSERT_EQUAL( result , true ); 00436 } 00437 00438 cout << endl << "Bucket test line 6" << endl ; 00439 00440 unsigned proc = rank; 00441 unsigned procnew = rank+10; 00442 00443 result = in_shared(elem, proc); 00444 if( result) { 00445 STKUNIT_ASSERT_EQUAL( result , true ); 00446 } 00447 cout << endl << "Bucket test line 7" << endl ; */ 00448 } 00449 00450 }