source: anuga_core/source/anuga_parallel/build_local.py @ 5529

Last change on this file since 5529 was 3579, checked in by ole, 18 years ago

Removed all references to pyvolution in parallel code

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