Sierra Toolkit  Version of the Day
UnitTestBulkDataAdapt.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 #include <iostream>
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/BulkData.hpp>
18 #include <stk_mesh/base/GetEntities.hpp>
19 #include <stk_mesh/base/EntityComm.hpp>
20 #include <stk_mesh/base/Comm.hpp>
21 
22 #include <stk_mesh/fixtures/BoxFixture.hpp>
23 #include <stk_mesh/fixtures/RingFixture.hpp>
24 
25 #include <unit_tests/UnitTestModificationEndWrapper.hpp>
26 #include <unit_tests/UnitTestRingFixture.hpp>
27 
37 using stk_classic::mesh::BaseEntityRank;
41 using stk_classic::mesh::EntityId;
43 using stk_classic::mesh::EntityVector;
44 using stk_classic::mesh::EntityRank;
47 
48 namespace {
49 const EntityRank NODE_RANK = FEMMetaData::NODE_RANK;
50 } // empty namespace
51 
52 void printEntity(std::ostringstream& msg, Entity *entity)
53 {
54  msg << " :: " << print_entity_key(entity) << ":o[" << entity->owner_rank() << "]:l[" << entity->log_query()
55  << "]:ec[";
56  for ( PairIterEntityComm ec = entity->comm() ; ! ec.empty() ; ++ec ) {
57  msg << "(" << ec->ghost_id << "," << ec->proc << ")";
58  }
59  msg << "]";
60 }
61 
62 void printNode(std::ostringstream& msg, Entity *node)
63 {
64  printEntity(msg, node);
65  PairIterRelation rels = node->relations();
66  for (unsigned i = 0; i < rels.size(); i++)
67  {
68  Entity *entity = rels[i].entity();
69  if (entity->entity_rank() > node->entity_rank())
70  printEntity(msg, entity);
71  }
72 }
73 
74 void printBuckets(std::ostringstream& msg, BulkData& mesh)
75 {
76  const std::vector<Bucket*> & buckets = mesh.buckets(0);
77  for (unsigned i=0; i < buckets.size(); i++)
78  {
79  const Bucket& bucket = *buckets[i];
80  msg << " bucket[" << i << "] = ";
81  size_t bucket_size = bucket.size();
82  for (unsigned ie=0; ie < bucket_size; ie++)
83  {
84  msg << bucket[ie].identifier() << ", ";
85  }
86  }
87 }
88 
89 static void checkBuckets( BulkData& mesh)
90 {
91  const std::vector<Bucket*> & buckets = mesh.buckets(0);
92  for (unsigned i=0; i < buckets.size(); i++)
93  {
94  Bucket* bucket = buckets[i];
95  STKUNIT_ASSERT(bucket->assert_correct());
96  }
97 }
98 
99 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, test_other_ghosting_2)
100 {
101  //
102  // testing if modification flags propagate properly for ghosted entities
103  //
104  // To test this, we focus on a single node shared on 2 procs, ghosted on others
105  //
106 
116  // elem, node0, node1, owner
117  EntityId elems_0[][4] = { {100, 21, 50, 0}, {201, 21, 32, 1}, {302, 32, 50, 2},
118  {500, 41, 70, 0}, {301, 41, 42, 1}, {402, 42, 70, 2} };
119  // node, owner
120  EntityId nodes_0[][2] = { {21,1}, {50,0}, {32, 2}, {41, 1}, {42, 1}, {70, 0} };
121 
122  unsigned nelems = sizeof(elems_0)/4/sizeof(EntityId);
123  unsigned nnodes = sizeof(nodes_0)/2/sizeof(EntityId);
124 
125  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
126 
127  // Set up meta and bulk data
128  const unsigned spatial_dim = 2;
129 
130  std::vector<std::string> entity_rank_names = stk_classic::mesh::fem::entity_rank_names(spatial_dim);
131  entity_rank_names.push_back("FAMILY_TREE");
132 
133  FEMMetaData meta_data(spatial_dim, entity_rank_names);
134  //Part & part_tmp = meta_data.declare_part( "temp");
135 
136  meta_data.commit();
137  unsigned max_bucket_size = 1;
138  BulkData mesh(FEMMetaData::get_meta_data(meta_data), pm, max_bucket_size);
139  //BulkData mesh(FEMMetaData::get_meta_data(meta_data), pm);
140  unsigned p_rank = mesh.parallel_rank();
141  unsigned p_size = mesh.parallel_size();
142 
143  if (p_size != 3) return;
144 
145  //
146  // Begin modification cycle so we can create the entities and relations
147  //
148 
149  // We're just going to add everything to the universal part
150  stk_classic::mesh::PartVector empty_parts;
151 
152  // Create elements
153  const EntityRank elem_rank = meta_data.element_rank();
154  Entity * elem = 0;
155 
156  mesh.modification_begin();
157 
158  for (unsigned ielem=0; ielem < nelems; ielem++)
159  {
160  if (elems_0[ielem][3] == p_rank)
161  {
162  elem = &mesh.declare_entity(elem_rank, elems_0[ielem][0], empty_parts);
163 
164  EntityVector nodes;
165  // Create node on all procs
166  nodes.push_back( &mesh.declare_entity(NODE_RANK, elems_0[ielem][2], empty_parts) );
167  nodes.push_back( &mesh.declare_entity(NODE_RANK, elems_0[ielem][1], empty_parts) );
168 
169  // Add relations to nodes
170  mesh.declare_relation( *elem, *nodes[0], 0 );
171  mesh.declare_relation( *elem, *nodes[1], 1 );
172 
173  }
174  }
175 
176  mesh.modification_end();
177 
178  Entity* node1 = 0;
179 
180  // change node owners
181  mesh.modification_begin();
182 
183  std::vector<EntityProc> change;
184 
185  for (unsigned inode=0; inode < nnodes; inode++)
186  {
187  node1 = mesh.get_entity(0, nodes_0[inode][0]);
188  if (node1 && node1->owner_rank() == p_rank)
189  {
190  unsigned dest = nodes_0[inode][1];
191  EntityProc eproc(node1, dest);
192  change.push_back(eproc);
193  }
194  }
195 
196  mesh.change_entity_owner( change );
197 
198  mesh.modification_end();
199 
200  checkBuckets(mesh);
201 
202  MPI_Barrier(MPI_COMM_WORLD);
203 
204 
205  // attempt to delete a node and its elems but on a ghosted proc
206  mesh.modification_begin();
207 
208  if (p_rank == 2)
209  {
210  node1 = mesh.get_entity(0, 21);
211  Entity *elem1 = mesh.get_entity(2, 201);
212  Entity *elem2 = mesh.get_entity(2, 100);
213 
214  bool did_it_elem = mesh.destroy_entity(elem1);
215  did_it_elem = did_it_elem & mesh.destroy_entity(elem2);
216  STKUNIT_ASSERT(did_it_elem);
217  bool did_it = mesh.destroy_entity(node1);
218  STKUNIT_ASSERT(did_it);
219  }
220 
221  mesh.modification_end();
222 
223  checkBuckets(mesh);
224 
225  // this node should no longer exist anywhere
226  node1 = mesh.get_entity(0, 21);
227 
228  // uncomment to force failure of test
229  // STKUNIT_ASSERT(node1 == 0);
230 
231 }
232 
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::EntityKey
Integer type for the entity keys, which is an encoding of the entity type and entity identifier.
Definition: base/EntityKey.hpp:63
stk_classic::mesh::BulkData::change_entity_owner
void change_entity_owner(const std::vector< EntityProc > &arg_change)
Give away ownership of entities to other parallel processes.
Definition: BulkDataOwner.cpp:313
stk_classic::mesh::fixtures::RingFixture
Definition: RingFixture.hpp:37
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::mesh::BulkData::parallel_rank
unsigned parallel_rank() const
Rank of the parallel machine's local processor.
Definition: BulkData.hpp:85
stk_classic::mesh::fixtures::BoxFixture
Definition: BoxFixture.hpp:26
stk_classic::mesh::BulkData::destroy_entity
bool destroy_entity(Entity *&entity)
Request the destruction an entity on the local process.
Definition: BulkData.cpp:698
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::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
stk_classic::mesh::BulkData::get_entity
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
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::Bucket::size
size_t size() const
Number of entities associated with this bucket.
Definition: Bucket.hpp:119
stk_classic::mesh::BulkData::declare_relation
void declare_relation(Entity &e_from, Entity &e_to, const RelationIdentifier local_id)
Declare a relation and its converse between entities in the same mesh.
Definition: BulkDataRelation.cpp:129
stk_classic::mesh::Entity::log_query
EntityModificationLog log_query() const
Query the current state of the entity log.
Definition: Entity.hpp:125
stk_classic::mesh::Entity::comm
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
Definition: Entity.hpp:181
stk_classic::PairIter
Definition: PairIter.hpp:21
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::Entity::relations
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
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::EntityProc
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Definition: Types.hpp:111
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::Bucket::assert_correct
bool assert_correct() const
A method to assist in unit testing - accesses private data as necessary.
Definition: Bucket.cpp:225
stk_classic::mesh::Entity::owner_rank
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175
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::entity_rank
EntityRank entity_rank() const
The rank of this entity.
Definition: Entity.hpp:128
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::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