Chi-Tech
decompose_pxpy.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
5typedef std::pair<int,int> IntPair;
6typedef std::vector<double> DblVec;
7typedef std::vector<int> IntVec;
8
9#include "chi_runtime.h"
10#include "chi_log.h"
11
12//================================================== Define LBF-Calc funtion
13/**Makes a centroid based load balance factor calculation.
14 *
15 * \author Jan*/
16double chi_mesh::ComputeLBF(std::vector<Vector3>& points,
17 std::vector<double>& x_cuts,
18 std::vector<double>& y_cuts)
19{
20 std::vector<IntVec> balance_matrix(x_cuts.size()+1,
21 IntVec(y_cuts.size()+1,0));
22
23 size_t num_points = points.size();
24 size_t num_x_cuts = x_cuts.size();
25 size_t num_y_cuts = y_cuts.size();
26 for (size_t p=0; p<num_points; p++)
27 {
28 double xr = points[p].x;
29 double yr = points[p].y;
30
31
32 int ir = -1;
33 for (int i=0; i<num_x_cuts; i++)
34 {
35 if (xr <= x_cuts[i])
36 {ir = i; break;}
37 }
38 if (ir < 0)
39 ir = num_x_cuts;
40
41 int jr = -1;
42 for (int j=0; j<num_y_cuts; j++)
43 {
44 if (yr <= y_cuts[j])
45 {jr = j; break;}
46 }
47 if (jr < 0)
48 jr = num_y_cuts;
49
50 balance_matrix[ir][jr] += 1;
51 }
52
53 //Now find max and average
54 int max_points_per_bin = 0;
55 int bin_sum = 0;
56 for (int i=0; i<=num_x_cuts; i++)
57 {
58 for (int j=0; j<=num_y_cuts; j++)
59 {
60 bin_sum += balance_matrix[i][j];
61
62 if (balance_matrix[i][j] > max_points_per_bin)
63 max_points_per_bin = balance_matrix[i][j];
64 }//for j
65 }//for i
66 double average = bin_sum/(num_x_cuts+1)/(num_y_cuts+1);
67
68 return max_points_per_bin/average;
69}
70
71//###################################################################
72/** Decomposes a 2D surface mesh using the centroids in a Px-Py fashion.*/
74 int px, int py)
75{
76 //================================================== Collect centroids
77 size_t num_pfaces = smesh.GetPolygons().size();
78 std::vector<chi_mesh::Vector3> centroids(num_pfaces);
79 for (int pf=0; pf<num_pfaces; pf++)
80 centroids[pf] = smesh.GetPolygons()[pf]->face_centroid;
81
82
83 //================================================== Define sort operators
84 struct
85 {
86 bool operator()(chi_mesh::Vector3 a, chi_mesh::Vector3 b)
87 {
88 if (a.x < b.x)
89 {return true;}
90 else
91 {return false;}
92 }
93 }compare_x;
94
95 struct
96 {
97 bool operator()(chi_mesh::Vector3 a, chi_mesh::Vector3 b)
98 {
99 if (a.y < b.y)
100 {return true;}
101 else
102 {return false;}
103 }
104 }compare_y;
105
106
107
108 //================================================== Create sorts
109 std::vector<chi_mesh::Vector3> centroids_sortedx;
110 std::vector<chi_mesh::Vector3> centroids_sortedy;
111 std::copy(centroids.begin(), centroids.end(),
112 std::back_inserter(centroids_sortedx));
113
114
115 std::stable_sort(centroids_sortedx.begin(),
116 centroids_sortedx.end(),
117 compare_x);
118
119 std::vector<IntPair> x_bins(px);
120 std::vector<double> x_cuts(px-1);
121 std::vector<DblVec> y_cuts_per_x_bin(px,DblVec(py-1));
122
123 //================================================== Populate xbins
124 int dx = std::ceil(centroids.size()/(double)px);
125 for (int x=0; x<px; x++)
126 {
127 x_bins[x].first = x*dx;
128 x_bins[x].second = x*dx + dx - 1;
129
130 if (x == (px-1))
131 x_bins[x].second = centroids_sortedx.size()-1;
132 }
133
134 //================================================== Populate x-cuts
135 for (int x=0; x<(px-1); x++)
136 {
137 int up_bounds_x = x*dx + dx - 1;
138 double a = centroids_sortedx[up_bounds_x].x;
139 double b = centroids_sortedx[up_bounds_x+1].x;
140
141 x_cuts[x] = (b+a)/2.0;
142
143 Chi::log.Log()
144 << "X-cut" << x << " " << x_cuts[x];
145 }
146
147 //================================================== Balance according to each
148 // x-bin
149 double min_lbf = 1000.0; //Minimum load balance factor
150 int min_bin = 0;
151 for (int x=0; x<px; x++)
152 {
153 int bin_i = x_bins[x].first;
154 int bin_f = x_bins[x].second;
155
156 centroids_sortedy.clear();
157 for (int i=bin_i; i<=bin_f; i++)
158 centroids_sortedy.push_back(centroids_sortedx[i]);
159
160 std::stable_sort(centroids_sortedy.begin(),
161 centroids_sortedy.end(),
162 compare_y);
163
164 int dy = std::ceil(centroids_sortedy.size()/(double)py);
165 for (int y=0; y<(py-1); y++)
166 {
167 int up_bounds_y = y*dy + dy - 1;
168
169 double a = centroids_sortedy[up_bounds_y].y;
170 double b = centroids_sortedy[up_bounds_y+1].y;
171
172 y_cuts_per_x_bin[x][y] = (b+a)/2.0;
173 }
174 double lbf = ComputeLBF(centroids,x_cuts,y_cuts_per_x_bin[x]);
175
176 if (lbf < min_lbf)
177 {
178 min_lbf = lbf;
179 min_bin = x;
180 }
181 Chi::log.Log() << "Load balance factor: " << lbf;
182 }//for x
183
184 //================================================== Write y-cuts
185 for (int y=0; y<(py-1); y++)
186 {
187 Chi::log.Log()
188 << "Y-cut" << y << " " << y_cuts_per_x_bin[min_bin][y];
189 }
190
191}
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
const std::vector< chi_mesh::PolyFace * > & GetPolygons() const
std::vector< double > DblVec
std::vector< int > IntVec
std::pair< int, int > IntPair
double ComputeLBF(std::vector< Vector3 > &points, std::vector< double > &x_cuts, std::vector< double > &y_cuts)
void DecomposeSurfaceMeshPxPy(const SurfaceMesh &smesh, int Px, int Py)
double x
Element-0.
double y
Element-1.