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/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::mesh::fem::FEMMetaData;
00043 using stk::mesh::MetaData;
00044 using stk::mesh::BulkData;
00045 using stk::mesh::Part;
00046 using stk::mesh::PartVector;
00047 using stk::mesh::EntityRank;
00048 using stk::mesh::EntityId;
00049 using stk::mesh::PairIterEntityComm;
00050 using stk::mesh::Entity;
00051 using stk::mesh::Bucket;
00052 using stk::mesh::BucketIterator;
00053 using stk::mesh::Selector;
00054 using stk::mesh::Field;
00055 using stk::mesh::FieldBase;
00056 using stk::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::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::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::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::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_1" );
00188 
00189   Part & partLeft_2 = stk::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::parallel_machine_rank( pm );
00204   size = stk::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::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::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::parallel_machine_rank( pm );
00286   size = stk::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::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::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::parallel_machine_rank( pm );
00398   // int size = stk::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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines