structured_partitioner.h
Go to the documentation of this file.
1 /*
2 This file is part of the Ristra Wonton project.
3 Please see the license file at the root of this repository, or at:
4  https://github.com/laristra/wonton/blob/master/LICENSE
5 */
6 
7 #ifndef WONTON_STRUCTURED_PARTITIONER_H
8 #define WONTON_STRUCTURED_PARTITIONER_H_
9 
10 
12 
13 namespace Wonton {
14 
15 
22 
23 template<int D>
24 std::vector<std::array<std::array<int64_t,D>,2>>
25 structured_partitioner(int N, std::array<int64_t, D> ncells, int d=D, int seed=0) {
26 
27  // factor the number of processors/partitions into D, nearly equal numbers
28  std::vector<int> nbins = equifactor(N, d, seed);
29  for (int i = d; i < D; i++)
30  nbins.push_back(1);
31 
32  // compute num cells in each bin along each axis
33  std::array<std::vector<int64_t>, D> bincounts;
34 
35  for (int i = 0; i < D; i++) {
36  int nperbin = ncells[i]/nbins[i];
37  int remainder = ncells[i]%nbins[i];
38 
39  // spread the cells as evenly as possible
40  bincounts[i].assign(nbins[i], nperbin);
41 
42  // distribute the remainder as best as possible
43  for (int j = 0; j < remainder; j++)
44  bincounts[i][j]++;
45  }
46 
47  // cell offsets of each bin along each axis
48  std::array<std::vector<int64_t>, D> binoffsets;
49 
50  for (int i = 0; i < D; i++) {
51  binoffsets[i].resize(nbins[i]+1);
52  binoffsets[i][0] = 0;
53 
54  for (int j = 1; j < nbins[i]+1; j++)
55  binoffsets[i][j] = binoffsets[i][j-1] + bincounts[i][j-1];
56  }
57 
58  std::vector<std::array<std::array<int64_t,D>,2>> ilimits(N);
59 
60  // One could make this a recursive function but it becomes less readable
61  if (D == 1) {
62  for (int n = 0; n < N; n++) {
63  ilimits[n][0][0] = binoffsets[0][n];
64  ilimits[n][1][0] = binoffsets[0][n+1];
65  }
66  } else if (D == 2) {
67  for (int i = 0; i < nbins[0]; i++) {
68  for (int j = 0; j < nbins[1]; j++) {
69  int n = i*nbins[1]+j;
70  ilimits[n][0][0] = binoffsets[0][i];
71  ilimits[n][0][1] = binoffsets[1][j];
72  ilimits[n][1][0] = binoffsets[0][i+1];
73  ilimits[n][1][1] = binoffsets[1][j+1];
74  }
75  }
76  } else if (D == 3) {
77  for (int i = 0; i < nbins[0]; i++) {
78  int n1 = i*nbins[1];
79  for (int j = 0; j < nbins[1]; j++) {
80  int n2 = (n1 + j)*nbins[2];
81  for (int k = 0; k < nbins[2]; k++) {
82  int n = n2 + k;
83  ilimits[n][0][0] = binoffsets[0][i];
84  ilimits[n][0][1] = binoffsets[1][j];
85  ilimits[n][0][2] = binoffsets[2][k];
86  ilimits[n][1][0] = binoffsets[0][i+1];
87  ilimits[n][1][1] = binoffsets[1][j+1];
88  ilimits[n][1][2] = binoffsets[2][k+1];
89  }
90  }
91  }
92  }
93 
94  return ilimits;
95 }
96 
97 } // namespace Wonton
98 
99 #endif
Factorize a number N into D equal (or nearly equal) factors.
Definition: adaptive_refinement_mesh.h:31
std::vector< std::array< std::array< int64_t, D >, 2 > > structured_partitioner(int N, std::array< int64_t, D > ncells, int d=D, int seed=0)
Partition a D-dimensional structured grid along d axes into N subdomains.
Definition: structured_partitioner.h:25