source: inundation/parallel/build_local.py @ 2197

Last change on this file since 2197 was 2130, checked in by linda, 19 years ago

Modified the parallel code to agree with the python style files

File size: 6.7 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#  Modified: Linda Stals, Nov 2005 (optimise python code)
16#
17#
18#########################################################
19
20from Numeric import  zeros, Float, Int, concatenate, \
21     take, arrayrange, put, sort, compress, equal
22
23
24#########################################################
25# Convert the format of the data to that used by
26# pyvolution
27#
28#
29# *) Change the nodes global ID's to an integer value,
30#starting from 0.
31#
32# *) The triangles and boundary edges must also be
33# updated accordingly.
34#
35# -------------------------------------------------------
36#
37# *) The nodes, triangles and boundary edges defined by
38# the new numbering scheme are returned
39#
40#########################################################
41
42def build_local_GA(nodes, triangles):
43
44    Nnodes =len(nodes)
45    Ntriangles = len(triangles)
46   
47    # Extract the nodes (using the local ID)
48   
49    GAnodes = take(nodes, (1, 2), 1)
50
51    # Build a global ID to local ID mapping
52
53    NGlobal = 0
54    for i in range(Nnodes):
55        if nodes[i][0] > NGlobal:
56            NGlobal = nodes[i][0]
57    index = zeros(int(NGlobal)+1, Int)
58    put(index, take(nodes, (0,), 1).astype(Int), \
59        arrayrange(Nnodes))
60       
61    # Change the global IDs in the triangles to the local IDs
62
63    GAtriangles = zeros((Ntriangles, 3), Int)
64    GAtriangles[:,0] = take(index, triangles[:,0])
65    GAtriangles[:,1] = take(index, triangles[:,1])
66    GAtriangles[:,2] = take(index, triangles[:,2])
67   
68    del (index)
69
70    return GAnodes, GAtriangles
71
72
73#########################################################
74# Change the communication format to that needed by the
75# parallel advection file.
76#
77# *) The index contains [global triangle no,
78# local triangle no.]
79#
80# -------------------------------------------------------
81#
82# *) The ghost_recv and full_send dictionaries are
83# returned.
84#
85# *) ghost_recv dictionary is local id, global id, value
86#
87# *) full_recv dictionary is local id, global id, value
88#
89# *) The information is ordered by the global id. This
90# means that the communication order is predetermined and
91# local and global id do not need to be
92# compared when the information is sent/received.
93#
94#########################################################
95
96def build_local_commun(index, ghostc, fullc, nproc):
97
98    # Initialise
99
100    full_send = {}
101    ghost_recv = {}
102
103    # Build the ghost_recv dictionary (sort the
104    # information by the global numbering)
105   
106    ghostc = sort(ghostc, 0)
107   
108    for c in range(nproc):
109        s = ghostc[:,0]
110        d = compress(equal(ghostc[:,1],c), s)
111        if len(d) > 0:
112            ghost_recv[c] = [0, 0]
113            ghost_recv[c][1] = d
114            ghost_recv[c][0] = take(index, d)
115           
116    # Build a temporary copy of the full_send dictionary
117    # (this version allows the information to be stored
118    # by the global numbering)
119
120    tmp_send = {}
121    for global_id in fullc:
122        for i in range(len(fullc[global_id])):
123            neigh = fullc[global_id][i]
124            if not tmp_send.has_key(neigh):
125                tmp_send[neigh] = []
126            tmp_send[neigh].append([global_id, \
127                                    index[global_id]])
128
129    # Extract the full send information and put it in the form
130    # required for the full_send dictionary
131
132    for neigh in tmp_send:
133        neigh_commun = sort(tmp_send[neigh], 0)
134        full_send[neigh] = [0, 0]
135        full_send[neigh][0] = neigh_commun[:,1]
136        full_send[neigh][1] = neigh_commun[:,0]
137
138    return ghost_recv, full_send
139
140
141#########################################################
142# Convert the format of the data to that used by
143# pyvolution
144#
145#
146# *) Change the nodes global ID's to an integer value,
147# starting from 0. The node numbering in the triangles
148# must also be updated to take this into account.
149#
150# *) The triangle number will also change, which affects
151# the boundary tag information and the communication
152# pattern.
153#
154# -------------------------------------------------------
155#
156# *) The nodes, triangles, boundary edges and communication
157# pattern defined by the new numbering scheme are returned
158#
159#########################################################
160
161def build_local_mesh(submesh, lower_t, upper_t, nproc):
162
163    # Combine the full nodes and ghost nodes
164
165    nodes = concatenate((submesh["full_nodes"], \
166                         submesh["ghost_nodes"]))
167   
168    # Combine the full triangles and ghost triangles
169
170    gtri =  take(submesh["ghost_triangles"],(1, 2, 3),1)
171    triangles = concatenate((submesh["full_triangles"], gtri))
172
173    # Renumber the boundary edges to correspond to the new
174    # triangle numbering
175
176    GAboundary = {}
177    for b in submesh["full_boundary"]:
178        GAboundary[b[0]-lower_t,b[1]] = submesh["full_boundary"][b]
179
180    # Make note of the new triangle numbers, including the ghost
181    # triangles
182
183    NGlobal = upper_t
184    for i in range(len(submesh["ghost_triangles"])):
185        id = submesh["ghost_triangles"][i][0]
186        if id > NGlobal:
187            NGlobal = id
188    index = zeros(int(NGlobal)+1, Int)
189    index[lower_t:upper_t]=arrayrange(upper_t-lower_t)
190    for i in range(len(submesh["ghost_triangles"])):
191        index[submesh["ghost_triangles"][i][0]] = i+upper_t-lower_t
192
193    # Change the node numbering (and update the numbering in the
194    # triangles)
195
196    [GAnodes, GAtriangles] = build_local_GA(nodes, triangles)
197
198    # Extract the local quantities
199   
200    quantities ={}
201    for k in submesh["full_quan"]:
202        Nf = len(submesh["full_quan"][k])
203        Ng = len(submesh["ghost_quan"][k])
204        quantities[k] = zeros((Nf+Ng, 3), Float)
205        quantities[k][0:Nf] = submesh["full_quan"][k] 
206        quantities[k][Nf:Nf+Ng] = submesh["ghost_quan"][k]
207                             
208    # Change the communication pattern into a form needed by
209    # the parallel_adv
210
211    gcommun = submesh["ghost_commun"]
212    fcommun = submesh["full_commun"]
213    [ghost_rec, full_send] = \
214                build_local_commun(index, gcommun, fcommun, nproc)
215
216    # Clean up before exiting
217
218    del(index)
219
220    return GAnodes, GAtriangles, GAboundary, quantities, ghost_rec, \
221           full_send
Note: See TracBrowser for help on using the repository browser.