source: anuga_work/development/parallel/build_local.py @ 6823

Last change on this file since 6823 was 3460, checked in by jack, 18 years ago

Moved parallel to development from inundation

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