source: anuga_core/source/anuga_parallel/build_commun.py @ 7400

Last change on this file since 7400 was 7400, checked in by steve, 15 years ago

Commit a working copy of numpy version of build_commun

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