Sierra Toolkit  Version of the Day
UnitTestField.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 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 <stdexcept>
11 #include <sstream>
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/BulkData.hpp>
19 #include <stk_mesh/base/FieldData.hpp>
20 #include <stk_mesh/base/GetBuckets.hpp>
21 #include <stk_mesh/base/GetEntities.hpp>
22 
23 #include <stk_mesh/fem/FEMMetaData.hpp>
24 #include <stk_mesh/fem/CoordinateSystems.hpp>
25 
26 #include <boost/range.hpp>
27 #include <boost/foreach.hpp>
28 
29 namespace {
30 
31 const stk_classic::mesh::EntityRank NODE_RANK = stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
32 
33 typedef shards::ArrayDimTag::size_type size_type;
34 
35 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( ATAG )
36 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( BTAG )
37 SHARDS_ARRAY_DIM_TAG_SIMPLE_DECLARATION( CTAG )
38 
39 template< class FieldType >
40 void print_bucket_array( const FieldType & f , const stk_classic::mesh::Bucket & k )
41 {
43  std::ostringstream oss;
44 
45  ArrayType a( f , k.begin(), k.end() );
46  ArrayType b( f , k );
47 
48  oss << " BucketArray[" << f.name() << "](" ;
49 
50  if ( a.size() != b.size() ) {
51  throw std::runtime_error("UnitTestField FAILED BucketArray dimensions not consistant with Bucket::iterator");
52  }
53 
54  if ( a.size() ) {
55  for ( unsigned i = 0 ; i < ArrayType::Rank ; ++i ) {
56  if ( i ) { oss << "," ; }
57  oss << a.dimension(i);
58  if (a.dimension(i) != b.dimension(i)) {
59  throw std::runtime_error("UnitTestField FAILED BucketArray dimensions not consistant with Bucket::iterator");
60  }
61  }
62  }
63  oss << ")" << std::endl ;
64 }
65 
66 STKUNIT_UNIT_TEST(UnitTestField, testCartesian)
67 {
68  // Test the Cartesian array dimension tag
69 
71 
72  std::string to_str = cartesian_tag.to_string(3 /*size*/, 1 /*idx*/);
73  std::string expected_str("y");
74  STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true);
75 
76  //should throw if we supply a size < 3:
77  STKUNIT_ASSERT_THROW( cartesian_tag.to_string(2 /*size*/, 1 /*idx*/),
78  std::runtime_error );
79 
80  size_type expected_idx = 1;
81  size_type idx = cartesian_tag.to_index(3 /*size*/, "y" /*dim*/);
82  STKUNIT_ASSERT_EQUAL( idx, expected_idx );
83 
84  //should throw if we supply a "z" along with size==2:
85  STKUNIT_ASSERT_THROW( cartesian_tag.to_index(2 /*size*/, "z" /*dim*/),
86  std::runtime_error );
87 }
88 
89 STKUNIT_UNIT_TEST(UnitTestField, testCylindrical)
90 {
91  // Test the Cylindrical array dimension tag
92 
94 
95  std::string to_str = cylindrical_tag.to_string(3 /*size*/, 1 /*idx*/);
96  std::string expected_str("a");
97  STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true );
98 
99  //should throw if we supply a size < 3:
100  STKUNIT_ASSERT_THROW( cylindrical_tag.to_string(2 /*size*/, 1 /*idx*/),
101  std::runtime_error );
102 
103  size_type expected_idx = 1;
104  size_type idx = cylindrical_tag.to_index(3 /*size*/, "a" /*dim*/);
105  STKUNIT_ASSERT_EQUAL( idx, expected_idx );
106 
107  //should throw if we supply a "z" along with size==2:
108  STKUNIT_ASSERT_THROW( cylindrical_tag.to_index(2 /*size*/, "z" /*dim*/),
109  std::runtime_error );
110 }
111 
112 STKUNIT_UNIT_TEST(UnitTestField, testFullTensor)
113 {
114  // Test the FullTensor array dimension tag
115 
117 
118  std::string to_str = fulltensor_tag.to_string(9 /*size*/, 1 /*idx*/);
119  std::string expected_str("yy");
120  STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true );
121 
122  //should throw if we supply a size < 9:
123  STKUNIT_ASSERT_THROW( fulltensor_tag.to_string(2 /*size*/, 1 /*idx*/),
124  std::runtime_error );
125 
126  size_type expected_idx = 6;
127  size_type idx = fulltensor_tag.to_index(9 /*size*/, "yx" /*dim*/);
128  STKUNIT_ASSERT_EQUAL( idx, expected_idx );
129 
130  //should throw if we supply a "zz" along with size==2:
131  STKUNIT_ASSERT_THROW( fulltensor_tag.to_index(2 /*size*/, "zz" /*dim*/),
132  std::runtime_error );
133 }
134 
135 STKUNIT_UNIT_TEST(UnitTestField, testSymmetricTensor)
136 {
137  // Test the SymmetricTensor array dimension tag
138 
139  const stk_classic::mesh::SymmetricTensor& symmetrictensor_tag =
141 
142  std::string to_str = symmetrictensor_tag.to_string(9 /*size*/, 1 /*idx*/);
143  std::string expected_str("yy");
144  STKUNIT_ASSERT_EQUAL( (to_str == expected_str), true);
145 
146  //should throw if we supply a size < 9:
147  STKUNIT_ASSERT_THROW( symmetrictensor_tag.to_string(2 /*size*/, 1 /*idx*/),
148  std::runtime_error );
149 
150  size_type expected_idx = 1;
151  size_type idx = symmetrictensor_tag.to_index(6 /*size*/, "yy" /*dim*/);
152  STKUNIT_ASSERT_EQUAL( idx, expected_idx );
153 
154  //should throw if we supply a "xz" along with size==5:
155  STKUNIT_ASSERT_THROW( symmetrictensor_tag.to_index(5 /*size*/, "xz" /*dim*/),
156  std::runtime_error );
157 }
158 
159 STKUNIT_UNIT_TEST(UnitTestField, testFieldDataArray)
160 {
161  stk_classic::ParallelMachine pm = MPI_COMM_SELF ;
162  std::ostringstream oss; // to test printing of things w/out spamming cout
163 
164  // specifications for some test fields
165  typedef stk_classic::mesh::Field<double> rank_zero_field ;
166  typedef stk_classic::mesh::Field<double,ATAG> rank_one_field ;
167  typedef stk_classic::mesh::Field<double,ATAG,BTAG> rank_two_field ;
168  typedef stk_classic::mesh::Field<double,ATAG,BTAG,CTAG> rank_three_field ;
169 
170  const std::string name0("test_field_0");
171  const std::string name1("test_field_1");
172  const std::string name2("test_field_2");
173  const std::string name3("test_field_3");
174 
175  const int spatial_dimension = 3;
176  stk_classic::mesh::fem::FEMMetaData meta_data( spatial_dimension );
178 
179  rank_zero_field & f0 = meta_data.declare_field< rank_zero_field >( name0 );
180  rank_one_field & f1 = meta_data.declare_field< rank_one_field >( name1 );
181  rank_three_field & f3 = meta_data.declare_field< rank_three_field >( name3 );
182  rank_two_field & f2 = meta_data.declare_field< rank_two_field >( name2 );
183 
184  // confirm that declaring field with erroneous type throws exception
185  typedef stk_classic::mesh::Field<double,CTAG> error_type ;
186  STKUNIT_ASSERT_THROW(meta_data.declare_field< error_type >( name1 ),
187  std::runtime_error);
188 
189  stk_classic::mesh::Part & p0 = meta_data.declare_part("P0", NODE_RANK );
190  stk_classic::mesh::Part & p1 = meta_data.declare_part("P1", NODE_RANK );
191  stk_classic::mesh::Part & p2 = meta_data.declare_part("P2", NODE_RANK );
192  stk_classic::mesh::Part & p3 = meta_data.declare_part("P3", NODE_RANK );
193 
194  stk_classic::mesh::put_field( f0 , NODE_RANK , p0 );
195  stk_classic::mesh::put_field( f1 , NODE_RANK , p1 , 10 );
196  stk_classic::mesh::put_field( f2 , NODE_RANK , p2 , 10 , 20 );
197  stk_classic::mesh::put_field( f3 , NODE_RANK , p3 , 10 , 20 , 30 );
198 
199  stk_classic::mesh::print( oss , " " , f0 );
200 
201  meta_data.commit();
202 
203  bulk_data.modification_begin();
204 
205  // Declare a 10 nodes on each part
206 
207  for ( unsigned i = 1 ; i < 11 ; ++i ) {
208  bulk_data.declare_entity( NODE_RANK , i ,
209  std::vector< stk_classic::mesh::Part * >( 1 , & p0 ) );
210  }
211 
212  for ( unsigned i = 11 ; i < 21 ; ++i ) {
213  bulk_data.declare_entity( NODE_RANK , i ,
214  std::vector< stk_classic::mesh::Part * >( 1 , & p1 ) );
215  }
216 
217  for ( unsigned i = 21 ; i < 31 ; ++i ) {
218  bulk_data.declare_entity( NODE_RANK , i ,
219  std::vector< stk_classic::mesh::Part * >( 1 , & p2 ) );
220  }
221 
222  for ( unsigned i = 31 ; i < 41 ; ++i ) {
223  bulk_data.declare_entity( NODE_RANK , i ,
224  std::vector< stk_classic::mesh::Part * >( 1 , & p3 ) );
225  }
226 
227  // Go through node_buckets and print the all the fields on each bucket
228  const std::vector< stk_classic::mesh::Bucket *> & node_buckets =
229  bulk_data.buckets( NODE_RANK );
230 
231  for ( std::vector< stk_classic::mesh::Bucket *>::const_iterator
232  ik = node_buckets.begin() ; ik != node_buckets.end() ; ++ik ) {
233  stk_classic::mesh::Bucket & k = **ik ;
234 
235  std::vector< stk_classic::mesh::Part * > parts ;
236  k.supersets( parts );
237 
238  for ( std::vector< stk_classic::mesh::Part * >::iterator
239  ip = parts.begin() ; ip != parts.end() ; ++ip ) {
240  oss << " " << (*ip)->name();
241  }
242 
243  print_bucket_array( f0 , k );
244  print_bucket_array( f1 , k );
245  print_bucket_array( f2 , k );
246  print_bucket_array( f3 , k );
247  }
248 }
249 
250 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelector)
251 {
252  stk_classic::ParallelMachine pm = MPI_COMM_SELF ;
253  std::ostringstream oss; // to test printing of things w/out spamming cout
254 
255  // specifications for test field
256  typedef stk_classic::mesh::Field<double> rank_zero_field ;
257 
258  const std::string name0("test_field_0");
259 
260  const int spatial_dimension = 3;
261  stk_classic::mesh::fem::FEMMetaData meta_data( spatial_dimension );
263 
264  rank_zero_field & f0 = meta_data.declare_field< rank_zero_field >( name0 );
265 
266  stk_classic::mesh::Part & p0 = meta_data.declare_part("P0", NODE_RANK );
267  stk_classic::mesh::Part & p1 = meta_data.declare_part("P1", NODE_RANK );
268 
269  stk_classic::mesh::Selector select_p0 = p0;
270  std::cout <<"select_p0: "<< select_p0 << std::endl;
271 
272  stk_classic::mesh::put_field( f0 , NODE_RANK , select_p0 );
273 
274  stk_classic::mesh::print( oss , " " , f0 );
275 
276  meta_data.commit();
277 
278  bulk_data.modification_begin();
279 
280  // Declare 10 nodes on each part
281 
282  for ( unsigned i = 1 ; i < 11 ; ++i ) {
283  bulk_data.declare_entity( NODE_RANK , i ,
284  std::vector< stk_classic::mesh::Part * >( 1 , & p0 ) );
285  }
286 
287  for ( unsigned i = 11 ; i < 21 ; ++i ) {
288  bulk_data.declare_entity( NODE_RANK , i ,
289  std::vector< stk_classic::mesh::Part * >( 1 , & p1 ) );
290  }
291 
292  const std::vector< stk_classic::mesh::Bucket *> & node_buckets =
293  bulk_data.buckets( NODE_RANK );
294 
295  unsigned num = stk_classic::mesh::count_selected_entities(select_p0, node_buckets);
296 
297  STKUNIT_ASSERT_EQUAL( 10u, num );
298 
299  stk_classic::mesh::Selector select_f0 = stk_classic::mesh::selectField(f0);
300 
301  std::cout <<"select_f0: "<< select_f0 << std::endl;
302 
303  unsigned num_f0 = stk_classic::mesh::count_selected_entities(select_f0, node_buckets);
304  STKUNIT_ASSERT_EQUAL(10u, num_f0);
305 
306  std::vector<stk_classic::mesh::Bucket*> f0_buckets;
307  stk_classic::mesh::get_buckets(select_p0, bulk_data.buckets(NODE_RANK), f0_buckets);
308  unsigned num_buckets = f0_buckets.size();
309  STKUNIT_ASSERT_EQUAL(1u, num_buckets);
310 
311  BOOST_FOREACH(stk_classic::mesh::Bucket* b, f0_buckets) {
312  unsigned f0_size = b->field_data_size(f0);
313  STKUNIT_ASSERT_EQUAL(8u, f0_size);
314  }
315 }
316 
317 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelectorAnd)
318 {
319  stk_classic::ParallelMachine pm = MPI_COMM_SELF ;
320  std::ostringstream oss; // to test printing of things w/out spamming cout
321 
323  // specifications for test field
324 
325  const std::string name0("test_field_0");
326 
327  const int spatial_dimension = 3;
328  stk_classic::mesh::fem::FEMMetaData meta_data( spatial_dimension );
330 
331  rank_one_field & f0 = meta_data.declare_field< rank_one_field >( name0 );
332 
333  stk_classic::mesh::EntityRank elem_rank = meta_data.element_rank();
334  stk_classic::mesh::Part & elements = meta_data.declare_part("Elements", elem_rank);
335  stk_classic::mesh::Part & hex8s = meta_data.declare_part("Hex8", elem_rank );
336  stk_classic::mesh::Part & tet4s = meta_data.declare_part("Tet4", elem_rank );
337 
338  stk_classic::mesh::Selector elem_hex_selector = elements & hex8s;
339  stk_classic::mesh::Selector elem_tet_selector = elements & tet4s;
340  std::cout <<"elem_hex_selector: "<< elem_hex_selector << std::endl;
341  std::cout <<"elem_tet_selector: "<< elem_tet_selector << std::endl;
342 
343  stk_classic::mesh::put_field( f0 , elem_rank , elem_hex_selector, 8u );
344  stk_classic::mesh::put_field( f0 , elem_rank , elem_tet_selector, 4u );
345 
346  stk_classic::mesh::print( oss , " " , f0 );
347 
348  meta_data.commit();
349 
350  bulk_data.modification_begin();
351 
352  // Declare 10 elements on each part
353 
355  parts.push_back(&elements);
356  parts.push_back(&hex8s);
357 
358  for ( unsigned i = 1 ; i < 11 ; ++i ) {
359  bulk_data.declare_entity( elem_rank , i , parts );
360  }
361 
362  parts.clear();
363  parts.push_back(&elements);
364  parts.push_back(&tet4s);
365 
366  for ( unsigned i = 11 ; i < 21 ; ++i ) {
367  bulk_data.declare_entity( elem_rank , i , parts );
368  }
369 
370  stk_classic::mesh::BucketVector f0_buckets;
371  stk_classic::mesh::get_buckets(elem_hex_selector, bulk_data.buckets(elem_rank), f0_buckets);
372 
373  BOOST_FOREACH(stk_classic::mesh::Bucket* b, f0_buckets) {
374  unsigned f0_size = b->field_data_size(f0);
375  STKUNIT_ASSERT_EQUAL(64u, f0_size);
376  }
377 
378  f0_buckets.clear();
379 
380  stk_classic::mesh::get_buckets(elem_tet_selector, bulk_data.buckets(elem_rank), f0_buckets);
381 
382  BOOST_FOREACH(stk_classic::mesh::Bucket* b, f0_buckets) {
383  unsigned f0_size = b->field_data_size(f0);
384  STKUNIT_ASSERT_EQUAL(32u, f0_size);
385  }
386 }
387 
388 
389 STKUNIT_UNIT_TEST(UnitTestField, testFieldWithSelectorInvalid)
390 {
391  stk_classic::ParallelMachine pm = MPI_COMM_SELF ;
392  std::ostringstream oss; // to test printing of things w/out spamming cout
393 
395  // specifications for test field
396 
397  const std::string name0("test_field_0");
398 
399  const int spatial_dimension = 3;
400  stk_classic::mesh::fem::FEMMetaData meta_data( spatial_dimension );
402 
403  rank_one_field & f0 = meta_data.declare_field< rank_one_field >( name0 );
404 
405  stk_classic::mesh::EntityRank elem_rank = meta_data.element_rank();
406  stk_classic::mesh::Part & hex8s = meta_data.declare_part("Hex8", elem_rank );
407 
408  stk_classic::mesh::Part & universal_part = meta_data.universal_part();
409  stk_classic::mesh::Selector elem_hexA_selector = hex8s;
410  stk_classic::mesh::Selector elem_hexB_selector = universal_part & hex8s;
411 
412  std::cout <<"elem_hexA_selector: "<< elem_hexA_selector << std::endl;
413  std::cout <<"elem_hexB_selector: "<< elem_hexB_selector << std::endl;
414 
415  stk_classic::mesh::put_field( f0 , elem_rank , elem_hexA_selector, 8u );
416  STKUNIT_ASSERT_THROW(
417  stk_classic::mesh::put_field( f0 , elem_rank , elem_hexA_selector, 4u ),
418  std::runtime_error
419  );
420  stk_classic::mesh::put_field( f0 , elem_rank , elem_hexB_selector, 4u );
421 
422  stk_classic::mesh::print( oss , " " , f0 );
423 
424  meta_data.commit();
425 
426  bulk_data.modification_begin();
427 
429  parts.push_back(&hex8s);
430  STKUNIT_ASSERT_THROW(
431  bulk_data.declare_entity( elem_rank , 1 , parts ),
432  std::runtime_error
433  );
434 
435 }
436 
437 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( ATAG )
438 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( BTAG )
439 SHARDS_ARRAY_DIM_TAG_SIMPLE_IMPLEMENTATION( CTAG )
440 
441 } //namespace <anonymous>
442 
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
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
static const SymmetricTensor33 & tag()
Singleton.
unsigned count_selected_entities(const Selector &selector, const std::vector< Bucket * > &input_buckets)
Count entities in selected buckets (selected by the given selector instance), and sorted by ID...
Definition: GetEntities.cpp:59
unsigned field_data_size(const FieldBase &field) const
Query the size of this field data specified by FieldBase.
Definition: Bucket.hpp:128
Implement an shards::ArrayDimTag for FullTensor.
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
Implement an shards::ArrayDimTag for SymmetricTensor.
static const FullTensor36 & tag()
Singleton.
field_type & put_field(field_type &field, EntityRank entity_rank, const Part &part, const void *init_value=NULL)
Declare a field to exist for a given entity type and Part.
static const Cartesian3d & tag()
Singleton.
An application-defined subset of a problem domain.
Definition: Part.hpp:49
Implement an shards::ArrayDimTag for Cylindrical coordinate dimensions.
Implement an shards::ArrayDimTag for Cartesian coordinate dimensions.
iterator begin() const
Beginning of the bucket.
Definition: Bucket.hpp:113
iterator end() const
End of the bucket.
Definition: Bucket.hpp:116
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
void supersets(PartVector &) const
This bucket is a subset of these parts.
Definition: Bucket.cpp:164
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
AllSelectedBucketsRange get_buckets(const Selector &selector, const BulkData &mesh)
Definition: GetBuckets.cpp:26
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
static const Cylindrical & tag()
Singleton.
Field data Array for a given array field and bucket
Definition: FieldData.hpp:65