Sierra Toolkit Version of the Day
UnitTestPart.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 #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::mesh::MetaData;
00026 using stk::mesh::Part;
00027 using stk::mesh::PartVector;
00028 using stk::mesh::PartRelation;
00029 using stk::mesh::impl::PartRepository;
00030 
00031 namespace {
00032 
00033 STKUNIT_UNIT_TEST(UnitTestPart, testUnit)
00034 {
00035   const int spatial_dimension = 3;
00036   MetaData m(stk::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::mesh::MetaData meta2( dummy_names );
00181 
00182       stk::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::mesh::fem::entity_rank_names(spatial_dimension));
00279   PartVector intersection;
00280   PartRepository partRepo(&m);
00281 
00282   stk::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::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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends