Sierra Toolkit Version of the Day
UnitTestBulkDataAdapt.cpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #include <iostream>
00010 #include <sstream>
00011 #include <stdexcept>
00012 
00013 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
00014 
00015 #include <stk_util/parallel/Parallel.hpp>
00016 
00017 #include <stk_mesh/base/BulkData.hpp>
00018 #include <stk_mesh/base/GetEntities.hpp>
00019 #include <stk_mesh/base/EntityComm.hpp>
00020 #include <stk_mesh/base/Comm.hpp>
00021 
00022 #include <stk_mesh/fixtures/BoxFixture.hpp>
00023 #include <stk_mesh/fixtures/RingFixture.hpp>
00024 
00025 #include <unit_tests/UnitTestModificationEndWrapper.hpp>
00026 #include <unit_tests/UnitTestRingFixture.hpp>
00027 
00028 using stk::mesh::Part;
00029 using stk::mesh::Bucket;
00030 using stk::mesh::PairIterRelation;
00031 using stk::mesh::PairIterEntityComm;
00032 using stk::mesh::MetaData;
00033 using stk::mesh::fem::FEMMetaData;
00034 using stk::mesh::BulkData;
00035 using stk::mesh::Selector;
00036 using stk::mesh::PartVector;
00037 using stk::mesh::BaseEntityRank;
00038 using stk::mesh::PairIterRelation;
00039 using stk::mesh::EntityProc;
00040 using stk::mesh::Entity;
00041 using stk::mesh::EntityId;
00042 using stk::mesh::EntityKey;
00043 using stk::mesh::EntityVector;
00044 using stk::mesh::EntityRank;
00045 using stk::mesh::fixtures::RingFixture;
00046 using stk::mesh::fixtures::BoxFixture;
00047 
00048 namespace {
00049 const EntityRank NODE_RANK = FEMMetaData::NODE_RANK;
00050 } // empty namespace
00051 
00052 void printEntity(std::ostringstream& msg, Entity *entity)
00053 {
00054   msg << " :: " << print_entity_key(entity) << ":o[" << entity->owner_rank() << "]:l[" << entity->log_query()
00055       << "]:ec[";
00056   for ( PairIterEntityComm ec = entity->comm() ; ! ec.empty() ; ++ec ) {
00057     msg << "(" << ec->ghost_id << "," << ec->proc << ")";
00058   }
00059   msg << "]";
00060 }
00061 
00062 void printNode(std::ostringstream& msg, Entity *node)
00063 {
00064   printEntity(msg, node);
00065   PairIterRelation rels = node->relations();
00066   for (unsigned i = 0; i < rels.size(); i++)
00067     {
00068       Entity *entity = rels[i].entity();
00069       if (entity->entity_rank() > node->entity_rank())
00070         printEntity(msg, entity);
00071     }
00072 }
00073 
00074 void printBuckets(std::ostringstream& msg, BulkData& mesh)
00075 {
00076   const std::vector<Bucket*> & buckets = mesh.buckets(0);
00077   for (unsigned i=0; i < buckets.size(); i++)
00078     {
00079       const Bucket& bucket = *buckets[i];
00080       msg << " bucket[" << i << "] = ";
00081       size_t bucket_size = bucket.size();
00082       for (unsigned ie=0; ie < bucket_size; ie++)
00083         {
00084           msg << bucket[ie].identifier() << ", ";
00085         }
00086     }
00087 }
00088 
00089 static void checkBuckets( BulkData& mesh)
00090 {
00091   const std::vector<Bucket*> & buckets = mesh.buckets(0);
00092   for (unsigned i=0; i < buckets.size(); i++)
00093     {
00094       Bucket* bucket = buckets[i];
00095       STKUNIT_ASSERT(bucket->assert_correct());
00096     }
00097 }
00098 
00099 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, test_other_ghosting_2)
00100 {
00101   //
00102   // testing if modification flags propagate properly for ghosted entities
00103   //
00104   // To test this, we focus on a single node shared on 2 procs, ghosted on others
00105   //
00106 
00116   // elem, node0, node1, owner
00117   EntityId elems_0[][4] = { {100, 21, 50, 0}, {201, 21, 32, 1}, {302, 32, 50, 2}, 
00118                             {500, 41, 70, 0}, {301, 41, 42, 1}, {402, 42, 70, 2}  };
00119   // node, owner
00120   EntityId nodes_0[][2] = { {21,1}, {50,0}, {32, 2}, {41, 1}, {42, 1}, {70, 0} };
00121 
00122   unsigned nelems = sizeof(elems_0)/4/sizeof(EntityId);
00123   unsigned nnodes = sizeof(nodes_0)/2/sizeof(EntityId);
00124 
00125   stk::ParallelMachine pm = MPI_COMM_WORLD;
00126 
00127   // Set up meta and bulk data
00128   const unsigned spatial_dim = 2;
00129 
00130   std::vector<std::string> entity_rank_names = stk::mesh::fem::entity_rank_names(spatial_dim);
00131   entity_rank_names.push_back("FAMILY_TREE");
00132 
00133   FEMMetaData meta_data(spatial_dim, entity_rank_names);
00134   //Part & part_tmp = meta_data.declare_part( "temp");
00135   
00136   meta_data.commit();
00137   unsigned max_bucket_size = 1;
00138   BulkData mesh(FEMMetaData::get_meta_data(meta_data), pm, max_bucket_size);
00139   //BulkData mesh(FEMMetaData::get_meta_data(meta_data), pm);
00140   unsigned p_rank = mesh.parallel_rank();
00141   unsigned p_size = mesh.parallel_size();
00142 
00143   if (p_size != 3) return;
00144 
00145   //
00146   // Begin modification cycle so we can create the entities and relations
00147   //
00148 
00149   // We're just going to add everything to the universal part
00150   stk::mesh::PartVector empty_parts;
00151 
00152   // Create elements
00153   const EntityRank elem_rank = meta_data.element_rank();
00154   Entity * elem = 0;
00155 
00156   mesh.modification_begin();
00157 
00158   for (unsigned ielem=0; ielem < nelems; ielem++)
00159     {
00160       if (elems_0[ielem][3] == p_rank)
00161         {
00162           elem = &mesh.declare_entity(elem_rank, elems_0[ielem][0], empty_parts);
00163 
00164           EntityVector nodes;
00165           // Create node on all procs
00166           nodes.push_back( &mesh.declare_entity(NODE_RANK, elems_0[ielem][2], empty_parts) );
00167           nodes.push_back( &mesh.declare_entity(NODE_RANK, elems_0[ielem][1], empty_parts) );
00168 
00169           // Add relations to nodes
00170           mesh.declare_relation( *elem, *nodes[0], 0 );
00171           mesh.declare_relation( *elem, *nodes[1], 1 );
00172 
00173         }
00174     }
00175 
00176   mesh.modification_end();
00177 
00178   Entity* node1 = 0;
00179 
00180   // change node owners
00181   mesh.modification_begin();
00182 
00183   std::vector<EntityProc> change;
00184 
00185   for (unsigned inode=0; inode < nnodes; inode++)
00186     {
00187       node1 = mesh.get_entity(0, nodes_0[inode][0]);
00188       if (node1 && node1->owner_rank() == p_rank)
00189         {
00190           unsigned dest = nodes_0[inode][1];
00191           EntityProc eproc(node1, dest);
00192           change.push_back(eproc);
00193         }
00194     }
00195 
00196   mesh.change_entity_owner( change );
00197 
00198   mesh.modification_end();
00199 
00200   checkBuckets(mesh);
00201 
00202   MPI_Barrier(MPI_COMM_WORLD);
00203 
00204 
00205   // attempt to delete a node and its elems but on a ghosted proc
00206   mesh.modification_begin();
00207 
00208   if (p_rank == 2)
00209     {
00210       node1 = mesh.get_entity(0, 21);
00211       Entity *elem1 = mesh.get_entity(2, 201);
00212       Entity *elem2 = mesh.get_entity(2, 100);
00213 
00214       bool did_it_elem = mesh.destroy_entity(elem1);
00215       did_it_elem = did_it_elem & mesh.destroy_entity(elem2);
00216       STKUNIT_ASSERT(did_it_elem);
00217       bool did_it = mesh.destroy_entity(node1);
00218       STKUNIT_ASSERT(did_it);
00219     }
00220 
00221   mesh.modification_end();
00222 
00223   checkBuckets(mesh);
00224 
00225   // this node should no longer exist anywhere
00226   node1 = mesh.get_entity(0, 21);
00227 
00228   // uncomment to force failure of test
00229   // STKUNIT_ASSERT(node1 == 0);
00230 
00231 }
00232 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines