10 #include <stk_util/parallel/Parallel.hpp> 11 #include <stk_util/parallel/ParallelReduce.hpp> 12 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 14 #include <stk_mesh/base/Types.hpp> 15 #include <stk_mesh/base/MetaData.hpp> 16 #include <stk_mesh/base/BulkData.hpp> 17 #include <stk_mesh/base/FieldData.hpp> 19 #include <stk_mesh/fem/CoordinateSystems.hpp> 20 #include <stk_mesh/fem/FEMMetaData.hpp> 21 #include <stk_mesh/fem/FEMHelpers.hpp> 26 #include <stk_rebalance_utils/RebalanceUtils.hpp> 29 static const size_t NODE_RANK = stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
34 static const int spatial_dimension = 2;
36 enum { nx = 2, ny = 2 };
42 enum BALANCE_TEST_STEP
56 void set_balance_step(BALANCE_TEST_STEP step)
59 void set_mesh_info (
const std::vector<stk_classic::mesh::Entity *> &mesh_entities,
62 { total_number_entities_ = mesh_entities.size(); }
65 {
return total_number_entities_; }
68 { RebalancingNeeded = (m_bulk_data.parallel_size() > 1); }
77 unsigned total_number_entities_;
80 BALANCE_TEST_STEP m_step;
86 const unsigned p_size = m_bulk_data.parallel_size();
87 const unsigned p_rank = m_bulk_data.parallel_rank();
88 const stk_classic::mesh::EntityRank element_rank = m_fem_meta.element_rank();
90 new_partition.clear();
98 const unsigned nnx = nx + 1 ;
99 const unsigned nny = ny + 1 ;
100 for (
unsigned iy = nny / 2 ; iy < nny ; ++iy ) {
101 for (
unsigned ix = 0 ; ix < nnx ; ++ix ) {
102 stk_classic::mesh::EntityId
id = 1 + ix + iy * nnx ;
103 unsigned proc = ix < nx/2 ? 1 : 2;
105 new_partition.push_back( tmp );
108 for (
unsigned iy = ny / 2 ; iy < ny ; ++iy ) {
109 for (
unsigned ix = 0 ; ix < nx ; ++ix ) {
110 stk_classic::mesh::EntityId
id = 1 + ix + iy * nx ;
111 unsigned proc = ix < nx/2 ? 1 : 2;
113 new_partition.push_back( tmp );
119 const unsigned nnx = nx + 1 ;
120 const unsigned nny = ny + 1 ;
121 for (
unsigned iy = nny / 2 ; iy < nny ; ++iy ) {
122 for (
unsigned ix = 0 ; ix < nnx ; ++ix ) {
123 stk_classic::mesh::EntityId
id = 1 + ix + iy * nnx ;
125 new_partition.push_back( tmp );
128 for (
unsigned iy = ny / 2 ; iy < ny ; ++iy ) {
129 for (
unsigned ix = 0 ; ix < nx ; ++ix ) {
130 stk_classic::mesh::EntityId
id = 1 + ix + iy * nx ;
132 new_partition.push_back( tmp );
139 else if( SECOND == m_step )
142 const unsigned nnx = nx + 1 ;
143 const unsigned nny = ny + 1 ;
144 for (
unsigned iy = 0 ; iy < nny / 2 ; ++iy ) {
145 for (
unsigned ix = 0 ; ix < nnx ; ++ix ) {
146 stk_classic::mesh::EntityId
id = 1 + ix + iy * nnx ;
148 new_partition.push_back( tmp );
151 for (
unsigned iy = 0 ; iy < ny / 2 ; ++iy ) {
152 for (
unsigned ix = 0 ; ix < nx ; ++ix ) {
153 stk_classic::mesh::EntityId
id = 1 + ix + iy * nx ;
155 new_partition.push_back( tmp );
161 else if( THIRD == m_step )
164 new_partition.clear();
167 const unsigned nnx = nx + 1 ;
168 const unsigned nny = ny + 1 ;
169 for (
unsigned iy = nny / 2 ; iy < nny ; ++iy ) {
170 for (
unsigned ix = nx / 2 ; ix < nnx ; ++ix ) {
171 stk_classic::mesh::EntityId
id = 1 + ix + iy * nnx ;
174 new_partition.push_back( tmp );
177 for (
unsigned iy = ny / 2 ; iy < ny ; ++iy ) {
178 for (
unsigned ix = nx / 2 ; ix < nx ; ++ix ) {
179 stk_classic::mesh::EntityId
id = 1 + ix + iy * nx ;
182 new_partition.push_back( tmp );
194 STKUNIT_UNIT_TEST(UnitTestRebalanceSimple, testUnit)
202 unsigned spatial_dimension = 2;
204 fem_meta.
FEM_initialize(spatial_dimension, stk_classic::mesh::fem::entity_rank_names(spatial_dimension) );
207 const stk_classic::mesh::EntityRank element_rank = fem_meta.
element_rank();
208 stk_classic::mesh::fem::CellTopology quad_top(shards::getCellTopologyData<shards::Quadrilateral<4> >());
218 const unsigned p_size = bulk_data.parallel_size();
219 const unsigned p_rank = bulk_data.parallel_rank();
222 bulk_data.modification_begin();
225 const unsigned nnx = nx + 1 ;
226 for (
unsigned iy = 0 ; iy < ny ; ++iy ) {
227 for (
unsigned ix = 0 ; ix < nx ; ++ix ) {
228 stk_classic::mesh::EntityId elem = 1 + ix + iy * nx ;
229 stk_classic::mesh::EntityId nodes[4] ;
230 nodes[0] = 1 + ix + iy * nnx ;
231 nodes[1] = 2 + ix + iy * nnx ;
232 nodes[2] = 2 + ix + ( iy + 1 ) * nnx ;
233 nodes[3] = 1 + ix + ( iy + 1 ) * nnx ;
241 for (
unsigned iy = 0 ; iy < ny ; ++iy ) {
242 for (
unsigned ix = 0 ; ix < nx ; ++ix ) {
243 stk_classic::mesh::EntityId elem = 1 + ix + iy * nx ;
254 STKUNIT_ASSERT( ! bulk_data.buckets( NODE_RANK ).empty() );
255 STKUNIT_ASSERT( ! bulk_data.buckets( element_rank ).empty() );
258 STKUNIT_ASSERT( bulk_data.buckets( NODE_RANK ).empty() );
259 STKUNIT_ASSERT( bulk_data.buckets( element_rank ).empty() );
262 bulk_data.modification_end();
265 MockPartition partition(fem_meta, bulk_data);
268 partition.set_balance_step(MockPartition::FIRST);
270 bool do_rebal = 1.5 < stk_classic::rebalance::check_balance(bulk_data, &weight_field, element_rank);
277 for (
unsigned iy = 0 ; iy < ny ; ++iy )
279 stk_classic::mesh::EntityId elem = 1 + iy * nx ;
289 partition.set_balance_step(MockPartition::SECOND);
292 partition.set_balance_step(MockPartition::THIRD);
298 STKUNIT_ASSERT( ! bulk_data.buckets( NODE_RANK ).empty() );
299 STKUNIT_ASSERT( ! bulk_data.buckets( element_rank ).empty() );
302 STKUNIT_ASSERT( bulk_data.buckets( NODE_RANK ).empty() );
303 STKUNIT_ASSERT( bulk_data.buckets( element_rank ).empty() );
bool rebalance(mesh::BulkData &bulk_data, const mesh::Selector &selector, const VectorField *coord_ref, const ScalarField *elem_weight_ref, Partition &partition, const stk_classic::mesh::EntityRank rank=stk_classic::mesh::InvalidEntityRank)
Rebalance with a Partition object.
virtual int get_new_partition(stk_classic::mesh::EntityProcVec &new_partition)=0
Perform communication to create new partition.
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
Partition(stk_classic::ParallelMachine comm)
Constructors.
Entity & declare_element(BulkData &mesh, Part &part, const EntityId elem_id, const EntityId node_id[])
Declare an element member of a Part with a CellTopology and nodes conformal to that topology...
ParallelMachine parallel() const
Return the parallel communicator for this partition entity.
This is a class for selecting buckets based on a set of meshparts and set logic.
field_type & put_field(field_type &field, EntityRank entity_rank, const Part &part, const void *init_value=NULL)
Declare a field to exist for a given entity type and Part.
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
An application-defined subset of a problem domain.
Manager for an integrated collection of entities, entity relations, and buckets of field data...
virtual bool partition_dependents_needed() const =0
Query whether element dependents need to be rebalanced outside this Partition.
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Initialized with a list of mesh entities unique to each processor.
virtual void set_mesh_info(const std::vector< mesh::Entity *> &mesh_entities, const VectorField *nodal_coord_ref, const ScalarField *elem_weight_ref=NULL)=0
Define mesh entities to balance.
virtual unsigned num_elems() const =0
Return the total number of mesh entities in all lists.
For partitioning of mesh entities over a processing grid.
Static functions for dynamic load balancing.
virtual void determine_new_partition(bool &RebalancingNeeded)=0
determine New Partition.