source: anuga_core/source/anuga_parallel/parallel_meshes.py @ 4686

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

Removed all references to pyvolution in parallel code

File size: 10.2 KB
Line 
1"""parallel-meshes -
22D triangular domains for parallel finite-volume computations of
3the advection equation, with extra structures to define the
4sending and receiving communications define in dictionaries
5full_send_dict and ghost_recv_dict
6
7
8Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
9Geoscience Australia, 2005
10
11Modified by Linda Stals, March 2006, to include ghost boundaries
12
13"""
14
15
16import sys
17from Numeric import array, zeros, Float, Int
18
19import pypar
20
21from anuga.config import epsilon
22
23
24def parallel_rectangle(m_g, n_g, len1_g=1.0, len2_g=1.0, origin_g = (0.0, 0.0)):
25
26
27    """Setup a rectangular grid of triangles
28    with m+1 by n+1 grid points
29    and side lengths len1, len2. If side lengths are omitted
30    the mesh defaults to the unit square, divided between all the
31    processors
32
33    len1: x direction (left to right)
34    len2: y direction (bottom to top)
35
36    """
37
38    processor = pypar.rank()
39    numproc   = pypar.size()
40
41    m_low, m_high = pypar.balance(m_g, numproc, processor)
42   
43    n = n_g
44    m_low  = m_low-1
45    m_high = m_high+1
46    m = m_high - m_low
47
48    delta1 = float(len1_g)/m_g
49    delta2 = float(len2_g)/n_g
50
51    len1 = len1_g*float(m)/float(m_g)
52    len2 = len2_g
53    origin = ( origin_g[0]+float(m_low)/float(m_g)*len1_g, origin_g[1] )
54
55    #Calculate number of points
56    Np = (m+1)*(n+1)
57
58    class VIndex:
59
60        def __init__(self, n,m):
61            self.n = n
62            self.m = m
63
64        def __call__(self, i,j):
65            return j+i*(self.n+1)
66
67    class EIndex:
68
69        def __init__(self, n,m):
70            self.n = n
71            self.m = m
72
73        def __call__(self, i,j):
74            return 2*(j+i*self.n)
75
76
77    I = VIndex(n,m)
78    E = EIndex(n,m)
79
80    points = zeros( (Np,2), Float)
81
82    for i in range(m+1):
83        for j in range(n+1):
84
85            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
86
87    #Construct 2 triangles per rectangular element and assign tags to boundary
88    #Calculate number of triangles
89    Nt = 2*m*n
90
91
92    elements = zeros( (Nt,3), Int)
93    boundary = {}
94    Idgl = []
95    Idfl = []
96    Idgr = []
97    Idfr = []
98
99    full_send_dict = {}
100    ghost_recv_dict = {}
101    nt = -1
102    for i in range(m):
103        for j in range(n):
104
105            i1 = I(i,j+1)
106            i2 = I(i,j)
107            i3 = I(i+1,j+1)
108            i4 = I(i+1,j)
109
110            #Lower Element
111            nt = E(i,j)
112            if i == 0:
113                Idgl.append(nt)
114
115            if i == 1:
116                Idfl.append(nt)
117
118            if i == m-2:
119                Idfr.append(nt)
120
121            if i == m-1:
122                Idgr.append(nt)
123
124            if i == m-1:
125                if processor == numproc-1:
126                    boundary[nt, 2] = 'right'
127                else:
128                    boundary[nt, 2] = 'ghost'
129       
130            if j == 0:
131                boundary[nt, 1] = 'bottom'
132            elements[nt,:] = [i4,i3,i2]
133
134            #Upper Element
135            nt = E(i,j)+1
136            if i == 0:
137                Idgl.append(nt)
138
139            if i == 1:
140                Idfl.append(nt)
141
142            if i == m-2:
143                Idfr.append(nt)
144
145            if i == m-1:
146                Idgr.append(nt)
147
148            if i == 0:
149                if processor == 0:
150                    boundary[nt, 2] = 'left'
151                else:
152                    boundary[nt, 2] = 'ghost'
153            if j == n-1:
154                boundary[nt, 1] = 'top'
155            elements[nt,:] = [i1,i2,i3]
156
157    if numproc==1:
158        Idfl.extend(Idfr)
159        Idgr.extend(Idgl)
160        Idfl = array(Idfl,Int)
161        Idgr = array(Idgr,Int)
162        full_send_dict[processor]  = [Idfl, Idfl]
163        ghost_recv_dict[processor] = [Idgr, Idgr]
164    elif numproc == 2:
165        Idfl.extend(Idfr)
166        Idgr.extend(Idgl)
167        Idfl = array(Idfl,Int)
168        Idgr = array(Idgr,Int)
169        full_send_dict[(processor-1)%numproc]  = [Idfl, Idfl]
170        ghost_recv_dict[(processor-1)%numproc] = [Idgr, Idgr]
171    else:
172        Idfl = array(Idfl,Int)
173        Idgl = array(Idgl,Int)
174
175        Idfr = array(Idfr,Int)
176        Idgr = array(Idgr,Int)
177
178        full_send_dict[(processor-1)%numproc]  = [Idfl, Idfl]
179        ghost_recv_dict[(processor-1)%numproc] = [Idgl, Idgl]
180        full_send_dict[(processor+1)%numproc]  = [Idfr, Idfr]
181        ghost_recv_dict[(processor+1)%numproc] = [Idgr, Idgr]
182
183    return  points, elements, boundary, full_send_dict, ghost_recv_dict
184
185
186
187def rectangular_periodic(m, n, len1=1.0, len2=1.0, origin = (0.0, 0.0)):
188
189
190    """Setup a rectangular grid of triangles
191    with m+1 by n+1 grid points
192    and side lengths len1, len2. If side lengths are omitted
193    the mesh defaults to the unit square.
194
195    len1: x direction (left to right)
196    len2: y direction (bottom to top)
197
198    Return to lists: points and elements suitable for creating a Mesh or
199    FVMesh object, e.g. Mesh(points, elements)
200    """
201
202    delta1 = float(len1)/m
203    delta2 = float(len2)/n
204
205    #Calculate number of points
206    Np = (m+1)*(n+1)
207
208    class VIndex:
209
210        def __init__(self, n,m):
211            self.n = n
212            self.m = m
213
214        def __call__(self, i,j):
215            return j+i*(self.n+1)
216
217    class EIndex:
218
219        def __init__(self, n,m):
220            self.n = n
221            self.m = m
222
223        def __call__(self, i,j):
224            return 2*(j+i*self.n)
225
226
227    I = VIndex(n,m)
228    E = EIndex(n,m)
229
230    points = zeros( (Np,2), Float)
231
232    for i in range(m+1):
233        for j in range(n+1):
234
235            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
236
237    #Construct 2 triangles per rectangular element and assign tags to boundary
238    #Calculate number of triangles
239    Nt = 2*m*n
240
241
242    elements = zeros( (Nt,3), Int)
243    boundary = {}
244    ghosts = {}
245    nt = -1
246    for i in range(m):
247        for j in range(n):
248
249            i1 = I(i,j+1)
250            i2 = I(i,j)
251            i3 = I(i+1,j+1)
252            i4 = I(i+1,j)
253
254            #Lower Element
255            nt = E(i,j)
256            if i == m-1:
257                ghosts[nt] = E(1,j)
258            if i == 0:
259                ghosts[nt] = E(m-2,j)
260
261            if j == n-1:
262                ghosts[nt] = E(i,1)
263
264            if j == 0:
265                ghosts[nt] = E(i,n-2)
266
267            if i == m-1:
268                if processor == numproc-1:
269                    boundary[nt, 2] = 'right'
270                else:
271                    boundary[nt, 2] = 'ghost'
272            if j == 0:
273                boundary[nt, 1] = 'bottom'
274            elements[nt,:] = [i4,i3,i2]
275
276            #Upper Element
277            nt = E(i,j)+1
278            if i == m-1:
279                ghosts[nt] = E(1,j)+1
280            if i == 0:
281                ghosts[nt] = E(m-2,j)+1
282
283            if j == n-1:
284                ghosts[nt] = E(i,1)+1
285
286            if j == 0:
287                ghosts[nt] = E(i,n-2)+1
288
289            if i == 0:
290                if processor == 0:
291                    boundary[nt, 2] = 'left'
292                else:
293                    boundary[nt, 2] = 'ghost'
294            if j == n-1:
295                boundary[nt, 1] = 'top'
296            elements[nt,:] = [i1,i2,i3]
297
298    #bottom left
299    nt = E(0,0)
300    nf = E(m-2,n-2)
301    ghosts[nt]   = nf
302    ghosts[nt+1] = nf+1
303
304    #bottom right
305    nt = E(m-1,0)
306    nf = E(1,n-2)
307    ghosts[nt]   = nf
308    ghosts[nt+1] = nf+1
309
310    #top left
311    nt = E(0,n-1)
312    nf = E(m-2,1)
313    ghosts[nt]   = nf
314    ghosts[nt+1] = nf+1
315
316    #top right
317    nt = E(m-1,n-1)
318    nf = E(1,1)
319    ghosts[nt]   = nf
320    ghosts[nt+1] = nf+1
321
322    return points, elements, boundary, ghosts
323
324def rectangular_periodic_lr(m, n, len1=1.0, len2=1.0, origin = (0.0, 0.0)):
325
326
327    """Setup a rectangular grid of triangles
328    with m+1 by n+1 grid points
329    and side lengths len1, len2. If side lengths are omitted
330    the mesh defaults to the unit square.
331
332    len1: x direction (left to right)
333    len2: y direction (bottom to top)
334
335    Return to lists: points and elements suitable for creating a Mesh or
336    Domain object, e.g. Mesh(points, elements)
337    """
338
339    delta1 = float(len1)/m
340    delta2 = float(len2)/n
341
342    #Calculate number of points
343    Np = (m+1)*(n+1)
344
345    class VIndex:
346
347        def __init__(self, n,m):
348            self.n = n
349            self.m = m
350
351        def __call__(self, i,j):
352            return j+i*(self.n+1)
353
354    class EIndex:
355
356        def __init__(self, n,m):
357            self.n = n
358            self.m = m
359
360        def __call__(self, i,j):
361            return 2*(j+i*self.n)
362
363
364    I = VIndex(n,m)
365    E = EIndex(n,m)
366
367    points = zeros( (Np,2), Float)
368
369    for i in range(m+1):
370        for j in range(n+1):
371
372            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
373
374    #Construct 2 triangles per rectangular element and assign tags to boundary
375    #Calculate number of triangles
376    Nt = 2*m*n
377
378
379    elements = zeros( (Nt,3), Int)
380    boundary = {}
381    ghosts = {}
382    nt = -1
383    for i in range(m):
384        for j in range(n):
385
386            i1 = I(i,j+1)
387            i2 = I(i,j)
388            i3 = I(i+1,j+1)
389            i4 = I(i+1,j)
390
391            #Lower Element
392            nt = E(i,j)
393            if i == m-1:
394                ghosts[nt] = E(1,j)
395            if i == 0:
396                ghosts[nt] = E(m-2,j)
397
398            if i == m-1:
399                if processor == numproc-1:
400                    boundary[nt, 2] = 'right'
401                else:
402                    boundary[nt, 2] = 'ghost'
403            if j == 0:
404                boundary[nt, 1] = 'bottom'
405            elements[nt,:] = [i4,i3,i2]
406
407            #Upper Element
408            nt = E(i,j)+1
409            if i == m-1:
410                ghosts[nt] = E(1,j)+1
411            if i == 0:
412                ghosts[nt] = E(m-2,j)+1
413
414            if i == 0:
415                if processor == 0:
416                    boundary[nt, 2] = 'left'
417                else:
418                    boundary[nt, 2] = 'ghost'
419            if j == n-1:
420                boundary[nt, 1] = 'top'
421            elements[nt,:] = [i1,i2,i3]
422
423
424    return points, elements, boundary, ghosts
Note: See TracBrowser for help on using the repository browser.