source: inundation/parallel/pmesh_divide.py @ 1855

Last change on this file since 1855 was 1585, checked in by steve, 19 years ago

Better partitioning of meribula data set

File size: 8.9 KB
Line 
1#########################################################
2#
3#
4#  Read in a data file stored in the mg_cell data format.
5#
6#  mg_cell is a code written by Linda Stals for parallel
7# mulitgrid solver based on adaptive finite elements. The
8# reason this code is used is because it gives a grid
9# partition.
10#
11#  This is only intended as a temporary file, once an
12# automatic grid partitioner has been incorporated this
13# file will become redundant.
14#
15#  Authors: Linda Stals and Matthew Hardy, June 2005
16#
17#
18#########################################################
19
20
21from math import floor
22from Numeric import zeros, Float, Int
23
24#########################################################
25#
26# Read the nodes, triangles and boundary information from
27# given file
28#
29# *) The information in the file is stored using the
30# mg_cell format.
31#
32# *) See the documentation of the previous functions.
33#
34# -------------------------------------------------------
35#
36# *The information returned by this routine includes the
37# nodes, triangles, boundary edges and the number of
38# triangles to be assigned to each processor.
39#
40#########################################################
41
42def pmesh_divide_linda(f, Domain, n_x = 1, n_y = 1):
43
44    # read in the pmesh
45
46    domain = pmesh_to_domain_instance(f, Domain)
47
48    # find the bounding box
49    x_coord_min = domain.xy_extent[0]
50    x_coord_max = domain.xy_extent[2]
51    y_coord_min = domain.xy_extent[1]
52    y_coord_max = domain.xy_extent[3]
53
54    rect = domain.xy_extent
55
56    # find the size of each sub-box
57
58    x_div = (x_coord_max-x_coord_min)/n_x
59    y_div = (y_coord_max-y_coord_min)/n_y
60
61
62    # initialise the arrays
63
64    tri_list = []
65    triangles_per_proc = []
66    proc_sum = []
67    for i in range(n_x*n_y):
68        tri_list.append([])
69        triangles_per_proc.append([])
70        proc_sum.append([])
71        tri_list[i] = []
72
73    # subdivide the triangles depending on which sub-box they sit
74    # in (a triangle sits in the sub-box if its first vectex sits
75    # in that sub-box)
76
77    tri_index = {}
78    for i in range(len(domain.triangles)):
79        t = domain.triangles[i]
80
81        x_coord = domain.coordinates[t[0]][0]
82        bin_x = int(floor((x_coord-x_coord_min)/x_div))
83        if (bin_x == n_x):
84            bin_x = n_x-1
85
86        y_coord = domain.coordinates[t[0]][1]
87        bin_y = int(floor((y_coord-y_coord_min)/y_div))
88        if (bin_y == n_y):
89            bin_y = n_y-1
90
91        bin = bin_y*n_x + bin_x
92        tri_list[bin].append([t[0], t[1], t[2]])
93        tri_index[i] = ([bin, len(tri_list[bin])-1])
94
95    # find the number of triangles per processor and order the
96    # triangle list so that all of the triangles belonging to
97    # processor i are listed before those belonging to processor
98    # i+1
99
100    triangles = []
101    for i in range(n_x*n_y):
102        triangles_per_proc[i] = len(tri_list[i])
103        for t in tri_list[i]:
104            triangles.append(t)
105
106    # the boundary labels have to changed in accoradance with the
107    # new triangle ordering, proc_sum and tri_index help with this
108
109    proc_sum[0] = 0
110    for i in range(n_x*n_y-1):
111        proc_sum[i+1]=proc_sum[i]+triangles_per_proc[i]
112
113    # relabel the boundary elements to fit in with the new triangle
114    # ordering
115
116    boundary = {}
117    for b in domain.boundary:
118        t =  tri_index[b[0]]
119        boundary[proc_sum[t[0]]+t[1], b[1]] = domain.boundary[b]
120
121    # extract the node list
122
123    nodes = []
124    for n in domain.coordinates:
125        nodes.append([n[0], n[1]])
126
127    return nodes, triangles, boundary,  triangles_per_proc, rect
128
129def reorder(quantities, tri_index, proc_sum):
130
131    # find the number triangles
132
133    N = len(tri_index)
134
135    # temporary storage area
136
137    index = zeros(N, Int)
138    q_reord = {}
139
140    # find the new ordering of the triangles
141
142    for i in range(N):
143        bin = tri_index[i][0]
144        bin_off_set = tri_index[i][1]
145        index[i] = proc_sum[bin]+bin_off_set
146
147    # reorder each quantity according to the new ordering
148
149    for k in quantities:
150        q_reord[k] = zeros((N, 3), Float)
151        for i in range(N):
152            q_reord[k][index[i]]=quantities[k].vertex_values[i]
153
154    del index
155
156    return q_reord
157
158def pmesh_divide(domain, n_x = 1, n_y = 1):
159
160    # find the bounding box
161    x_coord_min = domain.xy_extent[0]
162    x_coord_max = domain.xy_extent[2]
163    y_coord_min = domain.xy_extent[1]
164    y_coord_max = domain.xy_extent[3]
165
166
167    # find the size of each sub-box
168
169    x_div = (x_coord_max-x_coord_min)/n_x
170    y_div = (y_coord_max-y_coord_min)/n_y
171
172
173    # initialise the lists
174    tri_list = []
175    triangles_per_proc = []
176    proc_sum = []
177    for i in range(n_x*n_y):
178        tri_list.append([])
179        triangles_per_proc.append([])
180        proc_sum.append([])
181        tri_list[i] = []
182
183    # subdivide the triangles depending on which sub-box they sit
184    # in (a triangle sits in the sub-box if its first vectex sits
185    # in that sub-box)
186
187    tri_index = {}
188    N = domain.number_of_elements
189    for i in range(N):
190        t = domain.triangles[i]
191
192        x_coord = domain.centroid_coordinates[i][0]
193        bin_x = int(floor((x_coord-x_coord_min)/x_div))
194        if (bin_x == n_x):
195            bin_x = n_x-1
196
197        y_coord = domain.centroid_coordinates[i][1]
198        bin_y = int(floor((y_coord-y_coord_min)/y_div))
199        if (bin_y == n_y):
200            bin_y = n_y-1
201
202        bin = bin_y*n_x + bin_x
203        tri_list[bin].append(t)
204        tri_index[i] = ([bin, len(tri_list[bin])-1])
205
206    # find the number of triangles per processor and order the
207    # triangle list so that all of the triangles belonging to
208    # processor i are listed before those belonging to processor
209    # i+1
210
211    triangles = []
212    for i in range(n_x*n_y):
213        triangles_per_proc[i] = len(tri_list[i])
214        for t in tri_list[i]:
215            triangles.append(t)
216
217    # the boundary labels have to changed in accoradance with the
218    # new triangle ordering, proc_sum and tri_index help with this
219
220    proc_sum[0] = 0
221    for i in range(n_x*n_y-1):
222        proc_sum[i+1]=proc_sum[i]+triangles_per_proc[i]
223
224    # relabel the boundary elements to fit in with the new triangle
225    # ordering
226
227    boundary = {}
228    for b in domain.boundary:
229        t =  tri_index[b[0]]
230        boundary[proc_sum[t[0]]+t[1], b[1]] = domain.boundary[b]
231
232    quantities = reorder(domain.quantities, tri_index, proc_sum)
233
234    # extract the node list
235    nodes = domain.coordinates.copy()
236
237    return nodes, triangles, boundary, triangles_per_proc, quantities
238
239def pmesh_divide_steve(domain, n_x = 1, n_y = 1):
240
241    # find the bounding box
242    x_coord_min = domain.xy_extent[0]
243    x_coord_max = domain.xy_extent[2]
244    y_coord_min = domain.xy_extent[1]
245    y_coord_max = domain.xy_extent[3]
246
247
248    # find the size of each sub-box
249
250    x_div = (x_coord_max-x_coord_min)/n_x
251    y_div = (y_coord_max-y_coord_min)/n_y
252
253
254    # initialise the lists
255    tri_list = []
256    triangles_per_proc = []
257    proc_sum = []
258    for i in range(n_x*n_y):
259        tri_list.append([])
260        triangles_per_proc.append([])
261        proc_sum.append([])
262        tri_list[i] = []
263
264    # subdivide the triangles depending on which sub-box they sit
265    # in (a triangle sits in the sub-box if its first vectex sits
266    # in that sub-box)
267
268    tri_index = {}
269    N = domain.number_of_elements
270
271    #sort by x coordinate of centroid
272    from Numeric import argsort
273    sort_order = argsort(argsort(domain.centroid_coordinates[:,0]))
274
275    x_div = float(N)/n_x
276
277    for i in range(N):
278        t = domain.triangles[i]
279
280        bin = int(floor(sort_order[i]/x_div))
281        if (bin == n_x):
282            bin = n_x-1
283
284        tri_list[bin].append(t)
285        tri_index[i] = ([bin, len(tri_list[bin])-1])
286
287    #print tri_list
288
289    #print tri_index
290
291    # find the number of triangles per processor and order the
292    # triangle list so that all of the triangles belonging to
293    # processor i are listed before those belonging to processor
294    # i+1
295
296    triangles = []
297    for i in range(n_x*n_y):
298        triangles_per_proc[i] = len(tri_list[i])
299        for t in tri_list[i]:
300            triangles.append(t)
301
302    # the boundary labels have to changed in accoradance with the
303    # new triangle ordering, proc_sum and tri_index help with this
304
305    proc_sum[0] = 0
306    for i in range(n_x*n_y-1):
307        proc_sum[i+1]=proc_sum[i]+triangles_per_proc[i]
308
309    # relabel the boundary elements to fit in with the new triangle
310    # ordering
311
312    boundary = {}
313    for b in domain.boundary:
314        t =  tri_index[b[0]]
315        boundary[proc_sum[t[0]]+t[1], b[1]] = domain.boundary[b]
316
317    quantities = reorder(domain.quantities, tri_index, proc_sum)
318
319    # extract the node list
320    nodes = domain.coordinates.copy()
321
322    return nodes, triangles, boundary, triangles_per_proc, quantities
Note: See TracBrowser for help on using the repository browser.