Sierra Toolkit  Version of the Day
UnitTestFieldImpl.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010, 2011 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 
10 #include <sstream>
11 #include <stdexcept>
12 
13 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
14 
15 #include <stk_util/parallel/Parallel.hpp>
16 
17 #include <stk_mesh/base/MetaData.hpp>
18 #include <stk_mesh/base/FieldRelation.hpp>
19 #include <stk_mesh/base/PartRelation.hpp>
20 #include <stk_mesh/base/FieldData.hpp>
21 
22 #include <stk_mesh/baseImpl/PartRepository.hpp>
23 #include <stk_mesh/baseImpl/EntityRepository.hpp>
24 #include <stk_mesh/baseImpl/FieldBaseImpl.hpp>
25 #include <stk_mesh/fem/CoordinateSystems.hpp>
26 
27 #include <Shards_BasicTopologies.hpp>
28 
29 namespace stk_classic {
30 namespace mesh {
31 
32 class UnitTestFieldImpl {
33 public:
34  UnitTestFieldImpl() {}
35 
36  void testField();
37  void testFieldRestriction();
38  void testFieldRelation();
39 
40 };
41 
42 }//namespace mesh
43 }//namespace stk_classic
44 
45 namespace {
46 
47 STKUNIT_UNIT_TEST(UnitTestField, testUnit)
48 {
49  stk_classic::mesh::UnitTestFieldImpl ufield;
50  ufield.testField();
51 }
52 
53 STKUNIT_UNIT_TEST(UnitTestFieldRestriction, testUnit)
54 {
55  stk_classic::mesh::UnitTestFieldImpl ufield;
56  ufield.testFieldRestriction();
57 }
58 
59 STKUNIT_UNIT_TEST(UnitTestFieldRelation, testUnit)
60 {
61  stk_classic::mesh::UnitTestFieldImpl ufield;
62  ufield.testFieldRelation();
63 }
64 
65 }//namespace <anonymous>
66 
67 //----------------------------------------------------------------------
68 
69 namespace stk_classic {
70 namespace mesh {
71 
72 namespace {
73 
74 // Simple tags for testing field dimensions
75 
76 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ATAG )
77 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( BTAG )
78 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( CTAG )
79 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( DTAG )
80 
81 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ATAG )
82 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( BTAG )
83 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( CTAG )
84 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( DTAG )
85 
86 }
87 
88 void UnitTestFieldImpl::testField()
89 {
90  MetaData meta_data;
91 
92  // Declaration of a field allocates one field object
93  // per state of the field. These fields are inserted
94  // into a vector of fields of the base class.
95 
96  impl::FieldRepository field_repo;
97  const FieldVector & allocated_fields = field_repo.get_fields();
98 
99  //------------------------------
100  // Declare a double precision scalar field of one state.
101  // Not an array; therefore, is rank zero.
102  // Test the query methods for accuracy.
103  FieldBase * const fA =
104  field_repo.declare_field( std::string("A"),
105  data_traits<double>() ,
106  0 /* # Ranks */ ,
107  NULL /* dimension tags */ ,
108  1 /* # States */ ,
109  &meta_data );
110 
111  STKUNIT_ASSERT( allocated_fields.size() == 1 );
112  STKUNIT_ASSERT( fA != NULL );
113  STKUNIT_ASSERT( fA == allocated_fields[0] );
114  STKUNIT_ASSERT( fA->name() == std::string("A") );
115  STKUNIT_ASSERT( fA->type_is<double>() );
116  STKUNIT_ASSERT( fA->state() == StateNone );
117  STKUNIT_ASSERT( fA->rank() == 0 );
118 
119  //------------------------------
120  // Declare a field with an invalid suffix in its name.
121  // Suffixes corresponding to "OLD" "N" "NM1" "NM2" "NM3" "NM4"
122  // are not allowed as these are automatically appended to
123  // the declared variable name for multistate fields.
124  {
125  STKUNIT_ASSERT_THROW(
126  field_repo.declare_field( "A_STKFS_OLD" ,
127  data_traits<double>() ,
128  0 /* # Ranks */ ,
129  NULL /* dimension tags */ ,
130  1 /* # States */ ,
131  &meta_data ),
132  std::runtime_error);
133  STKUNIT_ASSERT( allocated_fields.size() == 1 );
134  }
135 
136  //------------------------------
137  // Declare a double precision scalar field of two states.
138  // Not an array; therefore, is rank zero.
139  // Test that two fields: "B" and "B_OLD" were created.
140  // Test the query methods for accuracy.
141 
142  FieldBase * const fB =
143  field_repo.declare_field( std::string("B"),
144  data_traits<int>(),
145  0 /* # Ranks */ ,
146  NULL /* dimension tags */ ,
147  2 /* # States */ ,
148  &meta_data );
149 
150  STKUNIT_ASSERT( allocated_fields.size() == 3 );
151  STKUNIT_ASSERT( fB != NULL );
152  STKUNIT_ASSERT( fB == allocated_fields[1] );
153  STKUNIT_ASSERT( fB->name() == std::string("B") );
154  STKUNIT_ASSERT( fB->type_is<int>() );
155  STKUNIT_ASSERT( fB->state() == StateNew );
156  STKUNIT_ASSERT( fB->rank() == 0 );
157 
158  const FieldBase * const fB_old = allocated_fields[2] ;
159  STKUNIT_ASSERT( fB_old->name() == std::string("B_STKFS_OLD") );
160  STKUNIT_ASSERT( fB_old->type_is<int>() );
161  STKUNIT_ASSERT( fB_old->state() == StateOld );
162  STKUNIT_ASSERT( fB_old->rank() == 0 );
163 
164  //------------------------------
165  // Redeclare field must give back the previous field:
166 
167  FieldBase * const fB_redundant =
168  field_repo.declare_field( std::string("B"),
169  data_traits<int>(),
170  0 /* # Ranks */ ,
171  NULL /* dimension tags */ ,
172  2 /* # States */ ,
173  &meta_data );
174 
175  STKUNIT_ASSERT( allocated_fields.size() == 3 );
176  STKUNIT_ASSERT( fB == fB_redundant );
177 
178  //------------------------------
179  // Declare a double precision array field of four states.
180  // Test that four fields: were created.
181  // Test the query methods for accuracy.
182 
183  const shards::ArrayDimTag * dim_tags[] =
184  { & ATAG::tag() , & BTAG::tag() , & CTAG::tag() , & DTAG::tag() };
185 
186  FieldBase * const fC =
187  field_repo.declare_field( std::string("C"),
188  data_traits<double>(),
189  3 /* # Ranks */ ,
190  dim_tags /* dimension tags */ ,
191  4 /* # States */ ,
192  &meta_data );
193 
194  STKUNIT_ASSERT( allocated_fields.size() == 7 );
195  STKUNIT_ASSERT( fC != NULL );
196  STKUNIT_ASSERT( fC == allocated_fields[3] );
197  STKUNIT_ASSERT( fC->name() == std::string("C") );
198  STKUNIT_ASSERT( fC->type_is<double>() );
199  STKUNIT_ASSERT( fC->state() == StateNew );
200  STKUNIT_ASSERT( fC->rank() == 3 );
201 
202  const FieldBase * const fC_n = allocated_fields[4] ;
203  const FieldBase * const fC_nm1 = allocated_fields[5] ;
204  const FieldBase * const fC_nm2 = allocated_fields[6] ;
205 
206  STKUNIT_ASSERT( fC == fC->field_state( StateNP1 ) );
207  STKUNIT_ASSERT( fC_n == fC->field_state( StateN ) );
208  STKUNIT_ASSERT( fC_nm1 == fC->field_state( StateNM1 ) );
209  STKUNIT_ASSERT( fC_nm2 == fC->field_state( StateNM2 ) );
210 
211  STKUNIT_ASSERT( fC == fC_n->field_state( StateNP1 ) );
212  STKUNIT_ASSERT( fC_n == fC_n->field_state( StateN ) );
213  STKUNIT_ASSERT( fC_nm1 == fC_n->field_state( StateNM1 ) );
214  STKUNIT_ASSERT( fC_nm2 == fC_n->field_state( StateNM2 ) );
215 
216  STKUNIT_ASSERT( fC == fC_nm1->field_state( StateNP1 ) );
217  STKUNIT_ASSERT( fC_n == fC_nm1->field_state( StateN ) );
218  STKUNIT_ASSERT( fC_nm1 == fC_nm1->field_state( StateNM1 ) );
219  STKUNIT_ASSERT( fC_nm2 == fC_nm1->field_state( StateNM2 ) );
220 
221  STKUNIT_ASSERT( fC == fC_nm2->field_state( StateNP1 ) );
222  STKUNIT_ASSERT( fC_n == fC_nm2->field_state( StateN ) );
223  STKUNIT_ASSERT( fC_nm1 == fC_nm2->field_state( StateNM1 ) );
224  STKUNIT_ASSERT( fC_nm2 == fC_nm2->field_state( StateNM2 ) );
225 
226  STKUNIT_ASSERT( fC_n->name() == std::string("C_STKFS_N") );
227  STKUNIT_ASSERT( fC_n->type_is<double>() );
228  STKUNIT_ASSERT( fC_n->state() == StateN );
229  STKUNIT_ASSERT( fC_n->rank() == 3 );
230 
231  STKUNIT_ASSERT( fC_nm1->name() == std::string("C_STKFS_NM1") );
232  STKUNIT_ASSERT( fC_nm1->type_is<double>() );
233  STKUNIT_ASSERT( fC_nm1->state() == StateNM1 );
234  STKUNIT_ASSERT( fC_nm1->rank() == 3 );
235 
236  STKUNIT_ASSERT( fC_nm2->name() == std::string("C_STKFS_NM2") );
237  STKUNIT_ASSERT( fC_nm2->type_is<double>() );
238  STKUNIT_ASSERT( fC_nm2->state() == StateNM2 );
239  STKUNIT_ASSERT( fC_nm2->rank() == 3 );
240 
241  //------------------------------
242  // Redeclare field must give back the previous field:
243  //------------------------------
244 
245  for ( unsigned i = 0 ; i < allocated_fields.size() ; ++i ) {
246  FieldBase * const f = allocated_fields[i] ;
247  STKUNIT_ASSERT( f->mesh_meta_data_ordinal() == i );
248  }
249 
250  //Coverage of EntityDimension::name in FieldData.cpp
251  {
253  // static const char * name();
254 
255  entity_dimension_tag.name();
256  }
257 }
258 
259 
260 //----------------------------------------------------------------------
261 // Test field restrictions: the mapping of ( field , part ) -> dimensions
262 
263 void UnitTestFieldImpl::testFieldRestriction()
264 {
265  unsigned stride[8] ;
266 
267  stride[0] = 10 ;
268  for ( unsigned i = 1 ; i < 8 ; ++i ) {
269  stride[i] = ( i + 1 ) * stride[i-1] ;
270  }
271 
272  std::vector< std::string > dummy_names(1);
273  dummy_names[0].assign("dummy");
274 
275  MetaData meta_data(dummy_names);
276 
277  const FieldVector & allocated_fields = meta_data.get_fields();
278 
279  //------------------------------
280 
282 
283  FieldBase * const f2 =
284  &meta_data.declare_field<VectorField>( std::string("F2"), 1/* # states */ );
285 
286  //------------------------------
287 
288  FieldBase * const f3 =
289  &meta_data.declare_field<VectorField>( std::string("F3"), 2/* #states*/);
290 
291  FieldBase * const f3_old = f3->field_state( StateOld ) ;
292 
293  //------------------------------
294  // Test for correctness of vector of declared fields.
295  STKUNIT_ASSERT( allocated_fields.size() == 3 );
296  STKUNIT_ASSERT( f2 == allocated_fields[0] );
297  STKUNIT_ASSERT( f3 == allocated_fields[1] );
298 
299  //------------------------------
300  // Test for correctness of field internal state access:
301 
302  STKUNIT_ASSERT( f2 == f2->field_state( StateNone ) );
303  STKUNIT_ASSERT( NULL == f2->field_state( StateOld ) );
304  STKUNIT_ASSERT( f3 == f3->field_state( StateNew ) );
305  STKUNIT_ASSERT( f3_old == f3->field_state( StateOld ) );
306  STKUNIT_ASSERT( NULL == f3->field_state( StateNM1 ) );
307  STKUNIT_ASSERT( f3 == f3_old->field_state( StateNew ) );
308  STKUNIT_ASSERT( f3_old == f3_old->field_state( StateOld ) );
309  STKUNIT_ASSERT( NULL == f3_old->field_state( StateNM1 ) );
310 
311  //------------------------------
312  // Declare some parts for restrictions:
313 
314  Part & pA = meta_data.declare_part( std::string("A") , 0 );
315  Part & pB = meta_data.declare_part( std::string("B") , 0 );
316  Part & pC = meta_data.declare_part( std::string("C") , 0 );
317  Part & pD = meta_data.declare_part( std::string("D") , 0 );
318 
319  // Declare three restrictions:
320 
321  meta_data.declare_field_restriction(*f3, 0 , pA , stride );
322  meta_data.declare_field_restriction(*f3, 1 , pB , stride + 1 );
323  meta_data.declare_field_restriction(*f3, 2 , pC , stride + 2 );
324 
325  // Check for correctness of restrictions:
326 
327  STKUNIT_ASSERT( f3->restrictions().size() == 3 );
328  STKUNIT_ASSERT( f3->restrictions()[0] ==
329  FieldRestriction( 0 , pA.mesh_meta_data_ordinal() ) );
330  STKUNIT_ASSERT( f3->restrictions()[1] ==
331  FieldRestriction( 1 , pB.mesh_meta_data_ordinal() ) );
332  STKUNIT_ASSERT( f3->restrictions()[2] ==
333  FieldRestriction( 2 , pC.mesh_meta_data_ordinal() ) );
334 
335  meta_data.declare_field_restriction(*f3, 0 , pB , stride + 1 );
336 
337  STKUNIT_ASSERT_EQUAL( f3->max_size( 0 ) , 20u );
338 
339  //------------------------------
340  // Check for error detection of bad stride:
341  {
342  unsigned bad_stride[4] = { 5 , 4 , 6 , 3 };
343  STKUNIT_ASSERT_THROW(
344  meta_data.declare_field_restriction(*f3, 0 , pA , bad_stride ),
345  std::runtime_error
346  );
347  STKUNIT_ASSERT( f3->restrictions().size() == 4 );
348  }
349 
350  // Check for error detection in re-declaring an incompatible
351  // field restriction.
352  {
353  STKUNIT_ASSERT_THROW(
354  meta_data.declare_field_restriction(*f3, 0 , pA , stride + 1 ),
355  std::runtime_error
356  );
357  STKUNIT_ASSERT( f3->restrictions().size() == 4 );
358  }
359 
360  // Verify and clean out any redundant restructions:
361 
362  STKUNIT_ASSERT( f3->restrictions().size() == 4 );
363 
364  //------------------------------
365  // Introduce a redundant restriction, clean it, and
366  // check that it was cleaned.
367 
368 std::cout<<"pA ord: "<<pA.mesh_meta_data_ordinal()<<", pD ord: "<<pD.mesh_meta_data_ordinal()<<std::endl;
369  meta_data.declare_part_subset( pD, pA );
370  meta_data.declare_field_restriction(*f2, 0 , pA , stride );
371  meta_data.declare_field_restriction(*f2, 0 , pD , stride );
372 
373  STKUNIT_ASSERT( f2->restrictions().size() == 1 );
374 
375  {
376  const FieldBase::Restriction & rA = f2->restriction( 0 , pA );
377  const FieldBase::Restriction & rD = f2->restriction( 0 , pD );
378  STKUNIT_ASSERT( & rA == & rD );
379  STKUNIT_ASSERT( rA.part_ordinal() == pD.mesh_meta_data_ordinal() );
380  }
381 
382  //------------------------------
383  // Introduce a new restriction, then introduce a
384  // subset-superset relationship that renders the new restriction
385  // redundant and incompatible.
386  // Check that the verify_and_clean_restrictions method detects
387  // this error condition.
388  {
389  meta_data.declare_field_restriction(*f2, 0 , pB , stride + 1 );
390  STKUNIT_ASSERT_THROW(
391  meta_data.declare_part_subset( pD, pB ),
392  std::runtime_error
393  );
394  }
395 
396  //Test to cover print function in FieldBaseImpl.cpp and FieldBase.cpp
397  {
398  //Create a new field with MetaData m and two restrictions
399 
400  FieldBase * const f4 =
401  &meta_data.declare_field<VectorField>( std::string("F4"),
402  2 /* # states */ );
403 
404  meta_data.declare_part_subset( pD, pA );
405  meta_data.declare_part_subset( pC, pB );
406 
407  meta_data.declare_field_restriction(*f4, 0 , pA , stride );
408  meta_data.declare_field_restriction(*f4, 1 , pB , stride + 1 );
409  stk_classic::mesh::impl::print(std::cout, "Field f4", *f4);
410 
411  //test stride[i] / stride[i-1] section of else-if
412  stk_classic::mesh::print(std::cout, "Field f4", *f4);
413  }
414 
415  //Further tests to cover print function in FieldBase.cpp
416  {
417  //test stride[i] % stride[i-1] section of else-if
418 
419  //Create a new field with MetaData m and two restrictions
420 
421  FieldBase * const f5 =
422  &meta_data.declare_field<VectorField>( std::string("F5"),
423  2 /* # states */ );
424 
425  unsigned stride2[8] ;
426  stride2[0] = 10 ;
427  for ( unsigned i = 1 ; i < 3 ; ++i ) {
428  stride2[i] = stride[i-1];
429  }
430  for ( unsigned i = 3 ; i < 8 ; ++i ) {
431  stride2[i] = 0;
432  }
433  meta_data.declare_field_restriction(*f5, 0 , pA, stride2 );
434 
435  stk_classic::mesh::print(std::cout, "Field f5", *f5);
436 
437  }
438 
439  //Coverage for error from print_restriction in FieldBaseImpl.cpp when there is no stride (!stride[i])
440  //Call print_restriction from insert_restriction
441  {
442  unsigned arg_no_stride[2];
443 
444  arg_no_stride[0] = 1;
445  arg_no_stride[1] = 0;
446 
447  STKUNIT_ASSERT_THROW(
448  meta_data.declare_field_restriction(*f2, 0, pA, arg_no_stride),
449  std::runtime_error
450  );
451  }
452 
453  //Coverage of ordinal in FieldRestriction.hpp:
454  {
455  const FieldRestrictionVector & rMap = f3->restrictions();
456  const FieldRestrictionVector::const_iterator ie = rMap.end() ;
457  FieldRestrictionVector::const_iterator i = rMap.begin();
458 
459  EntityId entity_id = 0;
460  unsigned max = 0 ;
461 
462  for ( ; i != ie ; ++i ) {
463  if ( i->part_ordinal() == entity_id ) {
464  const unsigned len = pA.mesh_meta_data_ordinal() ? i->stride( pA.mesh_meta_data_ordinal() - 1 ) : 1 ;
465  if ( max < len ) { max = len ; }
466  }
467  }
468  }
469 }
470 
471 // Unit test the FieldRelation copy constructor:
472 void UnitTestFieldImpl::testFieldRelation()
473 {
474 
475  FieldRelation rA;
476  FieldRelation rB(rA);
477 
478  rA = rB;
479 
480 }
481 
482 }
483 }
484 
std::ostream & print(std::ostream &os, const std::string &indent, const Bucket &bucket)
Print the parts and entities of this bucket.
Definition: Bucket.cpp:259
Previous state of a field with three+ states.
Definition: FieldState.hpp:39
Newest state of a field with two states.
Definition: FieldState.hpp:36
static const EntityDimension & tag()
Singleton.
Definition: FieldData.cpp:20
Field with defined data type and multi-dimensions (if any)
Definition: Field.hpp:118
State of a field with one state.
Definition: FieldState.hpp:35
EntityId entity_id(const EntityKey &key)
Given an entity key, return the identifier for the entity.
Previous-2 state of a field with four+ states.
Definition: FieldState.hpp:41
Sierra Toolkit.
Previous state of a field with two states.
Definition: FieldState.hpp:38
Implement ArrayDimTag for the entity count dimension of a BucketArray.
Definition: FieldData.hpp:196
Newest state of a field with three+ states.
Definition: FieldState.hpp:37
Previous-1 state of a field with three+ states.
Definition: FieldState.hpp:40