Sierra Toolkit Version of the Day
UnitTestField.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 <stdexcept>
00011 #include <sstream>
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/FieldData.hpp>
00020 #include <stk_mesh/base/GetBuckets.hpp>
00021 #include <stk_mesh/base/GetEntities.hpp>
00022 
00023 #include <stk_mesh/fem/FEMMetaData.hpp>
00024 #include <stk_mesh/fem/CoordinateSystems.hpp>
00025 
00026 #include <boost/range.hpp>
00027 #include <boost/foreach.hpp>
00028 
00029 namespace {
00030 
00031 const stk::mesh::EntityRank NODE_RANK = stk::mesh::fem::FEMMetaData::NODE_RANK;
00032 
00033 typedef shards::ArrayDimTag::size_type size_type;
00034 
00035 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ATAG )
00036 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( BTAG )
00037 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( CTAG )
00038 
00039 template< class FieldType >
00040 void print_bucket_array( const FieldType & f , const stk::mesh::Bucket & k )
00041 {
00042   typedef stk::mesh::BucketArray< FieldType > ArrayType ;
00043   std::ostringstream oss;
00044 
00045   ArrayType a( f , k.begin(), k.end() );
00046   ArrayType b( f , k );
00047 
00048   oss << "  BucketArray[" << f.name() << "](" ;
00049 
00050   if ( a.size() != b.size() ) {
00051     throw std::runtime_error("UnitTestField FAILED BucketArray dimensions not consistant with Bucket::iterator");
00052   }
00053 
00054   if ( a.size() ) {
00055     for ( unsigned i = 0 ; i < ArrayType::Rank ; ++i ) {
00056       if ( i ) { oss << "," ; }
00057       oss << a.dimension(i);
00058       if (a.dimension(i) != b.dimension(i)) {
00059         throw std::runtime_error("UnitTestField FAILED BucketArray dimensions not consistant with Bucket::iterator");
00060       }
00061     }
00062   }
00063   oss << ")" << std::endl ;
00064 }
00065 
00066 STKUNIT_UNIT_TEST(UnitTestField, testCartesian)
00067 {
00068   // Test the Cartesian array dimension tag
00069 
00070   const stk::mesh::Cartesian& cartesian_tag = stk::mesh::Cartesian::tag();
00071 
00072   std::string to_str = cartesian_tag.to_string(3 /*size*/, 1 /*idx*/);
00073   std::string expected_str("y");
00074   STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true);
00075 
00076   //should throw if we supply a size < 3:
00077   STKUNIT_ASSERT_THROW( cartesian_tag.to_string(2 /*size*/, 1 /*idx*/),
00078                         std::runtime_error );
00079 
00080   size_type expected_idx = 1;
00081   size_type idx = cartesian_tag.to_index(3 /*size*/, "y" /*dim*/);
00082   STKUNIT_ASSERT_EQUAL( idx, expected_idx );
00083 
00084   //should throw if we supply a "z" along with size==2:
00085   STKUNIT_ASSERT_THROW( cartesian_tag.to_index(2 /*size*/, "z" /*dim*/),
00086                         std::runtime_error );
00087 }
00088 
00089 STKUNIT_UNIT_TEST(UnitTestField, testCylindrical)
00090 {
00091   // Test the Cylindrical array dimension tag
00092 
00093   const stk::mesh::Cylindrical& cylindrical_tag =stk::mesh::Cylindrical::tag();
00094 
00095   std::string to_str = cylindrical_tag.to_string(3 /*size*/, 1 /*idx*/);
00096   std::string expected_str("a");
00097   STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true );
00098 
00099   //should throw if we supply a size < 3:
00100   STKUNIT_ASSERT_THROW( cylindrical_tag.to_string(2 /*size*/, 1 /*idx*/),
00101                         std::runtime_error );
00102 
00103   size_type expected_idx = 1;
00104   size_type idx = cylindrical_tag.to_index(3 /*size*/, "a" /*dim*/);
00105   STKUNIT_ASSERT_EQUAL( idx, expected_idx );
00106 
00107   //should throw if we supply a "z" along with size==2:
00108   STKUNIT_ASSERT_THROW( cylindrical_tag.to_index(2 /*size*/, "z" /*dim*/),
00109                         std::runtime_error );
00110 }
00111 
00112 STKUNIT_UNIT_TEST(UnitTestField, testFullTensor)
00113 {
00114   // Test the FullTensor array dimension tag
00115 
00116   const stk::mesh::FullTensor&  fulltensor_tag = stk::mesh::FullTensor::tag();
00117 
00118   std::string to_str = fulltensor_tag.to_string(9 /*size*/, 1 /*idx*/);
00119   std::string expected_str("yy");
00120   STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true );
00121 
00122   //should throw if we supply a size < 9:
00123   STKUNIT_ASSERT_THROW( fulltensor_tag.to_string(2 /*size*/, 1 /*idx*/),
00124                         std::runtime_error );
00125 
00126   size_type expected_idx = 6;
00127   size_type idx = fulltensor_tag.to_index(9 /*size*/, "yx" /*dim*/);
00128   STKUNIT_ASSERT_EQUAL( idx, expected_idx );
00129 
00130   //should throw if we supply a "zz" along with size==2:
00131   STKUNIT_ASSERT_THROW( fulltensor_tag.to_index(2 /*size*/, "zz" /*dim*/),
00132                         std::runtime_error );
00133 }
00134 
00135 STKUNIT_UNIT_TEST(UnitTestField, testSymmetricTensor)
00136 {
00137   // Test the SymmetricTensor array dimension tag
00138 
00139   const stk::mesh::SymmetricTensor& symmetrictensor_tag =
00140     stk::mesh::SymmetricTensor::tag();
00141 
00142   std::string to_str = symmetrictensor_tag.to_string(9 /*size*/, 1 /*idx*/);
00143   std::string expected_str("yy");
00144   STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true);
00145 
00146   //should throw if we supply a size < 9:
00147   STKUNIT_ASSERT_THROW( symmetrictensor_tag.to_string(2 /*size*/, 1 /*idx*/),
00148                         std::runtime_error );
00149 
00150   size_type expected_idx = 1;
00151   size_type idx = symmetrictensor_tag.to_index(6 /*size*/, "yy" /*dim*/);
00152   STKUNIT_ASSERT_EQUAL( idx, expected_idx );
00153 
00154   //should throw if we supply a "xz" along with size==5:
00155   STKUNIT_ASSERT_THROW( symmetrictensor_tag.to_index(5 /*size*/, "xz" /*dim*/),
00156                         std::runtime_error );
00157 }
00158 
00159 STKUNIT_UNIT_TEST(UnitTestField, testFieldDataArray)
00160 {
00161   stk::ParallelMachine pm = MPI_COMM_SELF ;
00162   std::ostringstream oss; // to test printing of things w/out spamming cout
00163 
00164   // specifications for some test fields
00165   typedef stk::mesh::Field<double>                rank_zero_field ;
00166   typedef stk::mesh::Field<double,ATAG>           rank_one_field ;
00167   typedef stk::mesh::Field<double,ATAG,BTAG>      rank_two_field ;
00168   typedef stk::mesh::Field<double,ATAG,BTAG,CTAG> rank_three_field ;
00169 
00170   const std::string name0("test_field_0");
00171   const std::string name1("test_field_1");
00172   const std::string name2("test_field_2");
00173   const std::string name3("test_field_3");
00174 
00175   const int spatial_dimension = 3;
00176   stk::mesh::fem::FEMMetaData meta_data( spatial_dimension );
00177   stk::mesh::BulkData bulk_data( stk::mesh::fem::FEMMetaData::get_meta_data(meta_data) , pm );
00178 
00179   rank_zero_field  & f0 = meta_data.declare_field< rank_zero_field >( name0 );
00180   rank_one_field   & f1 = meta_data.declare_field< rank_one_field >(  name1 );
00181   rank_three_field & f3 = meta_data.declare_field< rank_three_field >( name3 );
00182   rank_two_field   & f2 = meta_data.declare_field< rank_two_field >(  name2 );
00183 
00184   // confirm that declaring field with erroneous type throws exception
00185   typedef stk::mesh::Field<double,CTAG> error_type ;
00186   STKUNIT_ASSERT_THROW(meta_data.declare_field< error_type >( name1 ),
00187                        std::runtime_error);
00188 
00189   stk::mesh::Part & p0 = meta_data.declare_part("P0", NODE_RANK );
00190   stk::mesh::Part & p1 = meta_data.declare_part("P1", NODE_RANK );
00191   stk::mesh::Part & p2 = meta_data.declare_part("P2", NODE_RANK );
00192   stk::mesh::Part & p3 = meta_data.declare_part("P3", NODE_RANK );
00193 
00194   stk::mesh::put_field( f0 , NODE_RANK , p0 );
00195   stk::mesh::put_field( f1 , NODE_RANK , p1 , 10 );
00196   stk::mesh::put_field( f2 , NODE_RANK , p2 , 10 , 20 );
00197   stk::mesh::put_field( f3 , NODE_RANK , p3 , 10 , 20 , 30 );
00198 
00199   stk::mesh::print( oss , "  " , f0 );
00200 
00201   meta_data.commit();
00202 
00203   bulk_data.modification_begin();
00204 
00205   // Declare a 10 nodes on each part
00206 
00207   for ( unsigned i = 1 ; i < 11 ; ++i ) {
00208     bulk_data.declare_entity( NODE_RANK , i ,
00209                               std::vector< stk::mesh::Part * >( 1 , & p0 ) );
00210   }
00211 
00212   for ( unsigned i = 11 ; i < 21 ; ++i ) {
00213     bulk_data.declare_entity( NODE_RANK , i ,
00214                               std::vector< stk::mesh::Part * >( 1 , & p1 ) );
00215   }
00216 
00217   for ( unsigned i = 21 ; i < 31 ; ++i ) {
00218     bulk_data.declare_entity( NODE_RANK , i ,
00219                               std::vector< stk::mesh::Part * >( 1 , & p2 ) );
00220   }
00221 
00222   for ( unsigned i = 31 ; i < 41 ; ++i ) {
00223     bulk_data.declare_entity( NODE_RANK , i ,
00224                               std::vector< stk::mesh::Part * >( 1 , & p3 ) );
00225   }
00226 
00227   // Go through node_buckets and print the all the fields on each bucket
00228   const std::vector< stk::mesh::Bucket *> & node_buckets =
00229     bulk_data.buckets( NODE_RANK );
00230 
00231   for ( std::vector< stk::mesh::Bucket *>::const_iterator
00232         ik = node_buckets.begin() ; ik != node_buckets.end() ; ++ik ) {
00233     stk::mesh::Bucket & k = **ik ;
00234 
00235     std::vector< stk::mesh::Part * > parts ;
00236     k.supersets( parts );
00237 
00238     for ( std::vector< stk::mesh::Part * >::iterator
00239           ip = parts.begin() ; ip != parts.end() ; ++ip ) {
00240       oss << " " << (*ip)->name();
00241     }
00242 
00243     print_bucket_array( f0 , k );
00244     print_bucket_array( f1 , k );
00245     print_bucket_array( f2 , k );
00246     print_bucket_array( f3 , k );
00247   }
00248 }
00249 
00250 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelector)
00251 {
00252   stk::ParallelMachine pm = MPI_COMM_SELF ;
00253   std::ostringstream oss; // to test printing of things w/out spamming cout
00254 
00255   // specifications for test field
00256   typedef stk::mesh::Field<double>    rank_zero_field ;
00257 
00258   const std::string name0("test_field_0");
00259 
00260   const int spatial_dimension = 3;
00261   stk::mesh::fem::FEMMetaData meta_data( spatial_dimension );
00262   stk::mesh::BulkData bulk_data( stk::mesh::fem::FEMMetaData::get_meta_data(meta_data) , pm );
00263 
00264   rank_zero_field  & f0 = meta_data.declare_field< rank_zero_field >( name0 );
00265 
00266   stk::mesh::Part & p0 = meta_data.declare_part("P0", NODE_RANK );
00267   stk::mesh::Part & p1 = meta_data.declare_part("P1", NODE_RANK );
00268 
00269   stk::mesh::Selector select_p0 = p0;
00270   std::cout <<"select_p0: "<< select_p0 << std::endl;
00271 
00272   stk::mesh::put_field( f0 , NODE_RANK , select_p0 );
00273 
00274   stk::mesh::print( oss , "  " , f0 );
00275 
00276   meta_data.commit();
00277 
00278   bulk_data.modification_begin();
00279 
00280   // Declare 10 nodes on each part
00281 
00282   for ( unsigned i = 1 ; i < 11 ; ++i ) {
00283     bulk_data.declare_entity( NODE_RANK , i ,
00284                               std::vector< stk::mesh::Part * >( 1 , & p0 ) );
00285   }
00286 
00287   for ( unsigned i = 11 ; i < 21 ; ++i ) {
00288     bulk_data.declare_entity( NODE_RANK , i ,
00289                               std::vector< stk::mesh::Part * >( 1 , & p1 ) );
00290   }
00291 
00292   const std::vector< stk::mesh::Bucket *> & node_buckets =
00293     bulk_data.buckets( NODE_RANK );
00294 
00295   unsigned num = stk::mesh::count_selected_entities(select_p0, node_buckets);
00296   
00297   STKUNIT_ASSERT_EQUAL( 10u, num );
00298 
00299   stk::mesh::Selector select_f0 = stk::mesh::selectField(f0);
00300 
00301   std::cout <<"select_f0: "<< select_f0 << std::endl;
00302 
00303   unsigned num_f0 = stk::mesh::count_selected_entities(select_f0, node_buckets);
00304   STKUNIT_ASSERT_EQUAL(10u, num_f0);
00305 
00306   std::vector<stk::mesh::Bucket*> f0_buckets;
00307   stk::mesh::get_buckets(select_p0, bulk_data.buckets(NODE_RANK), f0_buckets);
00308   unsigned num_buckets = f0_buckets.size();
00309   STKUNIT_ASSERT_EQUAL(1u, num_buckets);
00310 
00311   BOOST_FOREACH(stk::mesh::Bucket* b, f0_buckets) {
00312     unsigned f0_size = b->field_data_size(f0);
00313     STKUNIT_ASSERT_EQUAL(8u, f0_size);
00314   }
00315 }
00316 
00317 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelectorAnd)
00318 {
00319   stk::ParallelMachine pm = MPI_COMM_SELF ;
00320   std::ostringstream oss; // to test printing of things w/out spamming cout
00321 
00322   typedef stk::mesh::Field<double,shards::ArrayDimension>           rank_one_field ;
00323   // specifications for test field
00324 
00325   const std::string name0("test_field_0");
00326 
00327   const int spatial_dimension = 3;
00328   stk::mesh::fem::FEMMetaData meta_data( spatial_dimension );
00329   stk::mesh::BulkData bulk_data( stk::mesh::fem::FEMMetaData::get_meta_data(meta_data) , pm );
00330 
00331   rank_one_field  & f0 = meta_data.declare_field< rank_one_field >( name0 );
00332 
00333   stk::mesh::EntityRank elem_rank = meta_data.element_rank();
00334   stk::mesh::Part & elements = meta_data.declare_part("Elements", elem_rank);
00335   stk::mesh::Part & hex8s = meta_data.declare_part("Hex8", elem_rank );
00336   stk::mesh::Part & tet4s = meta_data.declare_part("Tet4", elem_rank );
00337 
00338   stk::mesh::Selector elem_hex_selector = elements & hex8s;
00339   stk::mesh::Selector elem_tet_selector = elements & tet4s;
00340   std::cout <<"elem_hex_selector: "<< elem_hex_selector << std::endl;
00341   std::cout <<"elem_tet_selector: "<< elem_tet_selector << std::endl;
00342 
00343   stk::mesh::put_field( f0 , elem_rank , elem_hex_selector, 8u );
00344   stk::mesh::put_field( f0 , elem_rank , elem_tet_selector, 4u );
00345 
00346   stk::mesh::print( oss , "  " , f0 );
00347 
00348   meta_data.commit();
00349 
00350   bulk_data.modification_begin();
00351 
00352   // Declare 10 elements on each part
00353 
00354   stk::mesh::PartVector parts;
00355   parts.push_back(&elements);
00356   parts.push_back(&hex8s);
00357 
00358   for ( unsigned i = 1 ; i < 11 ; ++i ) {
00359     bulk_data.declare_entity( elem_rank , i , parts );
00360   }
00361 
00362   parts.clear();
00363   parts.push_back(&elements);
00364   parts.push_back(&tet4s);
00365 
00366   for ( unsigned i = 11 ; i < 21 ; ++i ) {
00367     bulk_data.declare_entity( elem_rank , i , parts );
00368   }
00369 
00370   stk::mesh::BucketVector f0_buckets;
00371   stk::mesh::get_buckets(elem_hex_selector, bulk_data.buckets(elem_rank), f0_buckets);
00372 
00373   BOOST_FOREACH(stk::mesh::Bucket* b, f0_buckets) {
00374     unsigned f0_size = b->field_data_size(f0);
00375     STKUNIT_ASSERT_EQUAL(64u, f0_size);
00376   }
00377 
00378   f0_buckets.clear();
00379 
00380   stk::mesh::get_buckets(elem_tet_selector, bulk_data.buckets(elem_rank), f0_buckets);
00381 
00382   BOOST_FOREACH(stk::mesh::Bucket* b, f0_buckets) {
00383     unsigned f0_size = b->field_data_size(f0);
00384     STKUNIT_ASSERT_EQUAL(32u, f0_size);
00385   }
00386 }
00387 
00388 
00389 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelectorInvalid)
00390 {
00391   stk::ParallelMachine pm = MPI_COMM_SELF ;
00392   std::ostringstream oss; // to test printing of things w/out spamming cout
00393 
00394   typedef stk::mesh::Field<double,shards::ArrayDimension>           rank_one_field ;
00395   // specifications for test field
00396 
00397   const std::string name0("test_field_0");
00398 
00399   const int spatial_dimension = 3;
00400   stk::mesh::fem::FEMMetaData meta_data( spatial_dimension );
00401   stk::mesh::BulkData bulk_data( stk::mesh::fem::FEMMetaData::get_meta_data(meta_data) , pm );
00402 
00403   rank_one_field  & f0 = meta_data.declare_field< rank_one_field >( name0 );
00404 
00405   stk::mesh::EntityRank elem_rank = meta_data.element_rank();
00406   stk::mesh::Part & hex8s = meta_data.declare_part("Hex8", elem_rank );
00407 
00408   stk::mesh::Part & universal_part = meta_data.universal_part();
00409   stk::mesh::Selector elem_hexA_selector = hex8s;
00410   stk::mesh::Selector elem_hexB_selector = universal_part & hex8s;
00411 
00412   std::cout <<"elem_hexA_selector: "<< elem_hexA_selector << std::endl;
00413   std::cout <<"elem_hexB_selector: "<< elem_hexB_selector << std::endl;
00414 
00415   stk::mesh::put_field( f0 , elem_rank , elem_hexA_selector, 8u );
00416   STKUNIT_ASSERT_THROW( 
00417     stk::mesh::put_field( f0 , elem_rank , elem_hexA_selector, 4u ),
00418     std::runtime_error
00419   );
00420   stk::mesh::put_field( f0 , elem_rank , elem_hexB_selector, 4u );
00421 
00422   stk::mesh::print( oss , "  " , f0 );
00423 
00424   meta_data.commit();
00425 
00426   bulk_data.modification_begin();
00427 
00428   stk::mesh::PartVector parts;
00429   parts.push_back(&hex8s);
00430   STKUNIT_ASSERT_THROW( 
00431     bulk_data.declare_entity( elem_rank , 1 , parts ),
00432     std::runtime_error
00433   );
00434 
00435 }
00436 
00437 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ATAG )
00438 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( BTAG )
00439 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( CTAG )
00440 
00441 } //namespace <anonymous>
00442 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines