35 #include "DistributedBoxCollection.hpp" 38 #include "Warnings.hpp" 41 template<
unsigned DIM>
44 template<
unsigned DIM>
46 : mBoxWidth(boxWidth),
47 mIsPeriodicInX(isPeriodicInX),
48 mAreLocalBoxesSet(false),
49 mCalculateNodeNeighbours(true)
58 for (
unsigned i=0; i<DIM; i++)
60 double r = fmod((domainSize[2*i+1]-domainSize[2*i]), boxWidth);
63 domainSize[2*i+1] += boxWidth - r;
72 for (
unsigned i=0; i<DIM; i++)
85 WARNING(
"There are more processes than convenient for the domain/mesh/box size. The domain size has been swollen.")
95 for (
unsigned dim=0; dim<DIM; dim++)
108 mBoxes.resize(num_local_boxes);
112 template<
unsigned DIM>
118 template<
unsigned DIM>
121 for (
unsigned i=0; i<
mBoxes.size(); i++)
131 template<
unsigned DIM>
146 unsigned global_index = hi * mNumBoxesInAFace + i;
148 mHalosRight.push_back(global_index - mNumBoxesInAFace);
160 unsigned global_index = (lo - 1) * mNumBoxesInAFace + i;
163 mHalosLeft.push_back(global_index + mNumBoxesInAFace);
168 template<
unsigned DIM>
195 template<
unsigned DIM>
201 template<
unsigned DIM>
207 template<
unsigned DIM>
216 template<
unsigned DIM>
224 template<
unsigned DIM>
228 unsigned global_index;
234 global_index = gridIndices(0);
239 global_index = gridIndices(0) +
245 global_index = gridIndices(0) +
258 template<
unsigned DIM>
266 template<
unsigned DIM>
270 for (
unsigned i=0; i<DIM; i++)
274 EXCEPTION(
"The point provided is outside all of the boxes");
279 c_vector<unsigned, DIM> containing_box_indices = scalar_vector<unsigned>(DIM, 0u);
280 for (
unsigned i=0; i<DIM; i++)
285 containing_box_indices[i]++;
291 unsigned containing_box_index = 0;
292 for (
unsigned i=0; i<DIM; i++)
295 for (
unsigned j=0; j<i; j++)
299 containing_box_index += temp*containing_box_indices[i];
303 assert(containing_box_index <
mNumBoxes);
305 return containing_box_index;
308 template<
unsigned DIM>
311 c_vector<unsigned, DIM> grid_indices;
317 grid_indices(0) = globalIndex;
323 grid_indices(0) = globalIndex % num_x;
324 grid_indices(1) = (globalIndex - grid_indices(0)) / num_x;
331 grid_indices(0) = globalIndex % num_x;
332 grid_indices(1) = (globalIndex % num_xy - grid_indices(0)) / num_x;
333 grid_indices(2) = globalIndex / num_xy;
345 template<
unsigned DIM>
358 template<
unsigned DIM>
368 template<
unsigned DIM>
374 template<
unsigned DIM>
380 template<
unsigned DIM>
386 template<
unsigned DIM>
392 template<
unsigned DIM>
398 template<
unsigned DIM>
404 template<
unsigned DIM>
410 template<
unsigned DIM>
419 int new_rows = localDistribution.size();
424 unsigned rows_on_left_process = 0;
425 std::vector<int> node_distr_on_left_process;
427 unsigned num_local_rows = localDistribution.size();
429 MPI_Send(&num_local_rows, 1, MPI_UNSIGNED, proc_right, 123, PETSC_COMM_WORLD);
430 MPI_Recv(&rows_on_left_process, 1, MPI_UNSIGNED, proc_left, 123, PETSC_COMM_WORLD, &status);
432 node_distr_on_left_process.resize(rows_on_left_process > 0 ? rows_on_left_process : 1);
434 MPI_Send(&localDistribution[0], num_local_rows, MPI_INT, proc_right, 123, PETSC_COMM_WORLD);
435 MPI_Recv(&node_distr_on_left_process[0], rows_on_left_process, MPI_INT, proc_left, 123, PETSC_COMM_WORLD, &status);
441 for (
unsigned i=0; i<localDistribution.size(); i++)
443 local_load += localDistribution[i];
445 int load_on_left_proc = 0;
446 for (
unsigned i=0; i<node_distr_on_left_process.size(); i++)
448 load_on_left_proc += node_distr_on_left_process[i];
455 int local_to_left_sq = (local_load - load_on_left_proc) * (local_load - load_on_left_proc);
456 int delta_left = ( (local_load + node_distr_on_left_process[node_distr_on_left_process.size() - 1]) - (load_on_left_proc - node_distr_on_left_process[node_distr_on_left_process.size() - 1]) );
457 delta_left = delta_left*delta_left - local_to_left_sq;
459 int delta_right = ( (local_load - localDistribution[0]) - (load_on_left_proc + localDistribution[0]));
460 delta_right = delta_right*delta_right - local_to_left_sq;
463 int local_change = 0;
464 bool move_left = (!(delta_left > 0) && (node_distr_on_left_process.size() > 1));
470 bool move_right = !(delta_right > 0) && (localDistribution.size() > 2);
476 if (move_left && move_right)
478 local_change = (fabs((
double)delta_right) > fabs((
double)delta_left)) ? -1 : 1;
482 new_rows += local_change;
485 MPI_Send(&local_change, 1, MPI_INT, proc_left, 123, PETSC_COMM_WORLD);
489 int remote_change = 0;
490 MPI_Recv(&remote_change, 1, MPI_INT, proc_right, 123, PETSC_COMM_WORLD, &status);
493 new_rows -= remote_change;
498 template<
unsigned DIM>
503 EXCEPTION(
"Local Boxes Are Already Set");
517 std::set<unsigned> local_boxes;
520 local_boxes.insert(global_index);
524 bool left = (global_index == 0);
530 local_boxes.insert(global_index+1);
533 if (proc_left && !left)
535 local_boxes.insert(global_index-1);
549 std::set<unsigned> local_boxes;
559 local_boxes.insert(global_index);
562 if (!bottom && bottom_proc)
597 local_boxes.insert(global_index + 1);
606 local_boxes.insert(global_index + 1);
623 std::set<unsigned> local_boxes;
630 bool front = (global_index < num_boxes_xy);
636 local_boxes.insert(global_index);
656 local_boxes.insert( global_index - num_boxes_xy + 1);
662 local_boxes.insert( global_index - num_boxes_xy );
666 local_boxes.insert( global_index - num_boxes_xy - 1);
686 local_boxes.insert( global_index + 1);
706 local_boxes.insert(global_index + num_boxes_xy);
710 local_boxes.insert(global_index + num_boxes_xy + 1);
729 local_boxes.insert(global_index + num_boxes_xy - 1);
758 template<
unsigned DIM>
768 std::set<unsigned> local_boxes;
770 local_boxes.insert(i);
775 local_boxes.insert(i-1);
779 local_boxes.insert(i+1);
793 std::vector<bool> is_xmin(N*M);
794 std::vector<bool> is_xmax(N*M);
795 std::vector<bool> is_ymin(N*M);
796 std::vector<bool> is_ymax(N*M);
798 for (
unsigned i=0; i<M*N; i++)
800 is_xmin[i] = (i%M==0);
801 is_xmax[i] = ((i+1)%M==0);
802 is_ymin[i] = (i%(M*N)<M);
803 is_ymax[i] = (i%(M*N)>=(N-1)*M);
808 std::set<unsigned> local_boxes;
810 local_boxes.insert(i);
815 local_boxes.insert(i-1);
821 local_boxes.insert(i+M-1);
828 local_boxes.insert(i+1);
834 local_boxes.insert(i-M+1);
841 local_boxes.insert(i-M);
847 local_boxes.insert(i+M);
852 if ((!is_xmin[i]) && (!is_ymin[i]))
854 local_boxes.insert(i-1-M);
856 if ((!is_xmin[i]) && (!is_ymax[i]))
858 local_boxes.insert(i-1+M);
860 if ((!is_xmax[i]) && (!is_ymin[i]))
862 local_boxes.insert(i+1-M);
864 if ((!is_xmax[i]) && (!is_ymax[i]))
866 local_boxes.insert(i+1+M);
872 if ((is_xmin[i]) && (!is_ymin[i]))
874 local_boxes.insert(i-1);
876 if ((is_xmin[i]) && (!is_ymax[i]))
878 local_boxes.insert(i-1+2*M);
880 if ((is_xmax[i]) && (!is_ymin[i]))
882 local_boxes.insert(i+1-2*M);
884 if ((is_xmax[i]) && (!is_ymax[i]))
886 local_boxes.insert(i+1);
902 std::vector<bool> is_xmin(N*M*P);
903 std::vector<bool> is_xmax(N*M*P);
904 std::vector<bool> is_ymin(N*M*P);
905 std::vector<bool> is_ymax(N*M*P);
906 std::vector<bool> is_zmin(N*M*P);
907 std::vector<bool> is_zmax(N*M*P);
909 for (
unsigned i=0; i<M*N*P; i++)
911 is_xmin[i] = (i%M==0);
912 is_xmax[i] = ((i+1)%M==0);
913 is_ymin[i] = (i%(M*N)<M);
914 is_ymax[i] = (i%(M*N)>=(N-1)*M);
915 is_zmin[i] = (i<M*N);
916 is_zmax[i] = (i>=M*N*(P-1));
921 std::set<unsigned> local_boxes;
924 local_boxes.insert(i);
931 local_boxes.insert(i-1);
936 local_boxes.insert(i-1-M);
941 local_boxes.insert(i-1+M);
946 local_boxes.insert(i-1-M*N);
951 local_boxes.insert(i-1+M*N);
958 local_boxes.insert(i+1);
963 local_boxes.insert(i+1-M);
968 local_boxes.insert(i+1+M);
973 local_boxes.insert(i+1-M*N);
978 local_boxes.insert(i+1+M*N);
985 local_boxes.insert(i-M);
990 local_boxes.insert(i-M-M*N);
995 local_boxes.insert(i-M+M*N);
1002 local_boxes.insert(i+M);
1007 local_boxes.insert(i+M-M*N);
1012 local_boxes.insert(i+M+M*N);
1019 local_boxes.insert(i-N*M);
1025 local_boxes.insert(i+N*M);
1030 if ((!is_xmin[i]) && (!is_ymin[i]) && (!is_zmin[i]))
1032 local_boxes.insert(i-1-M-M*N);
1035 if ((!is_xmin[i]) && (!is_ymin[i]) && (!is_zmax[i]))
1037 local_boxes.insert(i-1-M+M*N);
1040 if ((!is_xmin[i]) && (!is_ymax[i]) && (!is_zmin[i]))
1042 local_boxes.insert(i-1+M-M*N);
1045 if ((!is_xmin[i]) && (!is_ymax[i]) && (!is_zmax[i]))
1047 local_boxes.insert(i-1+M+M*N);
1050 if ((!is_xmax[i]) && (!is_ymin[i]) && (!is_zmin[i]))
1052 local_boxes.insert(i+1-M-M*N);
1055 if ((!is_xmax[i]) && (!is_ymin[i]) && (!is_zmax[i]))
1057 local_boxes.insert(i+1-M+M*N);
1060 if ((!is_xmax[i]) && (!is_ymax[i]) && (!is_zmin[i]))
1062 local_boxes.insert(i+1+M-M*N);
1065 if ((!is_xmax[i]) && (!is_ymax[i]) && (!is_zmax[i]))
1067 local_boxes.insert(i+1+M+M*N);
1079 template<
unsigned DIM>
1087 template<
unsigned DIM>
1095 template<
unsigned DIM>
1103 template<
unsigned DIM>
1111 containing_process++;
1115 containing_process--;
1118 return containing_process;
1121 template<
unsigned DIM>
1127 template<
unsigned DIM>
1133 template<
unsigned DIM>
1139 template<
unsigned DIM>
1145 for (
unsigned i=0; i<rNodes.size(); i++)
1153 rNodes[i]->ClearNeighbours();
1164 for (
unsigned i = 0; i < rNodes.size(); i++)
1172 rNodes[i]->RemoveDuplicateNeighbours();
1178 template<
unsigned DIM>
1184 for (
unsigned i=0; i<rNodes.size(); i++)
1192 rNodes[i]->ClearNeighbours();
1193 rNodes[i]->SetNeighboursSetUp(
false);
1207 for (
unsigned i = 0; i < rNodes.size(); i++)
1215 rNodes[i]->RemoveDuplicateNeighbours();
1216 rNodes[i]->SetNeighboursSetUp(
true);
1222 template<
unsigned DIM>
1235 for (
unsigned i = 0; i < rNodes.size(); i++)
1243 rNodes[i]->RemoveDuplicateNeighbours();
1244 rNodes[i]->SetNeighboursSetUp(
true);
1250 template<
unsigned DIM>
1261 const std::set<unsigned>& local_boxes_indices =
rGetLocalBoxes(boxIndex);
1264 for (std::set<unsigned>::iterator box_iter = local_boxes_indices.begin();
1265 box_iter != local_boxes_indices.end();
1279 assert(p_neighbour_box);
1282 std::set< Node<DIM>* >& r_contained_neighbour_nodes = p_neighbour_box->
rGetNodesContained();
1285 for (
typename std::set<
Node<DIM>*>::iterator neighbour_node_iter = r_contained_neighbour_nodes.begin();
1286 neighbour_node_iter != r_contained_neighbour_nodes.end();
1287 ++neighbour_node_iter)
1290 unsigned other_node_index = (*neighbour_node_iter)->GetIndex();
1293 for (
typename std::set<
Node<DIM>*>::iterator node_iter = r_contained_nodes.begin();
1294 node_iter != r_contained_nodes.end();
1297 unsigned node_index = (*node_iter)->GetIndex();
1300 if (*box_iter != boxIndex || other_node_index > node_index)
1302 rNodePairs.push_back(std::pair<
Node<DIM>*,
Node<DIM>*>((*node_iter), (*neighbour_node_iter)));
1305 (*node_iter)->AddNeighbour(other_node_index);
1306 (*neighbour_node_iter)->AddNeighbour(node_index);
1315 template<
unsigned DIM>
1325 cell_numbers[location_in_vector] +=
mBoxes[local_index].rGetNodesContained().size();
1328 return cell_numbers;
std::vector< Box< DIM > > mBoxes
bool IsBoxOwned(unsigned globalIndex)
std::vector< unsigned > & rGetHaloNodesRight()
std::vector< unsigned > mHalosRight
unsigned CalculateContainingBox(Node< DIM > *pNode)
unsigned GetNumLocalBoxes()
void CalculateInteriorNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)
~DistributedBoxCollection()
bool IsInteriorBox(unsigned globalIndex)
c_vector< double, 2 *DIM > rGetDomainSize() const
c_vector< double, 2 *DIM > mDomainSize
std::vector< std::set< unsigned > > mLocalBoxes
#define EXCEPTION(message)
std::vector< unsigned > mHalosLeft
void SetCalculateNodeNeighbours(bool calculateNodeNeighbours)
unsigned CalculateGlobalIndex(c_vector< unsigned, DIM > gridIndices)
void CalculateBoundaryNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)
std::set< Node< DIM > * > & rGetNodesContained()
std::vector< Box< DIM > > mHaloBoxes
std::vector< int > CalculateNumberOfNodesInEachStrip()
unsigned GetProcessOwningNode(Node< DIM > *pNode)
bool GetIsPeriodicInX() const
unsigned GetNumLocalRows() const
std::set< unsigned > & rGetLocalBoxes(unsigned boxIndex)
void SetupLocalBoxesHalfOnly()
static const double msFudge
double GetBoxWidth() const
c_vector< unsigned, DIM > mNumBoxesEachDirection
std::vector< unsigned > & rGetHaloNodesLeft()
bool IsOwned(Node< DIM > *pNode)
unsigned GetNumRowsOfBoxes() const
DistributedBoxCollection(double boxWidth, c_vector< double, 2 *DIM > domainSize, bool isPeriodicInX=false, int localRows=PETSC_DECIDE)
std::vector< unsigned > mHaloNodesRight
void CalculateNodePairs(std::vector< Node< DIM > * > &rNodes, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)
std::map< unsigned, unsigned > mHaloBoxesMapping
int LoadBalance(std::vector< int > localDistribution)
bool mCalculateNodeNeighbours
const c_vector< double, SPACE_DIM > & rGetLocation() const
c_vector< unsigned, DIM > CalculateGridIndices(unsigned globalIndex)
bool IsHaloBox(unsigned globalIndex)
Box< DIM > & rGetHaloBox(unsigned boxIndex)
unsigned mNumBoxesInAFace
Box< DIM > & rGetBox(unsigned boxIndex)
bool GetAreLocalBoxesSet() const
std::vector< unsigned > mHaloNodesLeft
DistributedVectorFactory * mpDistributedBoxStackFactory
void SetupAllLocalBoxes()
void AddPairsFromBox(unsigned boxIndex, std::vector< std::pair< Node< DIM > *, Node< DIM > * > > &rNodePairs)