|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010, 2011 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/FieldRelation.hpp> 00019 #include <stk_mesh/base/PartRelation.hpp> 00020 #include <stk_mesh/base/FieldData.hpp> 00021 00022 #include <stk_mesh/baseImpl/PartRepository.hpp> 00023 #include <stk_mesh/baseImpl/EntityRepository.hpp> 00024 #include <stk_mesh/baseImpl/FieldBaseImpl.hpp> 00025 #include <stk_mesh/fem/CoordinateSystems.hpp> 00026 00027 #include <Shards_BasicTopologies.hpp> 00028 00029 namespace stk_classic { 00030 namespace mesh { 00031 00032 class UnitTestFieldImpl { 00033 public: 00034 UnitTestFieldImpl() {} 00035 00036 void testField(); 00037 void testFieldRestriction(); 00038 void testFieldRelation(); 00039 00040 }; 00041 00042 }//namespace mesh 00043 }//namespace stk_classic 00044 00045 namespace { 00046 00047 STKUNIT_UNIT_TEST(UnitTestField, testUnit) 00048 { 00049 stk_classic::mesh::UnitTestFieldImpl ufield; 00050 ufield.testField(); 00051 } 00052 00053 STKUNIT_UNIT_TEST(UnitTestFieldRestriction, testUnit) 00054 { 00055 stk_classic::mesh::UnitTestFieldImpl ufield; 00056 ufield.testFieldRestriction(); 00057 } 00058 00059 STKUNIT_UNIT_TEST(UnitTestFieldRelation, testUnit) 00060 { 00061 stk_classic::mesh::UnitTestFieldImpl ufield; 00062 ufield.testFieldRelation(); 00063 } 00064 00065 }//namespace <anonymous> 00066 00067 //---------------------------------------------------------------------- 00068 00069 namespace stk_classic { 00070 namespace mesh { 00071 00072 namespace { 00073 00074 // Simple tags for testing field dimensions 00075 00076 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ATAG ) 00077 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( BTAG ) 00078 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( CTAG ) 00079 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( DTAG ) 00080 00081 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ATAG ) 00082 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( BTAG ) 00083 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( CTAG ) 00084 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( DTAG ) 00085 00086 } 00087 00088 void UnitTestFieldImpl::testField() 00089 { 00090 MetaData meta_data; 00091 00092 // Declaration of a field allocates one field object 00093 // per state of the field. These fields are inserted 00094 // into a vector of fields of the base class. 00095 00096 impl::FieldRepository field_repo; 00097 const FieldVector & allocated_fields = field_repo.get_fields(); 00098 00099 //------------------------------ 00100 // Declare a double precision scalar field of one state. 00101 // Not an array; therefore, is rank zero. 00102 // Test the query methods for accuracy. 00103 FieldBase * const fA = 00104 field_repo.declare_field( std::string("A"), 00105 data_traits<double>() , 00106 0 /* # Ranks */ , 00107 NULL /* dimension tags */ , 00108 1 /* # States */ , 00109 &meta_data ); 00110 00111 STKUNIT_ASSERT( allocated_fields.size() == 1 ); 00112 STKUNIT_ASSERT( fA != NULL ); 00113 STKUNIT_ASSERT( fA == allocated_fields[0] ); 00114 STKUNIT_ASSERT( fA->name() == std::string("A") ); 00115 STKUNIT_ASSERT( fA->type_is<double>() ); 00116 STKUNIT_ASSERT( fA->state() == StateNone ); 00117 STKUNIT_ASSERT( fA->rank() == 0 ); 00118 00119 //------------------------------ 00120 // Declare a field with an invalid suffix in its name. 00121 // Suffixes corresponding to "OLD" "N" "NM1" "NM2" "NM3" "NM4" 00122 // are not allowed as these are automatically appended to 00123 // the declared variable name for multistate fields. 00124 { 00125 STKUNIT_ASSERT_THROW( 00126 field_repo.declare_field( "A_STKFS_OLD" , 00127 data_traits<double>() , 00128 0 /* # Ranks */ , 00129 NULL /* dimension tags */ , 00130 1 /* # States */ , 00131 &meta_data ), 00132 std::runtime_error); 00133 STKUNIT_ASSERT( allocated_fields.size() == 1 ); 00134 } 00135 00136 //------------------------------ 00137 // Declare a double precision scalar field of two states. 00138 // Not an array; therefore, is rank zero. 00139 // Test that two fields: "B" and "B_OLD" were created. 00140 // Test the query methods for accuracy. 00141 00142 FieldBase * const fB = 00143 field_repo.declare_field( std::string("B"), 00144 data_traits<int>(), 00145 0 /* # Ranks */ , 00146 NULL /* dimension tags */ , 00147 2 /* # States */ , 00148 &meta_data ); 00149 00150 STKUNIT_ASSERT( allocated_fields.size() == 3 ); 00151 STKUNIT_ASSERT( fB != NULL ); 00152 STKUNIT_ASSERT( fB == allocated_fields[1] ); 00153 STKUNIT_ASSERT( fB->name() == std::string("B") ); 00154 STKUNIT_ASSERT( fB->type_is<int>() ); 00155 STKUNIT_ASSERT( fB->state() == StateNew ); 00156 STKUNIT_ASSERT( fB->rank() == 0 ); 00157 00158 const FieldBase * const fB_old = allocated_fields[2] ; 00159 STKUNIT_ASSERT( fB_old->name() == std::string("B_STKFS_OLD") ); 00160 STKUNIT_ASSERT( fB_old->type_is<int>() ); 00161 STKUNIT_ASSERT( fB_old->state() == StateOld ); 00162 STKUNIT_ASSERT( fB_old->rank() == 0 ); 00163 00164 //------------------------------ 00165 // Redeclare field must give back the previous field: 00166 00167 FieldBase * const fB_redundant = 00168 field_repo.declare_field( std::string("B"), 00169 data_traits<int>(), 00170 0 /* # Ranks */ , 00171 NULL /* dimension tags */ , 00172 2 /* # States */ , 00173 &meta_data ); 00174 00175 STKUNIT_ASSERT( allocated_fields.size() == 3 ); 00176 STKUNIT_ASSERT( fB == fB_redundant ); 00177 00178 //------------------------------ 00179 // Declare a double precision array field of four states. 00180 // Test that four fields: were created. 00181 // Test the query methods for accuracy. 00182 00183 const shards::ArrayDimTag * dim_tags[] = 00184 { & ATAG::tag() , & BTAG::tag() , & CTAG::tag() , & DTAG::tag() }; 00185 00186 FieldBase * const fC = 00187 field_repo.declare_field( std::string("C"), 00188 data_traits<double>(), 00189 3 /* # Ranks */ , 00190 dim_tags /* dimension tags */ , 00191 4 /* # States */ , 00192 &meta_data ); 00193 00194 STKUNIT_ASSERT( allocated_fields.size() == 7 ); 00195 STKUNIT_ASSERT( fC != NULL ); 00196 STKUNIT_ASSERT( fC == allocated_fields[3] ); 00197 STKUNIT_ASSERT( fC->name() == std::string("C") ); 00198 STKUNIT_ASSERT( fC->type_is<double>() ); 00199 STKUNIT_ASSERT( fC->state() == StateNew ); 00200 STKUNIT_ASSERT( fC->rank() == 3 ); 00201 00202 const FieldBase * const fC_n = allocated_fields[4] ; 00203 const FieldBase * const fC_nm1 = allocated_fields[5] ; 00204 const FieldBase * const fC_nm2 = allocated_fields[6] ; 00205 00206 STKUNIT_ASSERT( fC == fC->field_state( StateNP1 ) ); 00207 STKUNIT_ASSERT( fC_n == fC->field_state( StateN ) ); 00208 STKUNIT_ASSERT( fC_nm1 == fC->field_state( StateNM1 ) ); 00209 STKUNIT_ASSERT( fC_nm2 == fC->field_state( StateNM2 ) ); 00210 00211 STKUNIT_ASSERT( fC == fC_n->field_state( StateNP1 ) ); 00212 STKUNIT_ASSERT( fC_n == fC_n->field_state( StateN ) ); 00213 STKUNIT_ASSERT( fC_nm1 == fC_n->field_state( StateNM1 ) ); 00214 STKUNIT_ASSERT( fC_nm2 == fC_n->field_state( StateNM2 ) ); 00215 00216 STKUNIT_ASSERT( fC == fC_nm1->field_state( StateNP1 ) ); 00217 STKUNIT_ASSERT( fC_n == fC_nm1->field_state( StateN ) ); 00218 STKUNIT_ASSERT( fC_nm1 == fC_nm1->field_state( StateNM1 ) ); 00219 STKUNIT_ASSERT( fC_nm2 == fC_nm1->field_state( StateNM2 ) ); 00220 00221 STKUNIT_ASSERT( fC == fC_nm2->field_state( StateNP1 ) ); 00222 STKUNIT_ASSERT( fC_n == fC_nm2->field_state( StateN ) ); 00223 STKUNIT_ASSERT( fC_nm1 == fC_nm2->field_state( StateNM1 ) ); 00224 STKUNIT_ASSERT( fC_nm2 == fC_nm2->field_state( StateNM2 ) ); 00225 00226 STKUNIT_ASSERT( fC_n->name() == std::string("C_STKFS_N") ); 00227 STKUNIT_ASSERT( fC_n->type_is<double>() ); 00228 STKUNIT_ASSERT( fC_n->state() == StateN ); 00229 STKUNIT_ASSERT( fC_n->rank() == 3 ); 00230 00231 STKUNIT_ASSERT( fC_nm1->name() == std::string("C_STKFS_NM1") ); 00232 STKUNIT_ASSERT( fC_nm1->type_is<double>() ); 00233 STKUNIT_ASSERT( fC_nm1->state() == StateNM1 ); 00234 STKUNIT_ASSERT( fC_nm1->rank() == 3 ); 00235 00236 STKUNIT_ASSERT( fC_nm2->name() == std::string("C_STKFS_NM2") ); 00237 STKUNIT_ASSERT( fC_nm2->type_is<double>() ); 00238 STKUNIT_ASSERT( fC_nm2->state() == StateNM2 ); 00239 STKUNIT_ASSERT( fC_nm2->rank() == 3 ); 00240 00241 //------------------------------ 00242 // Redeclare field must give back the previous field: 00243 //------------------------------ 00244 00245 for ( unsigned i = 0 ; i < allocated_fields.size() ; ++i ) { 00246 FieldBase * const f = allocated_fields[i] ; 00247 STKUNIT_ASSERT( f->mesh_meta_data_ordinal() == i ); 00248 } 00249 00250 //Coverage of EntityDimension::name in FieldData.cpp 00251 { 00252 const stk_classic::mesh::EntityDimension& entity_dimension_tag = stk_classic::mesh::EntityDimension::tag(); 00253 // static const char * name(); 00254 00255 entity_dimension_tag.name(); 00256 } 00257 } 00258 00259 00260 //---------------------------------------------------------------------- 00261 // Test field restrictions: the mapping of ( field , part ) -> dimensions 00262 00263 void UnitTestFieldImpl::testFieldRestriction() 00264 { 00265 unsigned stride[8] ; 00266 00267 stride[0] = 10 ; 00268 for ( unsigned i = 1 ; i < 8 ; ++i ) { 00269 stride[i] = ( i + 1 ) * stride[i-1] ; 00270 } 00271 00272 std::vector< std::string > dummy_names(1); 00273 dummy_names[0].assign("dummy"); 00274 00275 MetaData meta_data(dummy_names); 00276 00277 const FieldVector & allocated_fields = meta_data.get_fields(); 00278 00279 //------------------------------ 00280 00281 typedef stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> VectorField; 00282 00283 FieldBase * const f2 = 00284 &meta_data.declare_field<VectorField>( std::string("F2"), 1/* # states */ ); 00285 00286 //------------------------------ 00287 00288 FieldBase * const f3 = 00289 &meta_data.declare_field<VectorField>( std::string("F3"), 2/* #states*/); 00290 00291 FieldBase * const f3_old = f3->field_state( StateOld ) ; 00292 00293 //------------------------------ 00294 // Test for correctness of vector of declared fields. 00295 STKUNIT_ASSERT( allocated_fields.size() == 3 ); 00296 STKUNIT_ASSERT( f2 == allocated_fields[0] ); 00297 STKUNIT_ASSERT( f3 == allocated_fields[1] ); 00298 00299 //------------------------------ 00300 // Test for correctness of field internal state access: 00301 00302 STKUNIT_ASSERT( f2 == f2->field_state( StateNone ) ); 00303 STKUNIT_ASSERT( NULL == f2->field_state( StateOld ) ); 00304 STKUNIT_ASSERT( f3 == f3->field_state( StateNew ) ); 00305 STKUNIT_ASSERT( f3_old == f3->field_state( StateOld ) ); 00306 STKUNIT_ASSERT( NULL == f3->field_state( StateNM1 ) ); 00307 STKUNIT_ASSERT( f3 == f3_old->field_state( StateNew ) ); 00308 STKUNIT_ASSERT( f3_old == f3_old->field_state( StateOld ) ); 00309 STKUNIT_ASSERT( NULL == f3_old->field_state( StateNM1 ) ); 00310 00311 //------------------------------ 00312 // Declare some parts for restrictions: 00313 00314 Part & pA = meta_data.declare_part( std::string("A") , 0 ); 00315 Part & pB = meta_data.declare_part( std::string("B") , 0 ); 00316 Part & pC = meta_data.declare_part( std::string("C") , 0 ); 00317 Part & pD = meta_data.declare_part( std::string("D") , 0 ); 00318 00319 // Declare three restrictions: 00320 00321 meta_data.declare_field_restriction(*f3, 0 , pA , stride ); 00322 meta_data.declare_field_restriction(*f3, 1 , pB , stride + 1 ); 00323 meta_data.declare_field_restriction(*f3, 2 , pC , stride + 2 ); 00324 00325 // Check for correctness of restrictions: 00326 00327 STKUNIT_ASSERT( f3->restrictions().size() == 3 ); 00328 STKUNIT_ASSERT( f3->restrictions()[0] == 00329 FieldRestriction( 0 , pA.mesh_meta_data_ordinal() ) ); 00330 STKUNIT_ASSERT( f3->restrictions()[1] == 00331 FieldRestriction( 1 , pB.mesh_meta_data_ordinal() ) ); 00332 STKUNIT_ASSERT( f3->restrictions()[2] == 00333 FieldRestriction( 2 , pC.mesh_meta_data_ordinal() ) ); 00334 00335 meta_data.declare_field_restriction(*f3, 0 , pB , stride + 1 ); 00336 00337 STKUNIT_ASSERT_EQUAL( f3->max_size( 0 ) , 20u ); 00338 00339 //------------------------------ 00340 // Check for error detection of bad stride: 00341 { 00342 unsigned bad_stride[4] = { 5 , 4 , 6 , 3 }; 00343 STKUNIT_ASSERT_THROW( 00344 meta_data.declare_field_restriction(*f3, 0 , pA , bad_stride ), 00345 std::runtime_error 00346 ); 00347 STKUNIT_ASSERT( f3->restrictions().size() == 4 ); 00348 } 00349 00350 // Check for error detection in re-declaring an incompatible 00351 // field restriction. 00352 { 00353 STKUNIT_ASSERT_THROW( 00354 meta_data.declare_field_restriction(*f3, 0 , pA , stride + 1 ), 00355 std::runtime_error 00356 ); 00357 STKUNIT_ASSERT( f3->restrictions().size() == 4 ); 00358 } 00359 00360 // Verify and clean out any redundant restructions: 00361 00362 STKUNIT_ASSERT( f3->restrictions().size() == 4 ); 00363 00364 //------------------------------ 00365 // Introduce a redundant restriction, clean it, and 00366 // check that it was cleaned. 00367 00368 std::cout<<"pA ord: "<<pA.mesh_meta_data_ordinal()<<", pD ord: "<<pD.mesh_meta_data_ordinal()<<std::endl; 00369 meta_data.declare_part_subset( pD, pA ); 00370 meta_data.declare_field_restriction(*f2, 0 , pA , stride ); 00371 meta_data.declare_field_restriction(*f2, 0 , pD , stride ); 00372 00373 STKUNIT_ASSERT( f2->restrictions().size() == 1 ); 00374 00375 { 00376 const FieldBase::Restriction & rA = f2->restriction( 0 , pA ); 00377 const FieldBase::Restriction & rD = f2->restriction( 0 , pD ); 00378 STKUNIT_ASSERT( & rA == & rD ); 00379 STKUNIT_ASSERT( rA.part_ordinal() == pD.mesh_meta_data_ordinal() ); 00380 } 00381 00382 //------------------------------ 00383 // Introduce a new restriction, then introduce a 00384 // subset-superset relationship that renders the new restriction 00385 // redundant and incompatible. 00386 // Check that the verify_and_clean_restrictions method detects 00387 // this error condition. 00388 { 00389 meta_data.declare_field_restriction(*f2, 0 , pB , stride + 1 ); 00390 STKUNIT_ASSERT_THROW( 00391 meta_data.declare_part_subset( pD, pB ), 00392 std::runtime_error 00393 ); 00394 } 00395 00396 //Test to cover print function in FieldBaseImpl.cpp and FieldBase.cpp 00397 { 00398 //Create a new field with MetaData m and two restrictions 00399 00400 FieldBase * const f4 = 00401 &meta_data.declare_field<VectorField>( std::string("F4"), 00402 2 /* # states */ ); 00403 00404 meta_data.declare_part_subset( pD, pA ); 00405 meta_data.declare_part_subset( pC, pB ); 00406 00407 meta_data.declare_field_restriction(*f4, 0 , pA , stride ); 00408 meta_data.declare_field_restriction(*f4, 1 , pB , stride + 1 ); 00409 stk_classic::mesh::impl::print(std::cout, "Field f4", *f4); 00410 00411 //test stride[i] / stride[i-1] section of else-if 00412 stk_classic::mesh::print(std::cout, "Field f4", *f4); 00413 } 00414 00415 //Further tests to cover print function in FieldBase.cpp 00416 { 00417 //test stride[i] % stride[i-1] section of else-if 00418 00419 //Create a new field with MetaData m and two restrictions 00420 00421 FieldBase * const f5 = 00422 &meta_data.declare_field<VectorField>( std::string("F5"), 00423 2 /* # states */ ); 00424 00425 unsigned stride2[8] ; 00426 stride2[0] = 10 ; 00427 for ( unsigned i = 1 ; i < 3 ; ++i ) { 00428 stride2[i] = stride[i-1]; 00429 } 00430 for ( unsigned i = 3 ; i < 8 ; ++i ) { 00431 stride2[i] = 0; 00432 } 00433 meta_data.declare_field_restriction(*f5, 0 , pA, stride2 ); 00434 00435 stk_classic::mesh::print(std::cout, "Field f5", *f5); 00436 00437 } 00438 00439 //Coverage for error from print_restriction in FieldBaseImpl.cpp when there is no stride (!stride[i]) 00440 //Call print_restriction from insert_restriction 00441 { 00442 unsigned arg_no_stride[2]; 00443 00444 arg_no_stride[0] = 1; 00445 arg_no_stride[1] = 0; 00446 00447 STKUNIT_ASSERT_THROW( 00448 meta_data.declare_field_restriction(*f2, 0, pA, arg_no_stride), 00449 std::runtime_error 00450 ); 00451 } 00452 00453 //Coverage of ordinal in FieldRestriction.hpp: 00454 { 00455 const FieldRestrictionVector & rMap = f3->restrictions(); 00456 const FieldRestrictionVector::const_iterator ie = rMap.end() ; 00457 FieldRestrictionVector::const_iterator i = rMap.begin(); 00458 00459 EntityId entity_id = 0; 00460 unsigned max = 0 ; 00461 00462 for ( ; i != ie ; ++i ) { 00463 if ( i->part_ordinal() == entity_id ) { 00464 const unsigned len = pA.mesh_meta_data_ordinal() ? i->stride( pA.mesh_meta_data_ordinal() - 1 ) : 1 ; 00465 if ( max < len ) { max = len ; } 00466 } 00467 } 00468 } 00469 } 00470 00471 // Unit test the FieldRelation copy constructor: 00472 void UnitTestFieldImpl::testFieldRelation() 00473 { 00474 00475 FieldRelation rA; 00476 FieldRelation rB(rA); 00477 00478 rA = rB; 00479 00480 } 00481 00482 } 00483 } 00484