source: inundation/parallel/build_commun.py @ 3429

Last change on this file since 3429 was 3429, checked in by ole, 18 years ago

Fixed import statements to be relative to PYTHONPATH

File size: 10.5 KB
Line 
1#########################################################
2#
3# Handle the communication between the host machine
4# (processor 0) and the processors. The host machine is
5# responsible for the doing the initial grid partitioning.
6#
7# The routines given below should be moved to the
8# build_submesh.py and build_local.py file to allow
9# overlapping of  communication and computation.
10# This should be done after more debugging.
11#
12#
13#  Author: Linda Stals, June 2005
14#  Modified: Linda Stals, Nov 2005 (optimise python code)
15#
16#
17#########################################################
18
19from Numeric import array, Int, Float, zeros
20import logging, logging.config
21logger = logging.getLogger('parallel')
22logger.setLevel(logging.WARNING)
23
24try:
25    logging.config.fileConfig('log.ini')
26except:
27    pass
28
29import sys
30
31from pypar_dist import pypar
32#import pypar
33
34from build_local import build_local_mesh
35
36#########################################################
37#
38# Send the submesh to processor p.
39#
40# *) The order and form is strongly coupled with
41# rec_submesh.
42#
43# -------------------------------------------------------
44#
45# *) All of the information has been sent to processor p.
46#
47#########################################################
48
49def send_submesh(submesh, triangles_per_proc, p):
50
51    myid = pypar.rank()
52    print 'process %d sending submesh to process %d' %(myid, p)
53   
54    # build and send the tagmap for the boundary conditions
55   
56    tagmap = {}
57    counter = 1
58    for b in submesh["full_boundary"][p]:
59         bkey = submesh["full_boundary"][p][b]
60         if not tagmap.has_key(bkey):
61             tagmap[bkey] = counter
62             counter = counter+1
63    for b in submesh["ghost_boundary"][p]:
64         bkey = submesh["ghost_boundary"][p][b]
65         if not tagmap.has_key(bkey):
66             tagmap[bkey] = counter
67             counter = counter+1
68    pypar.send(tagmap, p)
69
70    # send the quantities key information
71   
72    pypar.send(submesh["full_quan"].keys(), p)
73   
74    # send the number of triangles per processor
75
76    pypar.send(triangles_per_proc, p, use_buffer=True)
77
78    # compress full_commun
79
80    flat_full_commun = []
81
82    for c in submesh["full_commun"][p]:
83        for i in range(len(submesh["full_commun"][p][c])):
84            flat_full_commun.append([c,submesh["full_commun"][p][c][i]])
85
86    # send the array sizes so memory can be allocated
87
88    setup_array = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
89    setup_array[0] = len(submesh["full_nodes"][p])
90    setup_array[1] = len(submesh["ghost_nodes"][p])
91    setup_array[2] = len(submesh["full_triangles"][p])
92    setup_array[3] = len(submesh["ghost_triangles"][p])
93    setup_array[4] = len(submesh["full_boundary"][p])
94    setup_array[5] = len(submesh["ghost_boundary"][p])
95    setup_array[6] = len(submesh["ghost_commun"][p])
96    setup_array[7] = len(flat_full_commun)
97
98    pypar.send(setup_array, p)
99   
100    # send the nodes
101   
102    pypar.send(submesh["full_nodes"][p], p, use_buffer=True)
103    pypar.send(submesh["ghost_nodes"][p], p, use_buffer=True)
104
105    # send the triangles
106
107    pypar.send(array(submesh["full_triangles"][p], Int), p, use_buffer=True)
108    pypar.send(submesh["ghost_triangles"][p], p, use_buffer=True)
109
110    # send the boundary
111
112    bc = []
113    for b in submesh["full_boundary"][p]:
114        bc.append([b[0], b[1], tagmap[submesh["full_boundary"][p][b]]])
115    pypar.send(bc, p, use_buffer=True)
116    bc = []
117    for b in submesh["ghost_boundary"][p]:
118        bc.append([b[0], b[1], tagmap[submesh["ghost_boundary"][p][b]]])
119    pypar.send(bc, p, use_buffer=True)
120
121    # send the communication pattern
122
123    pypar.send(submesh["ghost_commun"][p], p, use_buffer=True)
124    pypar.send(flat_full_commun, p, use_buffer=True)
125
126    # send the quantities
127   
128    for k in submesh["full_quan"]:
129        pypar.send(submesh["full_quan"][k][p], p, use_buffer=True)
130       
131    for k in submesh["ghost_quan"]:
132        pypar.send(submesh["ghost_quan"][k][p], p, use_buffer=True)
133       
134
135#########################################################
136#
137# Receive the submesh from processor p.
138#
139# *) The order and form is strongly coupled with
140# send_submesh.
141#
142# -------------------------------------------------------
143#
144# *) All of the information has been received by the
145# processor p and passed into build_local.
146#
147# *) The information is returned in a form needed by the
148# GA datastructure.
149#
150#########################################################
151
152def rec_submesh_flat(p):
153
154    numproc = pypar.size()
155    myid = pypar.rank()
156
157    submesh_cell = {}
158   
159    print 'process %d receiving submesh from process %d' %(myid, p)
160
161    # receive the tagmap for the boundary conditions
162   
163    tagmap = pypar.receive(p)
164    itagmap = {}
165    for t in tagmap:
166        itagmap[tagmap[t]]=t
167
168    # receive the quantities key information
169   
170    qkeys = pypar.receive(p)
171
172    # receive the number of triangles per processor
173
174    triangles_per_proc = []
175    for i in range(numproc):
176        triangles_per_proc.append([0])
177
178    triangles_per_proc = pypar.receive(p, triangles_per_proc)
179
180    # recieve information about the array sizes
181
182    setup_array = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
183    setup_array = pypar.receive(p, setup_array)
184
185    # receive the full nodes
186
187    no_full_nodes = setup_array[0]
188    full_nodes = zeros((no_full_nodes, 3), Float)
189    submesh_cell["full_nodes"] = pypar.receive(p, full_nodes)
190   
191    # receive the ghost nodes
192
193    no_ghost_nodes = setup_array[1]
194    ghost_nodes = zeros((no_ghost_nodes, 3), Float)
195    submesh_cell["ghost_nodes"] = pypar.receive(p, ghost_nodes)
196
197   
198    # receive the full triangles
199
200    no_full_triangles = setup_array[2]
201    full_triangles = zeros((no_full_triangles, 3), Int)
202    submesh_cell["full_triangles"] = pypar.receive(p, full_triangles)
203   
204    # receive the ghost triangles
205
206    no_ghost_triangles = setup_array[3]
207    ghost_triangles = zeros((no_ghost_triangles, 4), Int)
208    submesh_cell["ghost_triangles"] = pypar.receive(p, ghost_triangles)
209   
210    # receive the full boundary
211
212    no_full_boundary = setup_array[4]
213    bc = []
214    for i in range(no_full_boundary):
215        bc.append([0.0, 0.0, 0.0])
216    bnd_c = pypar.receive(p, bc)
217
218    submesh_cell["full_boundary"] = {}
219    for b in bnd_c:
220        submesh_cell["full_boundary"][b[0],b[1]]=itagmap[b[2]]
221
222    # receive the ghost boundary
223
224    no_ghost_boundary = setup_array[5]
225    bc = []
226    for i in range(no_ghost_boundary):
227        bc.append([0.0, 0.0, 0.0])
228    bnd_c = pypar.receive(p, bc)
229
230    submesh_cell["ghost_boundary"] = {}
231    for b in bnd_c:
232        submesh_cell["ghost_boundary"][b[0],b[1]]=itagmap[b[2]]
233
234    # receive the ghost communication pattern
235
236    no_ghost_commun = setup_array[6]
237    ghost_commun = zeros((no_ghost_commun, 2), Int)
238    submesh_cell["ghost_commun"] = pypar.receive(p, ghost_commun)
239   
240    # receive the full communication pattern
241
242    no_full_commun = setup_array[7]
243    full_commun = []
244    for i in range(no_full_commun):
245        full_commun.append([0.0, 0.0])
246
247    full_commun = pypar.receive(p, full_commun)
248
249    submesh_cell["full_commun"] = {}
250    for c in full_commun:
251        submesh_cell["full_commun"][c[0]] = []
252    for c in full_commun:
253        submesh_cell["full_commun"][c[0]].append(c[1])
254
255    # receive the quantities
256
257    no_quantities = len(qkeys)
258    new_quan = zeros((no_full_triangles, 3), Float)
259    submesh_cell["full_quan"]={}
260   
261    for i in range(no_quantities):
262        tmp = pypar.receive(p, new_quan)
263        submesh_cell["full_quan"][qkeys[i]]=zeros((no_full_triangles,3), Float)
264        submesh_cell["full_quan"][qkeys[i]][:] = tmp[:]
265
266    new_quan = zeros((no_ghost_triangles, 3), Float)
267    submesh_cell["ghost_quan"]={}
268    for i in range(no_quantities):
269        tmp = pypar.receive(p, new_quan)
270        submesh_cell["ghost_quan"][qkeys[i]]= zeros((no_ghost_triangles,3), Float)
271        submesh_cell["ghost_quan"][qkeys[i]][:] = tmp[:]
272   
273    return submesh_cell, triangles_per_proc
274
275
276
277#########################################################
278#
279# Receive the submesh from processor p.
280#
281# *) The order and form is strongly coupled with
282# send_submesh.
283#
284# -------------------------------------------------------
285#
286# *) All of the information has been received by the
287# processor p and passed into build_local.
288#
289# *) The information is returned in a form needed by the
290# GA datastructure.
291#
292#########################################################
293
294def rec_submesh(p):
295
296    numproc = pypar.size()
297    myid = pypar.rank()
298
299    [submesh_cell, triangles_per_proc] = rec_submesh_flat(p)
300   
301    # find the full triangles assigned to this processor
302
303    lower_t = 0
304    for i in range(myid):
305        lower_t = lower_t+triangles_per_proc[i]
306    upper_t = lower_t+triangles_per_proc[myid]
307
308    # convert the information into a form needed by the GA
309    # datastructure
310
311    [GAnodes, GAtriangles, boundary, quantities, ghost_rec, full_send] = \
312              build_local_mesh(submesh_cell, lower_t, upper_t, \
313                               numproc)
314   
315    return GAnodes, GAtriangles, boundary, quantities, ghost_rec, full_send
316
317#########################################################
318#
319# Extract the submesh that will belong to the
320# "host processor" (i.e. processor zero)
321#
322#  *) See the documentation for build_submesh
323#
324# -------------------------------------------------------
325#
326#  *) A dictionary containing the full_triangles,
327# full_nodes, full_boundary, ghost_triangles, ghost_nodes,
328# ghost_boundary, ghost_commun and full_commun belonging
329# to processor zero are returned.
330#
331#########################################################
332def extract_hostmesh(submesh, triangles_per_proc):
333
334    submesh_cell = {}
335    submesh_cell["full_nodes"] = submesh["full_nodes"][0]
336    submesh_cell["ghost_nodes"] = submesh["ghost_nodes"][0]
337    submesh_cell["full_triangles"] = submesh["full_triangles"][0]
338    submesh_cell["ghost_triangles"] = submesh["ghost_triangles"][0]
339    submesh_cell["full_boundary"] = submesh["full_boundary"][0]
340    submesh_cell["ghost_boundary"] = submesh["ghost_boundary"][0]
341    submesh_cell["ghost_commun"] = submesh["ghost_commun"][0]
342    submesh_cell["full_commun"] = submesh["full_commun"][0]
343    submesh_cell["full_quan"] ={}
344    submesh_cell["ghost_quan"]={}
345    for k in submesh["full_quan"]:
346        submesh_cell["full_quan"][k] = submesh["full_quan"][k][0]
347        submesh_cell["ghost_quan"][k] = submesh["ghost_quan"][k][0]
348
349    numprocs = pypar.size()
350    points, vertices, boundary, quantities, ghost_recv_dict, full_send_dict = \
351            build_local_mesh(submesh_cell, 0, triangles_per_proc[0], numprocs)
352    return  points, vertices, boundary, quantities, ghost_recv_dict, \
353           full_send_dict
354
355
356
Note: See TracBrowser for help on using the repository browser.