source: anuga_work/development/parallel/run_parallel_sw_merimbula_test.py @ 4282

Last change on this file since 4282 was 3460, checked in by jack, 18 years ago

Moved parallel to development from inundation

File size: 7.6 KB
Line 
1#!/usr/bin/env python
2###
3#########################################################
4#
5#  Main file for parallel mesh testing.
6#
7#  This is a modification of the run_parallel_advection.py
8# file.
9#
10#
11# *) The (new) files that have been added to manage the
12# grid partitioning are
13#    +) pmesh_divide_metis.py: subdivide a pmesh
14#    +) build_submesh.py: build the submeshes on the host
15# processor.
16#    +) build_local.py: build the GA mesh datastructure
17# on each processor.
18#    +) build_commun.py: handle the communication between
19# the host and processors
20#
21# *) Things still to do:
22#    +) Overlap the communication and computation: The
23# communication routines in build_commun.py should be
24# interdispersed in the build_submesh.py and build_local.py
25# files. This will overlap the communication and
26# computation and will be far more efficient. This should
27# be done after more testing and there more confidence in
28# the subpartioning.
29#    +) Much more testing especially with large numbers of
30# processors.
31#  Authors: Linda Stals, Steve Roberts and Matthew Hardy,
32# June 2005
33#
34#
35#
36#########################################################
37import sys
38import pypar    # The Python-MPI interface
39import time
40
41
42from os import sep
43sys.path.append('..'+sep+'pyvolution')
44
45# Numeric arrays
46
47from Numeric import array, zeros, Float
48
49# Print debugging information
50
51from print_stats import print_test_stats, build_full_flag
52
53# pmesh
54
55from shallow_water import Domain
56from parallel_shallow_water import Parallel_Domain
57from pmesh2domain import pmesh_to_domain_instance
58
59# Reuse previous mesh import
60
61from caching import cache
62
63# Mesh partition routines
64
65from pmesh_divide import pmesh_divide_metis
66from build_submesh import build_submesh
67from build_local   import build_local_mesh
68from build_commun  import send_submesh, rec_submesh, extract_hostmesh
69
70###############################
71# Read in processor information
72###############################
73
74numprocs = pypar.size()
75myid = pypar.rank()
76processor_name = pypar.Get_processor_name()
77
78############################
79# Set the initial conditions
80############################
81
82rect = zeros( 4, Float) # Buffer for results
83
84class Set_Stage:
85    """Set an initial condition with constant water height, for x<x0
86    """
87
88    def __init__(self, x0=0.25, x1=0.5, h=1.0):
89        self.x0 = x0
90        self.x1 = x1
91        self.= h
92
93    def __call__(self, x, y):
94        return self.h*((x>self.x0)&(x<self.x1))
95
96#######################
97# Partition the domain
98#######################
99
100if myid == 0:
101
102    # Read in the test files
103
104    filename = 'test-100.tsh'
105#    filename = 'merimbula_10785_1.tsh'
106
107    # Build the whole domain
108   
109    domain_full = pmesh_to_domain_instance(filename, Domain)
110
111#    domain_full = cache(pmesh_to_domain_instance,
112#               (filename, Domain),
113#              dependencies = [filename])
114
115    rect = array(domain_full.xy_extent, Float)
116
117    # Initialise the wave
118
119    domain_full.set_quantity('stage', Set_Stage(200.0,300.0,1.0))
120#    domain_full.set_quantity('stage', Set_Stage(756000.0,756500.0,2.0))
121#    domain_full.set_quantity('stage', Set_Stage(756000.0,756500.0,0.0))
122
123    # Subdivide the domain
124
125    # Note the different arguments compared with pmesh_divide,
126    # pmesh_divide_steve etc.
127   
128    nodes, triangles, boundary, triangles_per_proc, quantities = \
129         pmesh_divide_metis(domain_full, numprocs)
130
131    print triangles_per_proc
132   
133    rect = array(domain_full.xy_extent, Float)
134
135    submesh = build_submesh(nodes, triangles, boundary,\
136                            quantities, triangles_per_proc)
137
138    # Send the mesh partition to the appropriate processor
139
140    for p in range(1, numprocs):
141      send_submesh(submesh, triangles_per_proc, p)
142
143    # Build the local mesh for processor 0
144
145    points, vertices, boundary, quantities, ghost_recv_dict, full_send_dict = \
146             extract_hostmesh(submesh, triangles_per_proc)
147
148# Read in the mesh partition that belongs to this
149# processor (note that the information is in the
150# correct form for the GA data structure
151
152else:
153    points, vertices, boundary, quantities, ghost_recv_dict, full_send_dict \
154            = rec_submesh(0)
155
156
157###########################################
158# Start the computations on each subpartion
159###########################################
160
161#if myid == 0:
162#    print 'ghost'
163#    print ghost_recv_dict
164#processor_name
165#if myid == 0:
166#    print 'full'
167#    print full_send_dict
168
169# The visualiser needs to know the size of the whole domain
170
171pypar.broadcast(rect,0)
172
173domain = Parallel_Domain(points, vertices, boundary,
174                         full_send_dict  = full_send_dict,
175                         ghost_recv_dict = ghost_recv_dict)
176
177# Make a note of which triangles are full and which are ghost
178
179tri_full_flag = build_full_flag(domain, ghost_recv_dict)
180
181try:
182    #domain.initialise_visualiser(rect=rect)
183    #domain.visualiser.coloring['stage'] = True
184    #domain.visualiser.scale_z['stage'] = 0.2
185    #domain.visualiser.scale_z['elevation'] = 0.05
186    pass
187except:
188    print 'No visualiser'
189
190
191
192domain.default_order = 1
193
194#Boundaries
195from parallel_shallow_water import Transmissive_boundary, Reflective_boundary
196
197T = Transmissive_boundary(domain)
198R = Reflective_boundary(domain)
199domain.set_boundary( {'outflow': R, 'inflow': R, 'inner':R, 'exterior': R, 'open':R, 'ghost':None} )
200
201
202domain.set_quantity('stage', quantities['stage'])
203domain.set_quantity('elevation', quantities['elevation'])
204
205domain.store = False
206#domain.filename = 'merimbula-%d' %domain.processor
207
208#---------
209# Evolution
210t0 = time.time()
211
212print 'Processor %d on %s: No of elements %d'%(domain.processor,processor_name,domain.number_of_elements)
213yieldstep = 0.05
214finaltime = 5.0
215
216yieldstep = 1
217finaltime = None
218
219#yieldstep = 1
220#finaltime = 1
221#processor_name
222#for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
223#    if myid == 0:
224#        domain.write_time()
225        #print 'Processor %d, Integral of stage %d'%\
226        #       (domain.processor,domain.quantities['stage'].get_integral())
227        #    print_test_stats(domain, tri_full_flag)
228
229
230# Profiling
231#import profile
232#profiler = profile.Profile()
233#result.dump_stats("profile." + str(numprocs) + "." + str(myid) + ".dat")
234
235## #New hotshot profiling
236## import hotshot
237## profiler = hotshot.Profile("hotshot." + str(numprocs) + "." + str(myid) + ".prof")
238## s = '''for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
239##   if myid == 0:
240##     domain.write_time()
241##   print_test_stats(domain, tri_full_flag)
242
243## '''
244## result = profiler.runctx(s, globals(), locals())
245## profiler.close()
246
247#from vtk_realtime_visualiser import Visualiser
248#V = Visualiser(domain,default_scale_z=100.0)
249#V.coloring['stage'] = True
250#V.coloring['elevation'] = False
251#V.setup['elevation']=True
252#V.updating['stage']=True
253#V.qcolor['stage'] = (0.1,0.4,0.99)
254
255
256#V.start()
257#V.idle.wait()
258#V.idle.clear()
259
260
261
262
263
264for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
265    if myid == 0:
266        domain.write_time()
267        #print_test_stats(domain, tri_full_flag)
268
269#    V.redraw_ready.set()
270#    V.idle.wait()
271#    V.idle.clear()
272#    V.unpaused.wait()
273
274
275#print 'P%d: That took %.2f seconds' %(myid, time.time()-t0)
276#print 'P%d: Communication time %.2f seconds' %(myid, domain.communication_time)
277#print 'P%d: Reduction Communication time %.2f seconds' %(myid, domain.communication_reduce_time)
278#print 'P%d: Broadcast time %.2f seconds' %(myid, domain.communication_broadcast_time)
279
280
281
282if myid == 0:
283    print 'That took %.2f seconds' %(time.time()-t0)
284    print 'Communication time %.2f seconds'%domain.communication_time
285    print 'Reduction Communication time %.2f seconds'%domain.communication_reduce_time
286    print 'Broadcast time %.2f seconds'%domain.communication_broadcast_time
Note: See TracBrowser for help on using the repository browser.