source: inundation/parallel/build_local.py @ 2051

Last change on this file since 2051 was 1580, checked in by linda, 20 years ago

communicate quantities in parallel

File size: 6.9 KB
Line 
1#########################################################
2#
3#  Given the subdivision of the grid assigned to the
4# current processor convert it into a form that is
5# appropriate for the GA datastructure.
6#
7#  The main function of these modules is to change the
8# node numbering. The GA datastructure assumes they
9# are numbered consecutively from 0.
10#
11#  The module also changes the communication pattern
12# datastructure into a form needed by parallel_advection
13#
14#  Authors: Linda Stals and Matthew Hardy, June 2005
15#
16#
17#########################################################
18
19from mesh import *
20from Numeric import array, Int, Float, zeros
21
22#########################################################
23# Convert the format of the data to that used by
24# pyvolution
25#
26#
27# *) Change the nodes global ID's to an integer value,
28#starting from 0.
29#
30# *) The triangles and boundary edges must also be
31# updated accordingly.
32#
33# -------------------------------------------------------
34#
35# *) The nodes, triangles and boundary edges defined by
36# the new numbering scheme are returned
37#
38#########################################################
39
40def build_local_GA(nodes, triangles):
41
42    Nnodes =len(nodes)
43    Ntriangles = len(triangles)
44
45    index={} #a dictionary mapping existing node ids to the new ids 0,1,2,...
46
47    GAnodes = []
48
49    nodes  = nodes # do not rearrange nodes in origianal grid
50    for node_idnew in range(Nnodes): #move through the list of nodes, renumbering to 0,1,2, ...
51        index[nodes[node_idnew][0]]=node_idnew #make the dictionary entry, for later use by triangles
52        GAnodes.append(nodes[node_idnew][1:3])
53        nodes[node_idnew][0]=node_idnew #renumber the node
54
55    #Now loop over the triangles, changing the node ids and orientation.
56    for t in range(Ntriangles):
57        for i in range(3):
58            n=index[triangles[t][i]] #use the dictionary to get the new node id
59            triangles[t][i]=n #relabel the node
60
61    del (index)
62
63    return GAnodes
64
65
66#########################################################
67# Change the communication format to that needed by the
68# parallel advection file.
69#
70# *) The index contains [global triangle no,
71# local triangle no.]
72#
73# -------------------------------------------------------
74#
75# *) The ghost_recv and full_send dictionaries are
76# returned.
77#
78# *) ghost_recv dictionary is local id, global id, value
79#
80# *) full_recv dictionary is local id, global id, value
81#
82# *) The information is ordered by the global id so the
83# local and global id do not need to be compared when the
84# information is sent/received because the order is
85# predetermined.
86#
87#########################################################
88
89def sort_tup(x, y):
90    return cmp(x[0], y[0])
91
92def build_local_commun(index, ghostc, fullc, nproc):
93
94    # initialise
95
96    full_send = {}
97    ghost_recv = {}
98
99    # build the ghost_recv dictionary (sort the
100    # information by the global numbering)
101
102    ghostc.sort(sort_tup)
103    for c in ghostc:
104        if not ghost_recv.has_key(c[1]):
105            ghost_recv[c[1]] = [0, 0]
106            ghost_recv[c[1]][0] = []
107            ghost_recv[c[1]][1] = []
108        ghost_recv[c[1]][0].append(index[c[0]])
109        ghost_recv[c[1]][1].append(c[0])
110
111
112    # build a temporary copy of the full_send dictionary
113    # (this version allows the information to be stored
114    # by the global numbering)
115
116    tmp_send = {}
117    for global_id in fullc:
118        for i in range(len(fullc[global_id])):
119            neigh = fullc[global_id][i]
120            if not tmp_send.has_key(neigh):
121                tmp_send[neigh] = []
122            tmp_send[neigh].append([global_id, index[global_id]])
123
124    # extract the full send information and put it in the form
125    # required for the full_send dictionary
126
127    for neigh in tmp_send:
128        neigh_commun = tmp_send[neigh]
129        neigh_commun.sort(sort_tup)
130        full_send[neigh] = [0, 0]
131        full_send[neigh][0] = []
132        full_send[neigh][1] = []
133        for t in neigh_commun:
134            full_send[neigh][0].append(t[1])
135            full_send[neigh][1].append(t[0])
136
137
138
139    # parallel advection expects numeric arrays
140    for key in full_send:
141        full_send[key][0] = array(full_send[key][0],Int)
142        full_send[key][1] = array(full_send[key][1],Int)
143
144
145    for key in ghost_recv:
146        ghost_recv[key][0] = array(ghost_recv[key][0],Int)
147        ghost_recv[key][1] = array(ghost_recv[key][1],Int)
148
149
150
151    return ghost_recv, full_send
152
153
154#########################################################
155# Convert the format of the data to that used by
156# pyvolution
157#
158#
159# *) Change the nodes global ID's to an integer value,
160# starting from 0. The node numbering in the triangles
161# must also be updated to take this into accound.
162#
163# *) The triangle number will also change, which affects
164# the boundary tag information and the communication
165# pattern.
166#
167# -------------------------------------------------------
168#
169# *) The nodes, triangles, boundary edges and communication
170# pattern defined by the new numbering scheme are returned
171#
172#########################################################
173
174def build_local_mesh(submesh, lower_t, upper_t, nproc):
175
176    # combine the full nodes and ghost nodes
177
178    nodes = submesh["full_nodes"]
179    nodes.extend(submesh["ghost_nodes"])
180
181    # combine the full triangles and ghost triangles
182
183    triangles = submesh["full_triangles"]
184    triangles.extend(map(lambda t: t[1], submesh["ghost_triangles"]))
185
186    # renumber the boundary edges to correspond to the new
187    # triangle numbering
188
189    GAboundary = {}
190    for b in submesh["full_boundary"]:
191        GAboundary[b[0]-lower_t,b[1]]=submesh["full_boundary"][b]
192
193    # make note of the new triangle numbers, including the ghost
194    # triangles
195
196    index = {}
197    for i in range(lower_t, upper_t):
198        index[i] = i-lower_t
199    for i in range(len(submesh["ghost_triangles"])):
200        index[submesh["ghost_triangles"][i][0]] = i+upper_t-lower_t
201
202    # change the node numbering (and update the numbering in the
203    # triangles)
204
205    GAnodes = build_local_GA(nodes, triangles)
206
207    # extract the local quantities
208   
209    quantities ={}
210    for k in submesh["full_quan"]:
211        Nf = len(submesh["full_quan"][k])
212        Ng = len(submesh["ghost_quan"][k])
213        quantities[k] = zeros((Nf+Ng, 3), Float)
214        quantities[k][0:Nf] = submesh["full_quan"][k] 
215        quantities[k][Nf:Nf+Ng] = submesh["ghost_quan"][k]
216                             
217    # change the communication pattern into a form needed by
218    # the parallel_advection.py file
219
220    gcommun = submesh["ghost_commun"]
221    fcommun = submesh["full_commun"]
222    [ghost_rec, full_send] = build_local_commun(index, gcommun, fcommun, nproc)
223
224    # clean up before exiting
225
226    del(index)
227
228    return GAnodes, triangles, GAboundary, quantities, ghost_rec, full_send
Note: See TracBrowser for help on using the repository browser.