source: branches/inundation-numpy-branch/parallel/parallel_meshes.py @ 8729

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