source: inundation/ga/storm_surge/parallel/parallel_meshes.py @ 1599

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