source: inundation/parallel/build_commun.py @ 2920

Last change on this file since 2920 was 2909, checked in by linda, 18 years ago

The parallel listed in the documentation is stored in the documentation/code directory

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