Sierra Toolkit  Version of the Day
UnitTestBucket.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 <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/BulkData.hpp>
19 #include <stk_mesh/base/GetEntities.hpp>
20 #include <stk_mesh/base/Field.hpp>
21 #include <stk_mesh/base/FieldData.hpp>
22 #include <stk_mesh/base/Comm.hpp>
23 #include <stk_mesh/base/EntityComm.hpp>
24 #include <stk_mesh/base/Part.hpp>
25 #include <stk_mesh/base/Entity.hpp>
26 #include <stk_mesh/base/GetBuckets.hpp>
27 #include <stk_mesh/base/Bucket.hpp>
28 #include <stk_mesh/base/BulkModification.hpp>
29 #include <stk_mesh/base/Entity.hpp>
30 #include <stk_mesh/base/Bucket.hpp>
31 #include <stk_mesh/base/Ghosting.hpp>
32 
33 #include <stk_mesh/fem/FEMMetaData.hpp>
34 #include <stk_mesh/fem/FEMHelpers.hpp>
35 
36 #include <stk_mesh/baseImpl/BucketImpl.hpp>
37 
38 #include <stk_mesh/fixtures/BoxFixture.hpp>
39 
40 #include <Shards_BasicTopologies.hpp>
41 
47 using stk_classic::mesh::EntityRank;
48 using stk_classic::mesh::EntityId;
52 using stk_classic::mesh::BucketIterator;
57 
59 
60 namespace {
61 
62 const EntityRank NODE_RANK = FEMMetaData::NODE_RANK;
63 
64 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testBucket)
65 {
66  // Unit test the Part functionality in isolation:
67 
68  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
69  MPI_Barrier( pm );
70 
71  // Create a mesh for testing buckets...
72 
73  // Create dummy names for entity ranks to be given to MetaData
74  std::vector<std::string> entity_names(10);
75  for ( size_t i = 0 ; i < 10 ; ++i ) {
76  std::ostringstream name ;
77  name << "EntityRank" << i ;
78  entity_names[i] = name.str();
79  }
80 
81  // Create MetaData, BulkData
82  unsigned max_bucket_size = 4;
83  stk_classic::mesh::fixtures::BoxFixture fixture(pm, max_bucket_size, entity_names);
84  FEMMetaData& meta = fixture.fem_meta();
85  BulkData& bulk = fixture.bulk_data();
86  const EntityRank element_rank = meta.element_rank();
87  // Create two scalar fields, temperature and volume. Put temperature
88  // on all the nodes and put volume on all the elements.
89  unsigned number_of_states = 4;
90 
91  ScalarFieldType & temperature =
92  meta.declare_field < ScalarFieldType > ( "temperature" , number_of_states );
93  ScalarFieldType & volume =
94 
95  meta.declare_field < ScalarFieldType > ( "volume" , number_of_states );
96  Part & universal = meta.universal_part ();
97  put_field ( temperature , NODE_RANK , universal );
98  put_field ( volume , element_rank , universal );
99  meta.commit();
100 
101  // Generate the mesh
102  int root_box[3][2] = { { 0,4 } , { 0,5 } , { 0,6 } };
103  int local_box[3][2] = { { 0,0 } , { 0,0 } , { 0,0 } };
104  bulk.modification_begin();
105  fixture.generate_boxes( root_box, local_box );
106  STKUNIT_ASSERT(bulk.modification_end());
107 
108  // First, test for streaming IO;
109  {
110  std::string gold1;
111  // Parallel and Serial runs have different part intersections for the first
112  // bucket
113  if ( bulk.parallel_size() == 1 )
114  gold1 = "Bucket( EntityRank0 : {UNIVERSAL} {OWNS} )";
115  else
116  gold1 = "Bucket( EntityRank0 : {UNIVERSAL} )";
117  Bucket *b1 = bulk.buckets(0)[0];
118  std::stringstream out1_str;
119  out1_str << (*b1);
120  bool equal = (gold1 == out1_str.str());
121  STKUNIT_ASSERT_EQUAL ( equal, true );
122  }
123 
124  // Second, update state of bucket until circular cue is filled
125  {
126  /* Need to set some data in state, rotate look for it, rotate 3 more times
127  and look for it again */
128  for ( size_t i = 0 ; i != 10 ; ++i )
129  bulk.update_field_data_states ();
130  }
131 
132  // Third, checking field_data_valid (...)
133  {
134  const std::vector< FieldBase * > &field_bases = meta.get_fields();
135  STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases[0] , *bulk.buckets(3)[0] , 1 , "error" ) , std::runtime_error);
136  STKUNIT_ASSERT_EQUAL(field_data_valid ( *field_bases[0] , *bulk.buckets(0)[0] , 1 , "no_error" ) , true);
137  STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases[0] , *bulk.buckets(3)[0] , 99 , "error" ) , std::runtime_error);
138 
139  // Set up a second mesh
140 
141  MetaData meta2 ( entity_names );
142  BulkData bulk2( meta2 , pm , max_bucket_size );
143 
144  ScalarFieldType & temperature2 =
145  meta2.declare_field < ScalarFieldType > ( "temperature2" , number_of_states );
146  ScalarFieldType & volume2 =
147  meta2.declare_field < ScalarFieldType > ( "volume2" , number_of_states );
148  Part & universal2 = meta2.universal_part ();
149  put_field ( temperature2 , NODE_RANK , universal2 );
150  put_field ( volume2 , element_rank , universal2 );
151  meta2.commit();
152 
153  // Cover line containing messsage for wrong MetaData used
154  const std::vector< FieldBase * > &field_bases2 = meta2.get_fields();
155  STKUNIT_ASSERT_THROW(field_data_valid ( *field_bases2[0] , *bulk.buckets(0)[0] , 1 , "error" ) , std::runtime_error);
156  }
157 
158  // Fourth, check has_superset (...) and membership functions
159  {
160  PartVector tmp(2) ;
161  tmp[0] = & meta.universal_part();
162  tmp[1] = & meta.locally_owned_part();
163  STKUNIT_ASSERT_EQUAL ( has_superset ( *bulk.buckets(0)[0] , tmp ) , bulk.parallel_size() == 1 );
164  STKUNIT_ASSERT ( bulk.buckets(0)[0]->member_any ( tmp ) );
165  STKUNIT_ASSERT_EQUAL ( bulk.buckets(0)[0]->member_all ( tmp ) , bulk.parallel_size() == 1 );
166  STKUNIT_ASSERT ( bulk.buckets(0)[0]->member ( **meta.get_parts().begin() ) );
167  }
168 }
169 
170 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testGetInvolvedParts)
171 {
172  // Tests to cover get_involved_parts for GetBuckets.cpp - C.Brickley - 12 May 2010
173 
174  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
175  MPI_Barrier( pm );
176 
177  const int spatial_dimension = 3;
178 
179  FEMMetaData meta( spatial_dimension );
180  const EntityRank element_rank = meta.element_rank();
181  const EntityRank edge_rank = meta.edge_rank();
182 
183  PartVector involved_parts(2) ;
184  involved_parts[0] = & meta.universal_part();
185  involved_parts[1] = & meta.locally_owned_part();
186 
187  Part & partLeft_1 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_1" );
188 
189  Part & partLeft_2 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_2" );
190 
191  meta.commit();
192 
193  PartVector union_parts;
194  union_parts.push_back(&partLeft_1);
195  union_parts.push_back(&partLeft_2);
196 
197  BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 );
198  PartVector add_part4, no_part;
199  add_part4.push_back ( &partLeft_1 );
200 
201  bulk.modification_begin();
202  int size , rank;
205 
206  for ( int id_base = 0 ; id_base < 99 ; ++id_base )
207  {
208  int new_id = size * id_base + rank + 1;
209  bulk.declare_entity( 3 , new_id , add_part4 );
210  bulk.declare_entity( NODE_RANK , new_id , no_part );
211  }
212 
213  bulk.modification_end();
214 
215  const std::vector<Bucket*> & buckets = bulk.buckets( element_rank );
216 
217  std::vector<Bucket*>::const_iterator k;
218 
219  k = buckets.begin();
220 
221  //test 1 covers aecond section of "if" statement in while loop
222  get_involved_parts( union_parts, **k, involved_parts);
223 
224  //test 2 covers union_parts.size() = 0
225  PartVector union_parts2(0) ;
226  get_involved_parts( union_parts2, **k, involved_parts);
227 
228  //test 3 covers first section of "if" statement in while loop
229  const std::vector<Bucket*> & buckets2 = bulk.buckets( NODE_RANK );
230  std::vector<Bucket*>::const_iterator k2;
231 
232  k2 = buckets2.begin();
233  get_involved_parts( union_parts, **k2, involved_parts);
234 
235  // tests on throw_error and BucketIterator in bucket.cpp/hpp
236 
237  FEMMetaData meta2 (spatial_dimension);
238  BulkData bulk2( FEMMetaData::get_meta_data(meta2) , pm , 4 );
239 
240  unsigned number_of_states = 4;
241 
242  ScalarFieldType & temperature2 =
243  meta2.declare_field < ScalarFieldType >("temperature2" , number_of_states);
244  ScalarFieldType & volume2 =
245 
246  meta2.declare_field < ScalarFieldType >("volume2", number_of_states);
247  Part & universal = meta2.universal_part ();
248  put_field ( temperature2 , NODE_RANK , universal );
249  put_field ( volume2 , element_rank , universal );
250 
251  meta2.commit();
252 
253  bulk2.modification_begin();
254  bulk2.declare_entity( edge_rank, rank+1 , no_part );
255  bulk2.modification_end();
256 }
257 
258 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testBucket2)
259 {
260  // Tests to cover print, has_superset and BucketLess::operator() for Buckets.cpp - C.Brickley - 2nd June 2010
261 
262  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
263  MPI_Barrier( pm );
264 
265  const int spatial_dimension = 3;
266  FEMMetaData meta( spatial_dimension );
267  const EntityRank element_rank = meta.element_rank();
268 
269  PartVector involved_parts(2) ;
270  involved_parts[0] = & meta.universal_part();
271  involved_parts[1] = & meta.locally_owned_part();
272 
273  Part & partLeft_1 = meta.declare_part("block_left_1", element_rank);
274 
275  Part & partLeft_3 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_3" );
276 
277  meta.commit();
278 
279  BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 );
280  std::vector<Part *> add_part4;
281  add_part4.push_back ( &partLeft_1 );
282 
283  bulk.modification_begin();
284  int size , rank;
287 
288  for ( int id_base = 0 ; id_base < 99 ; ++id_base )
289  {
290  int new_id = size * id_base + rank;
291  bulk.declare_entity( 3 , new_id+1 , add_part4 );
292  }
293 
294  bulk.modification_end();
295 
296  const std::vector<Bucket*> & buckets2 = bulk.buckets( element_rank );
297 
298  std::vector<Bucket*>::const_iterator k2;
299 
300  k2 = buckets2.begin();
301 
302  Bucket& b2 = **k2;
303 
304  //define a new meta and bulkdata
305  std::vector<std::string> entity_names(10);
306 
307  for ( size_t i = 0 ; i < 10 ; ++i ) {
308  std::ostringstream name ;
309  name << "EntityRank" << i ;
310  entity_names[i] = name.str();
311  }
312 
313  MetaData meta2 ( entity_names );
314  BulkData bulk2( meta2 , pm , 4 );
315 
316  unsigned number_of_states = 4;
317 
318  ScalarFieldType & temperature2 =
319  meta2.declare_field < ScalarFieldType >("temperature2" , number_of_states);
320  ScalarFieldType & volume2 =
321  meta2.declare_field < ScalarFieldType >("volume2", number_of_states);
322  Part & universal = meta2.universal_part ();
323  put_field ( temperature2 , NODE_RANK , universal );
324  put_field ( volume2 , element_rank , universal );
325 
326  typedef Field<double> VectorFieldType;
327  typedef Field<double> ElementNodePointerFieldType;
328 
329  meta2.commit();
330 
331  //Test to cover print function in Bucket.cpp
332  std::ostringstream oss;
333  print(oss, " ", b2);
334 
335  //Test to cover has_superset function in Bucket.cpp
336  STKUNIT_ASSERT_EQUAL ( has_superset ( b2 , partLeft_3 ) , false );
337 
338  //Test on BucketLess::operator() in Bucket.cpp/hpp
339 
340  enum { KEY_TMP_BUFFER_SIZE = 64 };
341 
342  const unsigned max = ~(0u);
343 
344  unsigned key_tmp_buffer[ KEY_TMP_BUFFER_SIZE ];
345 
346  std::vector<unsigned> key_tmp_vector ;
347 
348  const unsigned key_size = 2 + 3 ;
349 
350  unsigned * const key =
351  ( key_size <= KEY_TMP_BUFFER_SIZE )
352  ? key_tmp_buffer
353  : ( key_tmp_vector.resize( key_size ) , & key_tmp_vector[0] );
354 
355 
356  key[ key[0] = 3 + 1 ] = max;
357 
358  {
359  unsigned * const k = key + 1 ;
360  for ( unsigned i = 0 ; i < 3 ; ++i ) { k[i] = 1 ; }
361  }
362 
363  // FIXME: The code below needs to be fixed or removed
364  /*
365  impl::BucketImpl::last_bucket_in_family( *k2 );
366 
367  const unsigned * t = key;
368  const Bucket * u = last_bucket;
369 
370  BucketLess Buck;
371 
372  bool res = Buck( &t[0], &u[0] );
373 
374  STKUNIT_EXPECT_EQUAL( res, false );
375  */
376 }
377 
378 STKUNIT_UNIT_TEST(UnitTestingOfBucket, testEntityComm)
379 {
380  // FIXME: With so much code commented out, this unit-test does
381  // not appear to be testing anything.
382 
383  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
384  MPI_Barrier( pm );
385 
386  const int spatial_dimension = 3;
387  FEMMetaData meta( spatial_dimension );
388 
389  BulkData bulk ( FEMMetaData::get_meta_data(meta) , pm , 100 );
390  std::vector<Part *> add_part4;
391 
392  Part & partLeft_1 = stk_classic::mesh::fem::declare_part<shards::Tetrahedron<4> >( meta, "block_left_1" );
393  meta.commit();
394 
395  add_part4.push_back ( &partLeft_1 );
396 
397  //int rank = stk_classic::parallel_machine_rank( pm );
398  // int size = stk_classic::parallel_machine_size( pm );
399  PartVector tmp(1);
400 
401  bulk.modification_begin();
402 
403  //int id_base = 0;
404  //int new_id = size * id_base + rank;
405  // for ( id_base = 0 ; id_base < 93 ; ++id_base )
406  // {
407  // int new_id = size * id_base + rank;
408  // bulk.declare_entity( 0 , new_id+1 , add_part4 );
409  // }
410 
411  bulk.modification_end();
412 
413  /* cout << endl << "Bucket test line 3" << endl ;
414  bool result = in_shared(elem);
415  if( result) {
416  STKUNIT_ASSERT_EQUAL( result , true );
417  }
418  cout << endl << "Bucket test line 4" << endl ;
419 
420  result = in_receive_ghost(elem);
421  if( result) {
422  STKUNIT_ASSERT_EQUAL( result , true );
423  }
424 
425  for ( unsigned p = 0 ; p < p_size ; ++p ) if ( p != p_rank ) {
426  cout << endl << "in relation h and p =" << p << endl ;
427 
428  STKUNIT_ASSERT_EQUAL( in_send_ghost( *elem , p ), false );
429  cout << endl << "in relation ii =" << endl
430  }
431 
432  cout << endl << "Bucket test line 5" << endl ;
433  result = in_send_ghost(elem);
434  if( result) {
435  STKUNIT_ASSERT_EQUAL( result , true );
436  }
437 
438  cout << endl << "Bucket test line 6" << endl ;
439 
440  unsigned proc = rank;
441  unsigned procnew = rank+10;
442 
443  result = in_shared(elem, proc);
444  if( result) {
445  STKUNIT_ASSERT_EQUAL( result , true );
446  }
447  cout << endl << "Bucket test line 7" << endl ; */
448 }
449 
450 }
stk_classic::mesh::FieldBase
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
stk_classic::mesh::PairIterEntityComm
PairIter< std::vector< EntityCommInfo >::const_iterator > PairIterEntityComm
Span of ( communication-subset-ordinal , process-rank ) pairs for the communication of an entity.
Definition: Types.hpp:128
stk_classic::mesh::put_field
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.
stk_classic::mesh::Bucket
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
stk_classic::mesh::BulkData::parallel_size
unsigned parallel_size() const
Size of the parallel machine.
Definition: BulkData.hpp:82
stk_classic::parallel_machine_size
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Definition: Parallel.cpp:18
stk_classic::mesh::fixtures::BoxFixture
Definition: BoxFixture.hpp:26
stk_classic::mesh::Field
Field with defined data type and multi-dimensions (if any)
Definition: Field.hpp:118
stk_classic::mesh::print
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
stk_classic::mesh::Part
An application-defined subset of a problem domain.
Definition: Part.hpp:49
stk_classic::mesh::BulkData::declare_entity
Entity & declare_entity(EntityRank ent_rank, EntityId ent_id, const PartVector &parts)
Create or retrieve a locally owned entity of a given rank and id.
Definition: BulkData.cpp:215
stk_classic::mesh::fem::FEMMetaData::locally_owned_part
Part & locally_owned_part() const
Subset for the problem domain that is owned by the local process. Ghost entities are not members of t...
Definition: FEMMetaData.hpp:277
stk_classic::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
stk_classic::mesh::fem::FEMMetaData::get_parts
const PartVector & get_parts() const
Query all parts of the mesh ordered by the parts' ordinal.
Definition: FEMMetaData.hpp:304
stk_classic::mesh::BulkData::update_field_data_states
void update_field_data_states() const
Rotate the field data of multistate fields.
Definition: BulkData.hpp:174
stk_classic::mesh::BulkData::modification_end
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state.
Definition: BulkDataEndSync.cpp:729
stk_classic::mesh::fem::FEMMetaData::edge_rank
EntityRank edge_rank() const
Returns the edge rank which changes depending on spatial dimension.
Definition: FEMMetaData.hpp:132
stk_classic::mesh::fem::FEMMetaData::commit
void commit()
Commit the part and field declarations so that the meta data manager can be used to create mesh bulk ...
Definition: FEMMetaData.hpp:466
stk_classic::mesh::BulkData::modification_begin
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent....
Definition: BulkData.cpp:172
stk_classic::mesh::MetaData
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
stk_classic::mesh::PartVector
std::vector< Part * > PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
stk_classic::mesh::fem::FEMMetaData::get_fields
const FieldVector & get_fields() const
Get all defined fields.
Definition: FEMMetaData.hpp:415
eastl::equal
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
Definition: algorithm_eastl.h:1527
stk_classic::mesh::Selector
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
stk_classic::mesh::fem::FEMMetaData::declare_field
field_type & declare_field(const std::string &name, unsigned number_of_states=1)
Declare a field of the given field_type, test name, and number of states.
Definition: FEMMetaData.hpp:427
stk_classic::mesh::field_data_valid
bool field_data_valid(const FieldBase &f, const Bucket &k, unsigned ord, const char *required_by)
Check for existence of field data.
Definition: Bucket.cpp:194
stk_classic::mesh::has_superset
bool has_superset(const Bucket &bucket, const unsigned &ordinal)
Is this bucket a subset of the given part by partID.
Definition: Bucket.cpp:127
stk_classic::parallel_machine_rank
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
Definition: Parallel.cpp:29
stk_classic::mesh::fem::FEMMetaData::element_rank
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
Definition: FEMMetaData.hpp:160
stk_classic::mesh::fem::FEMMetaData
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
stk_classic::mesh::Entity
A fundamental unit within the discretization of a problem domain, including but not limited to nodes,...
Definition: Entity.hpp:120
stk_classic::mesh::fem::FEMMetaData::universal_part
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part.
Definition: FEMMetaData.hpp:272
stk_classic::mesh::BulkData
Manager for an integrated collection of entities, entity relations, and buckets of field data.
Definition: BulkData.hpp:49
stk_classic::mesh::BulkData::buckets
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195