Sierra Toolkit Version of the Day
UnitTestBulkData_ChangeParts.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 
00012 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
00013 
00014 #include <stk_util/parallel/Parallel.hpp>
00015 
00016 #include <stk_mesh/base/BulkData.hpp>
00017 #include <stk_mesh/base/GetEntities.hpp>
00018 #include <stk_mesh/base/Comm.hpp>
00019 
00020 #include <stk_mesh/fixtures/RingFixture.hpp>
00021 
00022 #include <unit_tests/UnitTestModificationEndWrapper.hpp>
00023 
00024 using stk::mesh::Part;
00025 using stk::mesh::MetaData;
00026 using stk::mesh::fem::FEMMetaData;
00027 using stk::mesh::BulkData;
00028 using stk::mesh::Entity;
00029 using stk::mesh::Selector;
00030 using stk::mesh::PartVector;
00031 using stk::mesh::fixtures::RingFixture;
00032 
00033 //----------------------------------------------------------------------
00034 
00035 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, testChangeParts)
00036 {
00037   // This unit test tests part operations and verifies operations
00038   // by looking at bucket supersets. We use contrived entities
00039   // (as opposed to a fixture) for simplicity and clarity.
00040 
00041   stk::ParallelMachine pm = MPI_COMM_WORLD;
00042   MPI_Barrier( pm );
00043 
00044   const unsigned p_size = stk::parallel_machine_size( pm );
00045   const unsigned p_rank = stk::parallel_machine_rank( pm );
00046 
00047   // Single process, no sharing
00048 
00049   // Meta data with entity ranks [0..9]
00050   const unsigned spatial_dimension = 10;
00051   std::vector<std::string> entity_names(spatial_dimension+1);
00052   for ( size_t i = 0 ; i <= spatial_dimension ; ++i ) {
00053     std::ostringstream name ;
00054     name << "EntityRank_" << i ;
00055     entity_names[i] = name.str();
00056   }
00057 
00058   // Create a mesh with a bunch of parts
00059 
00060   FEMMetaData meta( spatial_dimension, entity_names );
00061   BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 );
00062 
00063   Part & part_univ   = meta.universal_part();
00064   Part & part_owns   = meta.locally_owned_part();
00065   Part & part_shared = meta.globally_shared_part();
00066 
00067   Part & part_A_0 = meta.declare_part(std::string("A_0"), 0 /*entity_rank*/);
00068   Part & part_A_1 = meta.declare_part(std::string("A_1"), 1 /*entity_rank*/);
00069   Part & part_A_2 = meta.declare_part(std::string("A_2"), 2 /*entity_rank*/);
00070   Part & part_A_3 = meta.declare_part(std::string("A_3"), 3 /*entity_rank*/);
00071 
00072   Part & part_B_0 = meta.declare_part(std::string("B_0"), 0 /*entity_rank*/);
00073   Part & part_B_2 = meta.declare_part(std::string("B_2"), 2 /*entity_rank*/);
00074 
00075   meta.commit();
00076   bulk.modification_begin();
00077 
00078   PartVector tmp(1), no_parts;
00079 
00080   // Declare a few entities of various ranks. In order for the sharing
00081   // to work, we need to have all the entities we'll be playing with
00082   // to be in the owned-closure of a high-level non-shared entity, we'll
00083   // call that entity the closure_entity because all the other entities
00084   // will be in it's closure.
00085 
00086   Entity& closure_entity = bulk.declare_entity(4 /*entity rank*/,
00087                                                p_rank+1 /*id*/,
00088                                                no_parts);
00089 
00090   tmp[0] = & part_A_0 ;
00091   Entity& entity_0_1 = bulk.declare_entity(0 /*entity rank*/, 1 /*id*/, tmp);
00092   bulk.declare_relation( closure_entity , entity_0_1 , 0 /*local_rel_id*/ );
00093 
00094   tmp[0] = & part_A_1 ;
00095   Entity& entity_1_1 = bulk.declare_entity(1 /*entity rank*/, 1 /*id*/, tmp);
00096   bulk.declare_relation( closure_entity , entity_1_1 , 1 /*local_rel_id*/ );
00097 
00098   tmp[0] = & part_A_2 ;
00099   Entity& entity_2_1 = bulk.declare_entity(2 /*entity rank*/, 1 /*id*/, tmp);
00100   bulk.declare_relation( closure_entity , entity_2_1 , 2 /*local_rel_id*/ );
00101 
00102   tmp[0] = & part_A_3 ;
00103   Entity& entity_3_1 = bulk.declare_entity(3 /*entity rank*/, 1 /*id*/, tmp);
00104   bulk.declare_relation( closure_entity , entity_3_1 , 3 /*local_rel_id*/ );
00105 
00106   // Ensure that the supersets of the buckets containing the entities we
00107   // just created are correct.
00108 
00109   entity_0_1.bucket().supersets( tmp );
00110   STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00111   STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00112   STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00113   STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00114 
00115   entity_1_1.bucket().supersets( tmp );
00116   STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00117   STKUNIT_ASSERT( entity_1_1.bucket().member(part_univ) );
00118   STKUNIT_ASSERT( entity_1_1.bucket().member(part_owns) );
00119   STKUNIT_ASSERT( entity_1_1.bucket().member(part_A_1) );
00120 
00121   entity_2_1.bucket().supersets( tmp );
00122   STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00123   STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
00124   STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
00125   STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
00126 
00127   entity_3_1.bucket().supersets( tmp );
00128   STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00129   STKUNIT_ASSERT( entity_3_1.bucket().member(part_univ) );
00130   STKUNIT_ASSERT( entity_3_1.bucket().member(part_owns) );
00131   STKUNIT_ASSERT( entity_3_1.bucket().member(part_A_3) );
00132 
00133   // Add entity_0_1 to the part it was already in
00134   {
00135     tmp.resize(1);
00136     tmp[0] = & part_A_0 ;
00137     bulk.change_entity_parts( entity_0_1 , tmp );
00138     entity_0_1.bucket().supersets( tmp );
00139     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00140     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00141     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00142     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00143   }
00144 
00145   // Add entity_0_1 to part_B_0
00146   {
00147     tmp.resize(1);
00148     tmp[0] = & part_B_0 ;
00149     bulk.change_entity_parts( entity_0_1 , tmp );
00150     entity_0_1.bucket().supersets( tmp );
00151     STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
00152     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00153     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00154     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00155     STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
00156   }
00157 
00158   // Remove entity_0_1 from the part it was just added to above
00159   {
00160     tmp.resize(1);
00161     tmp[0] = & part_B_0 ;
00162     bulk.change_entity_parts( entity_0_1 , PartVector() , tmp );
00163     entity_0_1.bucket().supersets( tmp );
00164     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00165     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00166     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00167     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00168   }
00169 
00170   // Add relation from entity_1_1 (which is in part_A_1) to
00171   // entity_0_1 (which is in part_A_0). After the relation
00172   // is added, there is an induced membership of entity_0_1
00173   // within part A_1.
00174   stk::mesh::RelationIdentifier test_rel_id = 0;
00175   {
00176     bulk.declare_relation( entity_1_1 , entity_0_1 , test_rel_id );
00177     entity_0_1.bucket().supersets( tmp );
00178     STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
00179     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00180     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00181     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00182     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_1) );
00183   }
00184 
00185   // Remove the relationship added in the step above and
00186   // demonstrate that the induced membership of entity_0_1
00187   // in part_A_1 is gone
00188   {
00189     bulk.destroy_relation( entity_1_1 , entity_0_1, test_rel_id );
00190     entity_0_1.bucket().supersets( tmp );
00191     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00192     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00193     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00194     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00195   }
00196 
00197   // Add entity_2_1 to part_B_2
00198   {
00199     tmp.resize(1);
00200     tmp[0] = & part_B_2 ;
00201     bulk.change_entity_parts( entity_2_1 , tmp );
00202     entity_2_1.bucket().supersets( tmp );
00203     STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
00204     STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
00205     STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
00206     STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
00207     STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
00208   }
00209 
00210   // Add relation from entity_2_1 (which is in part_A_2 and B_2) to
00211   // entity_0_1 (which is in part_A_0). After the relation
00212   // is added, there is an induced membership of entity_0_1
00213   // within entity_2_1's parts (A_2 and B_2) (and of course entity_0_1
00214   // is still in the parts it was already in).
00215   {
00216     bulk.declare_relation( entity_2_1 , entity_0_1 , test_rel_id );
00217     entity_0_1.bucket().supersets( tmp );
00218     STKUNIT_ASSERT_EQUAL( size_t(5) , tmp.size() );
00219     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00220     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00221     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00222     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_2) );
00223     STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_2) );
00224   }
00225 
00226   // Remove the relationship added in the step above and
00227   // demonstrate that the induced membership of entity_0_1
00228   // in parts A_2 and B_2 is gone.
00229   {
00230     bulk.destroy_relation( entity_2_1 , entity_0_1, test_rel_id );
00231     entity_0_1.bucket().supersets( tmp );
00232     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00233     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00234     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00235     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00236   }
00237 
00238   bulk.modification_end();
00239 
00240   //------------------------------
00241   // Now the parallel fun.  Existing entities should be shared
00242   // by all processes since they have the same identifiers.
00243   // They should also have the same parts.
00244 
00245   bool parallel = p_size > 1;
00246 
00247   // For parallel runs, the entities should be in the same parts
00248   // as they were before the modification end and they should
00249   // be in the shared part as well.
00250 
00251   entity_0_1.bucket().supersets( tmp );
00252   if ( entity_0_1.owner_rank() == p_rank ) {
00253     STKUNIT_ASSERT_EQUAL( size_t(parallel ? 4 : 3) , tmp.size() );
00254     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00255     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00256     if ( parallel )
00257       STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00258     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00259   }
00260   else {
00261     STKUNIT_ASSERT( parallel );
00262     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00263     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00264     STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00265     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00266   }
00267 
00268   entity_2_1.bucket().supersets( tmp );
00269   if ( entity_2_1.owner_rank() == p_rank ) {
00270     STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
00271     STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
00272     STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
00273     if ( parallel )
00274       STKUNIT_ASSERT( entity_2_1.bucket().member(part_shared) );
00275     STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
00276     STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
00277   }
00278   else {
00279     STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
00280     STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
00281     STKUNIT_ASSERT( entity_2_1.bucket().member(part_shared) );
00282     STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
00283     STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
00284   }
00285 
00286   if ( parallel ) {
00287     // If parallel, check that the entities are shared across all procs.
00288     STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_0_1.sharing().size() );
00289     STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_1_1.sharing().size() );
00290     STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_2_1.sharing().size() );
00291     STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_3_1.sharing().size() );
00292   }
00293 
00294   bulk.modification_begin();
00295 
00296   // Add entity_0_1 to a new part on the owning process
00297 
00298   int ok_to_modify = entity_0_1.owner_rank() == p_rank ;
00299 
00300   try {
00301     tmp.resize(1);
00302     tmp[0] = & part_B_0 ;
00303     bulk.change_entity_parts( entity_0_1 , tmp );
00304     STKUNIT_ASSERT( ok_to_modify );
00305   }
00306   catch( const std::exception & x ) {
00307     STKUNIT_ASSERT( ! ok_to_modify );
00308   }
00309 
00310   // Check that entity_0_1 is in the new part on the owning
00311   // process, but not on other processes.
00312 
00313   entity_0_1.bucket().supersets( tmp );
00314   if ( entity_0_1.owner_rank() == p_rank ) {
00315     STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
00316     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00317     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00318     if ( parallel )
00319       STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00320     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00321     STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
00322   }
00323   else {
00324     STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
00325     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00326     STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00327     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00328   }
00329 
00330   bulk.modification_end();
00331 
00332   // Now that modification_end has been called, entity_0_1 should
00333   // be in the new part (B_0) on all processes.
00334 
00335   entity_0_1.bucket().supersets( tmp );
00336   if ( entity_0_1.owner_rank() == p_rank ) {
00337     STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
00338     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00339     STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
00340     if ( parallel )
00341       STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00342     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00343     STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
00344   }
00345   else {
00346     STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
00347     STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
00348     STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
00349     STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
00350     STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
00351   }
00352 }
00353 
00354 //----------------------------------------------------------------------
00355 //----------------------------------------------------------------------
00356 
00357 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, testChangeParts_ringmesh)
00358 {
00359   // This unit test tests part operations and verifies operations
00360   // by looking at bucket supersets. We use RingMesh for a slightly
00361   // more realistic test than the test above but it's a bit harder
00362   // to read.
00363 
00364   stk::ParallelMachine pm = MPI_COMM_WORLD;
00365   MPI_Barrier( pm );
00366 
00367   const unsigned nPerProc   = 10;
00368   const unsigned p_rank     = stk::parallel_machine_rank( pm );
00369   const unsigned p_size     = stk::parallel_machine_size( pm );
00370   const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
00371   const unsigned nLocalEdge = nPerProc ;
00372   
00373   // Create the ring mesh
00374 
00375   RingFixture ring_mesh( pm , nPerProc , true /* generate parts */ );
00376   ring_mesh.m_meta_data.commit();
00377   BulkData& bulk = ring_mesh.m_bulk_data;
00378 
00379   bulk.modification_begin();
00380   ring_mesh.generate_mesh( );
00381   STKUNIT_ASSERT(stk::unit_test::modification_end_wrapper(bulk,
00382                                                           false /* no aura */));
00383 
00384   bulk.modification_begin();
00385   ring_mesh.fixup_node_ownership();
00386   STKUNIT_ASSERT(stk::unit_test::modification_end_wrapper(bulk,
00387                                                           false /* no aura */));
00388 
00389   Part & part_owns = ring_mesh.m_meta_data.locally_owned_part();
00390   Part & part_univ = ring_mesh.m_meta_data.universal_part();
00391 
00392   // Check that local edges are in the expected parts. Note that the
00393   // RingMesh puts each edge in its own part.
00394   for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) {
00395     const unsigned n = i + nPerProc * p_rank ;
00396     Entity * const edge = bulk.get_entity( 1 /*entity rank*/,
00397                                            ring_mesh.m_edge_ids[n] );
00398     STKUNIT_ASSERT( edge != NULL );
00399     STKUNIT_ASSERT( edge->bucket().member( part_univ ) );
00400     STKUNIT_ASSERT( edge->bucket().member( part_owns ) );
00401     STKUNIT_ASSERT( edge->bucket().member( * ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ] ) );
00402   }
00403 
00404   // Check that local nodes are in the expected parts. Note that the relations
00405   // that nodes have to edges should cause induced membership of the node
00406   // in the parts of both edges it touches.
00407   for ( unsigned i = 0 ; i < nLocalNode ; ++i ) {
00408     const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size();
00409     const unsigned e0 = n ;
00410     const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size();
00411     const unsigned ns = ring_mesh.m_edge_parts.size();
00412     const unsigned n0 = e0 % ns ;
00413     const unsigned n1 = e1 % ns ;
00414     Part * const epart_0 = ring_mesh.m_edge_parts[ n0 < n1 ? n0 : n1 ];
00415     Part * const epart_1 = ring_mesh.m_edge_parts[ n0 < n1 ? n1 : n0 ];
00416 
00417     Entity * const node = bulk.get_entity( 0 , ring_mesh.m_node_ids[n] );
00418     STKUNIT_ASSERT( node != NULL );
00419     if ( node->owner_rank() == p_rank ) {
00420       STKUNIT_ASSERT( node->bucket().member( part_univ ) );
00421       STKUNIT_ASSERT( node->bucket().member( part_owns ) );
00422       STKUNIT_ASSERT( node->bucket().member( *epart_0 ) );
00423       STKUNIT_ASSERT( node->bucket().member( *epart_1 ) );
00424     }
00425     else {
00426       STKUNIT_ASSERT( node->bucket().member( part_univ ) );
00427       STKUNIT_ASSERT( ! node->bucket().member( part_owns ) );
00428       STKUNIT_ASSERT( node->bucket().member( * epart_0 ) );
00429       STKUNIT_ASSERT( node->bucket().member( * epart_1 ) );
00430     }
00431   }
00432 
00433   bulk.modification_begin();
00434 
00435   // On rank 0, change all locally owned edges to the extra-part then check
00436   // for correct part membership
00437   if ( 0 == p_rank ) {
00438     for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) {
00439       const unsigned n = i + nPerProc * p_rank ;
00440 
00441       PartVector add(1); add[0] = & ring_mesh.m_edge_part_extra ;
00442       PartVector rem(1); rem[0] = ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ];
00443 
00444       Entity * const edge = bulk.get_entity( 1 , ring_mesh.m_edge_ids[n] );
00445       bulk.change_entity_parts( *edge , add , rem );
00446       STKUNIT_ASSERT( edge->bucket().member( part_univ ) );
00447       STKUNIT_ASSERT( edge->bucket().member( part_owns ) );
00448       STKUNIT_ASSERT( edge->bucket().member(ring_mesh.m_edge_part_extra ) );
00449     }
00450   }
00451 
00452   bulk.modification_end();
00453 
00454   // Modification end has been called, check that the part changes made
00455   // in the previous step are reflected across the other procs.
00456   for ( unsigned i = 0 ; i < nLocalNode ; ++i ) {
00457     const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size();
00458     const unsigned e0 = n ;
00459     const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size();
00460     const unsigned ns = ring_mesh.m_edge_parts.size();
00461     const unsigned n0 = e0 % ns ;
00462     const unsigned n1 = e1 % ns ;
00463     Part * ep_0 = e0 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n0] ;
00464     Part * ep_1 = e1 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n1] ;
00465 
00466     Part * epart_0 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_0 : ep_1 ;
00467     Part * epart_1 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_1 : ep_0 ;
00468 
00469     Entity * const node = bulk.get_entity( 0 , ring_mesh.m_node_ids[n] );
00470     STKUNIT_ASSERT( node != NULL );
00471     if ( node->owner_rank() == p_rank ) {
00472       STKUNIT_ASSERT( node->bucket().member( part_owns ) );
00473     }
00474     else {
00475       STKUNIT_ASSERT( ! node->bucket().member( part_owns ) );
00476     }
00477 
00478     STKUNIT_ASSERT( node->bucket().member( part_univ ) );
00479     STKUNIT_ASSERT( node->bucket().member( *epart_0 ) );
00480     STKUNIT_ASSERT( node->bucket().member( *epart_1 ) );
00481   }
00482 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines