source: inundation/parallel/mg2ga.py @ 1855

Last change on this file since 1855 was 1500, checked in by linda, 19 years ago
File size: 10.0 KB
Line 
1#########################################################
2#   
3
4#  Read in a data file stored in the mg_cell data format.
5#
6#  mg_cell is a code written by Linda Stals for parallel
7# mulitgrid solver based on adaptive finite elements. The
8# reason this code is used is because it gives a grid
9# partition.
10#
11#  This is only intended as a temporary file, once an
12# automatic grid partitioner has been incorporated this
13# file will become redundant.
14#
15#  Authors: Linda Stals and Matthew Hardy, June 2005
16#
17#
18#########################################################
19
20from string import atoi
21from string import atof
22from string import split
23
24
25#########################################################
26#  Read in a mg_cell file. It is assumed that the file
27# has a very specific format. An example file is given in
28# test_3l_2c.out.
29#
30#  *) The mg_cell data-structure is a node-based
31# data-structure, consequently the same triangle will
32# appear three times (mg_cell outputs all of the triangles
33# connected to a given node).
34#
35#  *) The node labels are given in terms of the global ID,
36# which may be thought of as a string (e.g. 12_2), this
37# needs to be converted into an integer format for the GA
38# data structure.
39#
40#  *) It is necessary to specify the boundary conditions,
41# which has been done in mg_cel by outputing the edges
42# with a tag. If the tag is negative the edge is an
43# interior edge, if the tag is positive it is a boundary
44# edge. Different boundary conditions will be given
45# different tags.
46#
47# -------------------------------------------------------
48#
49#  *) The information returned by this routine is the
50# nodes, triangles, boundary edges and the number of
51# triangles to be assigned to each processor. All of the
52# node labels are still stored by the global ID.
53#
54#########################################################
55def readmg(f):
56
57    # read the nuber of processors
58
59    f.readline()
60    no_proc = atoi(f.readline().split()[0])
61
62    # skip over additional information not needed
63   
64    for i in range(5):
65        f.readline();
66
67    # nodes list
68
69    nodes = []
70
71    # boundary edge list
72
73    edges = []
74
75    # triangle list
76
77    triangles = []
78
79    # know first nodes_per_proc[0] belong to cell 0, next
80    # nodes_per_proc[1] belong to cell 1 etc.
81
82    nodes_per_proc = [] 
83    triangles_per_proc = []
84
85    # loop over the processors
86
87    for q in range(no_proc):
88   
89        # read the nodes
90
91        no_nodes = atoi(f.readline().split()[1])
92        nodes_per_proc.append(no_nodes)
93        f.readline()
94
95        for i in range(no_nodes):
96            line = f.readline().split()
97            line[1:3] = map(atof, line[1:3])
98            nodes.append(line[0:3])
99
100        # read the edges
101       
102        f.readline()
103        no_edges = atoi(f.readline().split()[1])
104        f.readline()
105
106        for i in range(no_edges):
107            line = f.readline().split()
108            if (atoi(line[2]) >= 0):
109                edges.append(line)
110       
111        # read the triangles
112
113        f.readline(), f.readline(), f.readline()
114        no_triangles = atoi(f.readline().split()[1])
115        f.readline()
116
117        # remove any triangles that have been repeated
118       
119        for i in range(no_triangles):
120            line = f.readline().split()
121            line.sort()
122            if (len(triangles)==0):
123                triangles.append(line)
124                continue
125           
126            for t in range(len(triangles)):
127                if (triangles[t]==line): 
128                    break
129            if (triangles[t]!=line): 
130               triangles.append(line)
131
132        # keep a record of how many triangles belong to each processor
133       
134        no_triangles=len(triangles)-sum(triangles_per_proc)
135        triangles_per_proc.append(no_triangles)
136
137        # skip extra space
138   
139        f.readline()
140        f.readline()
141        f.readline()
142        f.readline()
143
144    # return the nodes, triangles, boundary edges and the number of triangles
145    # to be assigned to each processor
146   
147    return nodes, triangles, edges, triangles_per_proc
148
149
150#########################################################
151# Convert the format of the data to that used by
152# pyvolution
153#
154#
155# *) Change the nodes global ID's to an integer value,
156#starting from 0.
157#
158# *) The triangles and boundary edges must also be
159# updated accordingly.
160#
161# -------------------------------------------------------
162#
163# *) The nodes, triangles and boundary edges defined by
164# the new numbering scheme are returned
165#
166#########################################################
167
168def restructure(nodes, triangles, edges):
169    Nnodes =len(nodes)
170    Ntriangles = len(triangles)
171   
172    index={} #a dictionary mapping existing node ids to the new ids 0,1,2,...
173
174    GAnodes = []
175   
176    for node_idnew in range(Nnodes): #move through the list of nodes, renumbering to 0,1,2, ...
177        index[nodes[node_idnew][0]]=node_idnew #make the dictionary entry, for later use by triangles
178        GAnodes.append(nodes[node_idnew][1:3])
179#        nodes[node_idnew][0]=node_idnew #renumber the node
180
181    GAedges = {}
182    for e in edges:
183        GAedges[index[e[0]]]=[]
184    for e in edges:
185        GAedges[index[e[0]]].append([index[e[1]],e[2]])
186   
187    #Now loop over the triangles, changing the node ids and orientation.
188    for t in range(Ntriangles):
189        for i in range(3):
190            n=index[triangles[t][i]] #use the dictionary to get the new node id
191            triangles[t][i]=n #relabel the node
192
193           
194    del(index) #delete the dictionary
195
196    return GAnodes, triangles, GAedges
197
198
199#########################################################
200#
201# Reorientate the triangles
202#
203#
204# *) The ordering of the nodes in the triangles may need
205# be changed to ensure the correct orientation.
206#
207# -------------------------------------------------------
208#
209# *) The modified list of triangles is returned
210#
211#########################################################
212def reorient(nodes, triangles):
213   
214
215    Nnodes =len(nodes)
216    Ntriangles = len(triangles)
217   
218    #Now loop over the triangles, changing the node ids and orientation.
219    for t in range(Ntriangles):
220        x=[] #x-coordinates of the three nodes (vertices)
221        y=[] #y-coordinates of the three nodes (vertices)
222        for i in range(3):
223            n=triangles[t][i] #use the dictionary to get the new node id
224            x.append(nodes[n][0])
225            y.append(nodes[n][1])
226        if ((x[1]-x[0])*(y[2]-y[0])-(x[2]-x[0])*(y[1]-y[0])<0): #need to change the orientation
227            triangles[t][2]=triangles[t][0]#swap the 0th and 2nd nodes
228            triangles[t][0]=n
229   
230    del(x)
231    del(y)
232   
233    return triangles
234
235
236#########################################################
237#
238# Put the boundary edge information into a form compatible
239# with the GA datastructure
240#
241# *) The GA datastructure assumes that the boundary edge
242# information is stored in a dictionary. The dictionary
243# key is a list [ti, ei], where ti is the triangle number
244# and ei (0 <= ei < 2) is the edge number for the triangle
245# ti. The value assigned to the given key is the boundary
246# tag.
247#
248# -------------------------------------------------------
249#
250# *) The boundary edge information is returned.
251#########################################################
252def mesh_boundary(triangles, edges):
253
254    # intialise the boundary dictionary
255   
256    boundary = {}
257
258    # loop over all of the triangles
259   
260    for i in range(len(triangles)):
261
262        # given a particular triangle
263       
264        t = triangles[i]
265
266        # is the first vertex a boundary node?
267       
268        if (edges.has_key(t[0])):
269
270            # check to see if the triangles has a boundary
271            # edge
272           
273            for b in edges[t[0]]:
274                if (b[0] == t[1]):
275                   boundary[i, 2] = b[1]
276                elif (b[0] == t[2]):
277                    boundary[i, 1] = b[1]
278
279        # is the second vertex a boundary node?
280       
281        if (edges.has_key(t[1])):
282
283            # check to see if the triangles has a boundary
284            # edge
285           
286            for b in edges[t[1]]:
287                if (b[0] == t[0]):
288                   boundary[i, 2] = b[1]
289                elif (b[0] == t[2]):
290                    boundary[i, 0] = b[1]
291
292        # is the third vertex a boundary node?
293       
294        if (edges.has_key(t[2])):
295
296            # check to see if the triangles has a boundary
297            # edge
298           
299            for b in edges[t[2]]:
300                if (b[0] == t[0]):
301                   boundary[i, 1] = b[1]
302                elif (b[0] == t[1]):
303                    boundary[i, 0] = b[1]
304
305    # return the boundary information
306   
307    return boundary
308
309
310#########################################################
311#
312# Read the nodes, triangles and boundary information from
313# given file
314#
315# *) The information in the file is stored using the
316# mg_cell format.
317#
318# *) See the documentation of the previous functions.
319#
320# -------------------------------------------------------
321#
322# *The information returned by this routine includes the
323# nodes, triangles, boundary edges and the number of
324# triangles to be assigned to each processor.
325#
326#########################################################
327
328def mg2ga(f):
329
330    # read in the information from the file
331   
332    [nodes, triangles, edges, triangles_per_proc] = readmg(f)
333
334    # change the node numbering scheme to be compatible
335    # with the GA datastructure
336   
337    [nodes, triangles, edges] = restructure(nodes, triangles, edges)
338
339    # makesure the triangles are orientated in the correct
340    # way
341    triangles = reorient(nodes, triangles)
342
343    # collect the boundary edge information
344   
345    boundary = mesh_boundary(triangles, edges)
346
347    # return the information
348   
349    return nodes, triangles, boundary, triangles_per_proc
Note: See TracBrowser for help on using the repository browser.