|
Sierra Toolkit
Version of the Day
|
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_classic::mesh::Part; 00029 using stk_classic::mesh::Bucket; 00030 using stk_classic::mesh::PairIterRelation; 00031 using stk_classic::mesh::PairIterEntityComm; 00032 using stk_classic::mesh::MetaData; 00033 using stk_classic::mesh::fem::FEMMetaData; 00034 using stk_classic::mesh::BulkData; 00035 using stk_classic::mesh::Selector; 00036 using stk_classic::mesh::PartVector; 00037 using stk_classic::mesh::BaseEntityRank; 00038 using stk_classic::mesh::PairIterRelation; 00039 using stk_classic::mesh::EntityProc; 00040 using stk_classic::mesh::Entity; 00041 using stk_classic::mesh::EntityId; 00042 using stk_classic::mesh::EntityKey; 00043 using stk_classic::mesh::EntityVector; 00044 using stk_classic::mesh::EntityRank; 00045 using stk_classic::mesh::fixtures::RingFixture; 00046 using stk_classic::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_classic::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_classic::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_classic::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