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