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 
PairIterEntityComm comm() const
Complete communicaiton list for this entity.
Definition: Entity.hpp:181
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.
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
bool assert_correct() const
A method to assist in unit testing - accesses private data as necessary.
Definition: Bucket.cpp:225
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
Integer type for the entity keys, which is an encoding of the entity type and entity identifier...
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Definition: Types.hpp:111
EntityModificationLog log_query() const
Query the current state of the entity log.
Definition: Entity.hpp:125
An application-defined subset of a problem domain.
Definition: Part.hpp:49
size_t size() const
Number of entities associated with this bucket.
Definition: Bucket.hpp:119
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state...
unsigned parallel_size() const
Size of the parallel machine.
Definition: BulkData.hpp:82
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent. This is a parallel synchronous call. The first time this method is called the mesh meta data is verified to be committed and parallel consistent. An exception is thrown if this verification fails.
Definition: BulkData.cpp:172
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
void change_entity_owner(const std::vector< EntityProc > &arg_change)
Give away ownership of entities to other parallel processes.
unsigned parallel_rank() const
Rank of the parallel machine&#39;s local processor.
Definition: BulkData.hpp:85
EntityRank entity_rank() const
The rank of this entity.
Definition: Entity.hpp:128
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
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
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
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
bool destroy_entity(Entity *&entity)
Request the destruction an entity on the local process.
Definition: BulkData.cpp:698
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175