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

Last change on this file since 1520 was 1520, checked in by steve, 19 years ago
File size: 10.1 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_rectangular(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    Xgl  = []
95    Idfl = []
96    Xfl  = []
97    Idgr = []
98    Xgr  = []
99    Idfr = []
100    Xfr  = []
101
102    full_send_dict = {}
103    ghost_recv_dict = {}
104    nt = -1
105    for i in range(m):
106        for j in range(n):
107
108            i1 = I(i,j+1)
109            i2 = I(i,j)
110            i3 = I(i+1,j+1)
111            i4 = I(i+1,j)
112
113            #Lower Element
114            nt = E(i,j)
115            if i == 0:
116                Idgl.append(nt)
117
118            if i == 1:
119                Idfl.append(nt)
120
121            if i == m-2:
122                Idfr.append(nt)
123
124            if i == m-1:
125                Idgr.append(nt)
126
127            if i == m-1:
128                boundary[nt, 2] = 'right'
129            if j == 0:
130                boundary[nt, 1] = 'bottom'
131            elements[nt,:] = [i4,i3,i2]
132
133            #Upper Element
134            nt = E(i,j)+1
135            if i == 0:
136                Idgl.append(nt)
137
138            if i == 1:
139                Idfl.append(nt)
140
141            if i == m-2:
142                Idfr.append(nt)
143
144            if i == m-1:
145                Idgr.append(nt)
146
147            if i == 0:
148                boundary[nt, 2] = 'left'
149            if j == n-1:
150                boundary[nt, 1] = 'top'
151            elements[nt,:] = [i1,i2,i3]
152
153    if numproc==1:
154        #print Idfl
155        #print Idfr
156        Idfl.extend(Idfr)
157        #print Idfl
158        Idgr.extend(Idgl)
159        Idfl = array(Idfl,Int)
160        Idgr = array(Idgr,Int)
161        Xf   = zeros(Idfl.shape,Float)
162        Xg   = zeros(Idgr.shape,Float)
163        full_send_dict[processor]  = [Idfl, Idfl, Xf]
164        ghost_recv_dict[processor] = [Idgr, Idgr, Xg]
165    elif numproc == 2:
166        Idfl.extend(Idfr)
167        Idgr.extend(Idgl)
168        #print Idfl
169        Idfl = array(Idfl,Int)
170        Idgr = array(Idgr,Int)
171        Xf   = zeros(Idfl.shape,Float)
172        Xg   = zeros(Idgr.shape,Float)
173        full_send_dict[(processor-1)%numproc]  = [Idfl, Idfl, Xf]
174        ghost_recv_dict[(processor-1)%numproc] = [Idgr, Idgr, Xg]
175    else:
176        Idfl = array(Idfl,Int)
177        Idgl = array(Idgl,Int)
178        Xfl  = zeros(Idfl.shape,Float)
179        Xgl  = zeros(Idgl.shape,Float)
180
181        Idfr = array(Idfr,Int)
182        Idgr = array(Idgr,Int)
183        Xfr  = zeros(Idfr.shape,Float)
184        Xgr  = zeros(Idgr.shape,Float)
185
186        full_send_dict[(processor-1)%numproc]  = [Idfl, Idfl, Xfl]
187        ghost_recv_dict[(processor-1)%numproc] = [Idgl, Idgl, Xgl]
188        full_send_dict[(processor+1)%numproc]  = [Idfr, Idfr, Xfr]
189        ghost_recv_dict[(processor+1)%numproc] = [Idgr, Idgr, Xgr]
190
191    return  points, elements, boundary, full_send_dict, ghost_recv_dict
192
193
194
195def rectangular_periodic(m, n, len1=1.0, len2=1.0, origin = (0.0, 0.0)):
196
197
198    """Setup a rectangular grid of triangles
199    with m+1 by n+1 grid points
200    and side lengths len1, len2. If side lengths are omitted
201    the mesh defaults to the unit square.
202
203    len1: x direction (left to right)
204    len2: y direction (bottom to top)
205
206    Return to lists: points and elements suitable for creating a Mesh or
207    FVMesh object, e.g. Mesh(points, elements)
208    """
209
210    from config import epsilon
211    from Numeric import zeros, Float, Int
212
213    delta1 = float(len1)/m
214    delta2 = float(len2)/n
215
216    #Calculate number of points
217    Np = (m+1)*(n+1)
218
219    class VIndex:
220
221        def __init__(self, n,m):
222            self.n = n
223            self.m = m
224
225        def __call__(self, i,j):
226            return j+i*(self.n+1)
227
228    class EIndex:
229
230        def __init__(self, n,m):
231            self.n = n
232            self.m = m
233
234        def __call__(self, i,j):
235            return 2*(j+i*self.n)
236
237
238    I = VIndex(n,m)
239    E = EIndex(n,m)
240
241    points = zeros( (Np,2), Float)
242
243    for i in range(m+1):
244        for j in range(n+1):
245
246            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
247
248    #Construct 2 triangles per rectangular element and assign tags to boundary
249    #Calculate number of triangles
250    Nt = 2*m*n
251
252
253    elements = zeros( (Nt,3), Int)
254    boundary = {}
255    ghosts = {}
256    nt = -1
257    for i in range(m):
258        for j in range(n):
259
260            i1 = I(i,j+1)
261            i2 = I(i,j)
262            i3 = I(i+1,j+1)
263            i4 = I(i+1,j)
264
265            #Lower Element
266            nt = E(i,j)
267            if i == m-1:
268                ghosts[nt] = E(1,j)
269            if i == 0:
270                ghosts[nt] = E(m-2,j)
271
272            if j == n-1:
273                ghosts[nt] = E(i,1)
274
275            if j == 0:
276                ghosts[nt] = E(i,n-2)
277
278            if i == m-1:
279                boundary[nt, 2] = 'right'
280            if j == 0:
281                boundary[nt, 1] = 'bottom'
282            elements[nt,:] = [i4,i3,i2]
283
284            #Upper Element
285            nt = E(i,j)+1
286            if i == m-1:
287                ghosts[nt] = E(1,j)+1
288            if i == 0:
289                ghosts[nt] = E(m-2,j)+1
290
291            if j == n-1:
292                ghosts[nt] = E(i,1)+1
293
294            if j == 0:
295                ghosts[nt] = E(i,n-2)+1
296
297            if i == 0:
298                boundary[nt, 2] = 'left'
299            if j == n-1:
300                boundary[nt, 1] = 'top'
301            elements[nt,:] = [i1,i2,i3]
302
303    #bottom left
304    nt = E(0,0)
305    nf = E(m-2,n-2)
306    ghosts[nt]   = nf
307    ghosts[nt+1] = nf+1
308
309    #bottom right
310    nt = E(m-1,0)
311    nf = E(1,n-2)
312    ghosts[nt]   = nf
313    ghosts[nt+1] = nf+1
314
315    #top left
316    nt = E(0,n-1)
317    nf = E(m-2,1)
318    ghosts[nt]   = nf
319    ghosts[nt+1] = nf+1
320
321    #top right
322    nt = E(m-1,n-1)
323    nf = E(1,1)
324    ghosts[nt]   = nf
325    ghosts[nt+1] = nf+1
326
327    return points, elements, boundary, ghosts
328
329def rectangular_periodic_lr(m, n, len1=1.0, len2=1.0, origin = (0.0, 0.0)):
330
331
332    """Setup a rectangular grid of triangles
333    with m+1 by n+1 grid points
334    and side lengths len1, len2. If side lengths are omitted
335    the mesh defaults to the unit square.
336
337    len1: x direction (left to right)
338    len2: y direction (bottom to top)
339
340    Return to lists: points and elements suitable for creating a Mesh or
341    Domain object, e.g. Mesh(points, elements)
342    """
343
344    from config import epsilon
345    from Numeric import zeros, Float, Int
346
347    delta1 = float(len1)/m
348    delta2 = float(len2)/n
349
350    #Calculate number of points
351    Np = (m+1)*(n+1)
352
353    class VIndex:
354
355        def __init__(self, n,m):
356            self.n = n
357            self.m = m
358
359        def __call__(self, i,j):
360            return j+i*(self.n+1)
361
362    class EIndex:
363
364        def __init__(self, n,m):
365            self.n = n
366            self.m = m
367
368        def __call__(self, i,j):
369            return 2*(j+i*self.n)
370
371
372    I = VIndex(n,m)
373    E = EIndex(n,m)
374
375    points = zeros( (Np,2), Float)
376
377    for i in range(m+1):
378        for j in range(n+1):
379
380            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
381
382    #Construct 2 triangles per rectangular element and assign tags to boundary
383    #Calculate number of triangles
384    Nt = 2*m*n
385
386
387    elements = zeros( (Nt,3), Int)
388    boundary = {}
389    ghosts = {}
390    nt = -1
391    for i in range(m):
392        for j in range(n):
393
394            i1 = I(i,j+1)
395            i2 = I(i,j)
396            i3 = I(i+1,j+1)
397            i4 = I(i+1,j)
398
399            #Lower Element
400            nt = E(i,j)
401            if i == m-1:
402                ghosts[nt] = E(1,j)
403            if i == 0:
404                ghosts[nt] = E(m-2,j)
405
406            if i == m-1:
407                boundary[nt, 2] = 'right'
408            if j == 0:
409                boundary[nt, 1] = 'bottom'
410            elements[nt,:] = [i4,i3,i2]
411
412            #Upper Element
413            nt = E(i,j)+1
414            if i == m-1:
415                ghosts[nt] = E(1,j)+1
416            if i == 0:
417                ghosts[nt] = E(m-2,j)+1
418
419            if i == 0:
420                boundary[nt, 2] = 'left'
421            if j == n-1:
422                boundary[nt, 1] = 'top'
423            elements[nt,:] = [i1,i2,i3]
424
425
426    return points, elements, boundary, ghosts
Note: See TracBrowser for help on using the repository browser.