source: inundation/ga/storm_surge/parallel/parallel_advection.py @ 1452

Last change on this file since 1452 was 1436, checked in by steve, 20 years ago
File size: 6.1 KB
RevLine 
[1363]1import sys
2from os import sep
3sys.path.append('..'+sep+'pyvolution')
4
5"""Class Parallel_Domain -
62D triangular domains for finite-volume computations of
7the advection equation, with extra structures to allow
8communication between other Parallel_Domains and itself
9
10This module contains a specialisation of class Domain from module advection.py
11
12Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
13Geoscience Australia, 2004
14"""
15
[1387]16from advection import *
17Advection_Domain = Domain
[1424]18from Numeric import zeros, Float, Int, ones, allclose, array
[1407]19import pypar
[1363]20
[1407]21
[1387]22class Parallel_Domain(Advection_Domain):
[1363]23
[1424]24    def __init__(self, coordinates, vertices, boundary = None,
25                 full_send_dict = None, ghost_recv_dict = None,
[1414]26                 velocity = None):
[1363]27
[1424]28        self.processor = pypar.rank()
29        self.numproc   = pypar.size()
[1426]30        #print 'Processor %d'%self.processor
31        #velocity = [(self.processor+1),0.0]
[1424]32
[1426]33        #print 'velocity',velocity
[1424]34
[1387]35        Advection_Domain.__init__(self, coordinates, vertices, boundary, velocity)
[1363]36
[1387]37        N = self.number_of_elements
38
[1414]39        self.processor = pypar.rank()
40        self.numproc   = pypar.size()
[1407]41
[1424]42        self.full_send_dict  = full_send_dict
43        self.ghost_recv_dict = ghost_recv_dict
[1363]44
[1424]45        #print self.full_send_dict
46        #print self.ghost_recv_dict
[1407]47
[1363]48    def check_integrity(self):
[1387]49        Advection_Domain.check_integrity(self)
[1363]50
[1387]51        msg = 'Will need to check global and local numbering'
[1363]52        assert self.conserved_quantities[0] == 'stage', msg
53
54
[1407]55
56    def update_timestep(self, yieldstep, finaltime):
[1414]57
58        # Calculate local timestep
[1407]59        Advection_Domain.update_timestep(self, yieldstep, finaltime)
60
[1414]61        # For some reason it looks like pypar only reduces numeric arrays
62        # hence we need to create some dummy arrays for communication
63        ltimestep = ones( 1, Float )
64        ltimestep[0] = self.timestep
[1407]65
[1414]66        gtimestep = zeros( 1, Float) # Buffer for results
[1407]67
[1414]68        pypar.raw_reduce(ltimestep, gtimestep, pypar.MIN, 0)
69        pypar.broadcast(gtimestep,0)
[1424]70        #pypar.Barrier()
[1407]71
[1414]72        self.timestep = gtimestep[0]
[1407]73
[1414]74
75
[1402]76    def update_ghosts(self):
[1414]77
78        # We must send the information from the full cells and
79        # receive the information for the ghost cells
80        # We have a dictionary of lists with ghosts expecting updates from
81        # the separate processors
82
[1436]83        from weave import converters
84
[1414]85        stage_cv = self.quantities['stage'].centroid_values
86
[1424]87        # update of non-local ghost cells
[1426]88        for iproc in range(self.numproc):
[1414]89
[1426]90            if iproc == self.processor:
91                #Send data from iproc processor to other processors
92                for send_proc in self.full_send_dict:
93                    if send_proc != iproc:
94                        Idf  = self.full_send_dict[send_proc][0]
95                        Xout = self.full_send_dict[send_proc][1]
[1436]96                        N = len(Xout)
97
98                        """
99                        # Original python Code
100                        for i in range(N):
[1426]101                            Xout[i] = stage_cv[Idf[i]]
[1436]102                        """
103                        code1 = """
104                        for (int i=0; i<N ; i++){
105                            Xout(i) = stage_cv(Idf(i));
106                        }
107                        """
108                        weave.inline(code1, ['stage_cv','Idf','Xout','N'],
109                                     type_converters = converters.blitz, compiler='gcc');
[1426]110
111                        pypar.send(Xout,send_proc)
[1428]112                        #print 'Processor %d Sending to Processor %d'%(self.processor,send_proc)
[1426]113            else:
114                #Receive data from the iproc processor
115                if  self.ghost_recv_dict.has_key(iproc):
116                    Idg = self.ghost_recv_dict[iproc][0]
117                    X   = self.ghost_recv_dict[iproc][1]
118
119                    X = pypar.receive(iproc,X)
[1436]120                    N = len(X)
[1428]121                    #print 'Processor %d receiving from Processor %d'%(self.processor,iproc)
[1436]122                    for i in range(N):
[1426]123                        stage_cv[Idg[i]] = X[i]
124            pypar.barrier()
125
[1424]126        #local update of ghost cells
127        iproc = self.processor
128        if self.full_send_dict.has_key(iproc):
129            Idf  = self.full_send_dict[iproc][0]
130            #print Idf
131            Idg  = self.ghost_recv_dict[iproc][0]
[1436]132            N = len(Idg)
[1424]133            #print Idg
[1436]134            for i in range(N):
[1424]135                #print i,Idg[i],Idf[i]
136                stage_cv[Idg[i]] = stage_cv[Idf[i]]
[1414]137
[1363]138
[1424]139#        if self.ghosts is not None:
140#            stage_cv = self.quantities['stage'].centroid_values
141#            for triangle in self.ghosts:
142#                stage_cv[triangle] = stage_cv[self.ghosts[triangle]]
[1407]143
[1424]144
[1407]145    def write_time(self):
146        if self.min_timestep == self.max_timestep:
147            print 'Processor %d, Time = %.4f, delta t = %.8f, steps=%d (%d)'\
148                  %(self.processor, self.time, self.min_timestep, self.number_of_steps,
149                    self.number_of_first_order_steps)
150        elif self.min_timestep > self.max_timestep:
151            print 'Processor %d, Time = %.4f, steps=%d (%d)'\
152                  %(self.processor, self.time, self.number_of_steps,
153                    self.number_of_first_order_steps)
154        else:
155            print 'Processor %d, Time = %.4f, delta t in [%.8f, %.8f], steps=%d (%d)'\
156                  %(self.processor, self.time, self.min_timestep,
157                    self.max_timestep, self.number_of_steps,
158                    self.number_of_first_order_steps)
159
160
161
[1387]162    def evolve(self, yieldstep = None, finaltime = None):
163        """Specialisation of basic evolve method from parent class
[1363]164        """
165
[1387]166        #Initialise real time viz if requested
[1407]167        if self.time == 0.0:
168            pass
[1363]169
[1387]170        #Call basic machinery from parent class
171        for t in Advection_Domain.evolve(self, yieldstep, finaltime):
[1363]172
[1387]173            #Pass control on to outer loop for more specific actions
174            yield(t)
[1363]175
176
177
[1414]178
Note: See TracBrowser for help on using the repository browser.