Changeset 851


Ignore:
Timestamp:
Feb 8, 2005, 7:07:56 PM (20 years ago)
Author:
ole
Message:

First cut at a spatio-temporal boundary.
Need to improve the test, though.

Location:
inundation/ga/storm_surge/pyvolution
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • inundation/ga/storm_surge/pyvolution/domain.py

    r850 r851  
    270270                raise msg
    271271
     272               
    272273    def set_region(self, functions):
    273274        # The order of functions in the list is used.
  • inundation/ga/storm_surge/pyvolution/generic_boundary_conditions.py

    r850 r851  
    187187        #any tagged boundary later on.
    188188       
    189         midpoint_coordinates = zeros( (len(domain.boundary), 2), Float)
     189        self.midpoint_coordinates = zeros( (len(domain.boundary), 2), Float)
    190190        boundary_keys = domain.boundary.keys()
     191       
     192        #Record ordering #FIXME: should this happen in domain.py
     193        self.boundary_indices = {}
     194       
    191195        for i, (vol_id, edge_id) in enumerate(boundary_keys):
    192196           
     
    199203            if edge_id == 1: m = array([(x0 + x2)/2, (y0 + y2)/2])
    200204            if edge_id == 2: m = array([(x1 + x0)/2, (y1 + y0)/2])           
    201             midpoint_coordinates[i,:] = m
    202        
    203         self.midpoint_coordinates = midpoint_coordinates   
     205            self.midpoint_coordinates[i,:] = m
     206           
     207            self.boundary_indices[(vol_id, edge_id)] = i
     208       
    204209       
    205         self.F = file_function(filename, domain, interpolation_points=midpoint_coordinates)
     210        self.F = file_function(filename, domain,
     211                               interpolation_points=self.midpoint_coordinates)
    206212        self.domain = domain
    207213
    208214        #Test
    209         q = self.F(0, 0, 0)
     215        q = self.F(0, point_id=0)
    210216
    211217        d = len(domain.conserved_quantities)
    212         msg = 'Values specified in file %s must be a list or an array of length %d' %(filename, d)
     218        msg = 'Values specified in file %s must be ' %filename
     219        msg += ' a list or an array of length %d' %d
    213220        assert len(q) == d, msg
    214221
     
    226233
    227234        if vol_id is not None and edge_id is not None:
    228             x, y = self.midpoint_coordinates[ vol_id, edge_id ]
    229             return self.F(t, x, y)
     235            i = self.boundary_indices[ vol_id, edge_id ]
     236            return self.F(t, point_id = i)
    230237        else:
    231             return self.F(t)
     238            return self.F(t) #What should the semantics be?
    232239
    233240
  • inundation/ga/storm_surge/pyvolution/shallow_water.py

    r850 r851  
    941941        except Exception, e:
    942942            msg = 'Function %s could not be executed:\n%s' %(f, e)
     943            #FIXME: Reconsider this semantics
    943944            raise msg
    944945                   
  • inundation/ga/storm_surge/pyvolution/test_shallow_water.py

    r850 r851  
    24152415        Bd = Dirichlet_boundary([0.3,0,0])     
    24162416        Bt = Transmissive_boundary(domain1)
    2417         domain1.set_boundary({'left': Bd, 'right': Bt, 'top': Br, 'bottom': Br})
     2417        domain1.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
    24182418
    24192419        #Initial condition
     
    24522452        domain2.reduction = domain1.reduction
    24532453        domain2.smooth = False
    2454         domain2.visualise = True
     2454        domain2.visualise = False
    24552455        domain2.default_order = 2
    24562456       
     
    24652465       
    24662466
    2467         #FIXME: Continue from here!!!!!!!
    2468         return 
    2469                
    24702467        Bf = Spatio_temporal_boundary(domain1.filename + '.' + domain1.format,
    24712468                                      domain2)
    2472         domain2.set_boundary({'right':Bt, 'bottom':Br, 'diagonal':Bf})
     2469        domain2.set_boundary({'right':Br, 'bottom':Br, 'diagonal':Bf})
    24732470
    24742471        #Initial condition
     
    24862483        cv2 = domain2.quantities['stage'].centroid_values
    24872484       
    2488         print take(cv1, (12,14,16))  #Right
    2489         print take(cv2, (4,6,8))
    2490        
     2485        #print take(cv1, (12,14,16))  #Right
     2486        #print take(cv2, (4,6,8))
    24912487        #print take(cv1, (0,6,12))  #Bottom     
    2492        
    2493         assert allclose( take(cv1, (12,14,16)), take(cv2, (4,6,8))) #RHS
    2494         assert allclose( take(cv1, (0,6,12)), take(cv2, (0,1,4))) #Bottom       
     2488        #print take(cv2, (0,1,4))
     2489        #print take(cv1, (0,8,16))  #Diag       
     2490        #print take(cv2, (0,3,8))       
     2491        #assert allclose( take(cv1, (12,14,16)), take(cv2, (4,6,8))) #RHS
     2492        #assert allclose( take(cv1, (0,6,12)), take(cv2, (0,1,4))) #Bottom     
    24952493       
    24962494        #Cleanup
    2497         os.remove(domain1.filename + '.' + domain1.format)
    2498    
     2495        try:
     2496            os.remove(domain1.filename + '.' + domain1.format)
     2497        except:
     2498            pass
     2499             
    24992500#-------------------------------------------------------------
    25002501if __name__ == "__main__":
    2501     #suite = unittest.makeSuite(TestCase,'test')
    2502     suite = unittest.makeSuite(TestCase,'test_spatio_temporal_boundary')
     2502    suite = unittest.makeSuite(TestCase,'test')
     2503    #suite = unittest.makeSuite(TestCase,'test_spatio_temporal_boundary')
    25032504    runner = unittest.TextTestRunner()
    25042505    runner.run(suite)
  • inundation/ga/storm_surge/pyvolution/util.py

    r850 r851  
    123123    quantities = ['stage', 'xmomentum', 'ymomentum']
    124124   
    125     interpolation_points decides at which points interpolated quantities are to be computed
     125    interpolation_points decides at which points interpolated
     126    quantities are to be computed whenever object is called.
     127   
     128   
     129   
    126130    If None, return average value
    127131    """
     
    133137        will be checked and possibly modified
    134138       
    135 
    136 
    137139        All times are assumed to be in UTC
    138140        """
     
    213215        msg = 'File %s must list time as a monotonuosly ' %self.filename
    214216        msg += 'increasing sequence'
    215         assert alltrue( time[1:] - time[:-1] > 0 ), msg
     217        assert alltrue(time[1:] - time[:-1] > 0 ), msg 
    216218       
    217219
     
    227229           
    228230            ####self.Q = zeros( (len(time),
    229              
    230             for i, t in enumerate(time[:]):
     231            self.T = time[:]
     232            self.index = 0 #Initial index       
     233
     234            self.values = {}               
     235            for name in self.quantities:
     236                self.values[name] = zeros( (len(self.T),
     237                                            len(interpolation_points)),
     238                                            Float)                 
     239           
     240            for i, t in enumerate(self.T):
    231241   
    232242                #Interpolate quantities at this timestep
     
    238248                                         verbose = False)
    239249
    240                 for name in self.quantities:                           
    241                     print t, name, interpol.interpolate(fid.variables[name][i,:])                   
     250                for name in self.quantities:
     251                    self.values[name][i, :] =\
     252                    interpol.interpolate(fid.variables[name][i,:])   
    242253
    243254        else:
    244255            pass
    245256
    246         self.T = time[:]
    247        
    248         return
    249        
    250         fid = open(self.filename)       
    251         lines = fid.readlines()
    252         fid.close()
    253        
    254         N = len(lines)
    255         d = self.number_of_values
    256 
    257         T = zeros(N, Float)       #Time
    258         Q = zeros((N, d), Float)  #Values
    259        
    260         for i, line in enumerate(lines):
    261             fields = line.split(',')
    262             realtime = calendar.timegm(time.strptime(fields[0], time_format))
    263 
    264             T[i] = realtime - self.starttime
    265 
    266             for j, value in enumerate(fields[1].split()):
    267                 Q[i, j] = float(value)
    268 
    269 
    270 
    271         self.T = T     #Time
    272         self.Q = Q     #Values
    273         self.index = 0 #Initial index
    274 
    275        
     257    def __repr__(self):
     258        return 'File function'
     259
     260    def __call__(self, t, x=None, y=None, point_id = None):
     261        """Evaluate f(t, point_id)
     262       
     263        Inputs:
     264          t: time - Model time (tau = domain.starttime-self.starttime+t) 
     265                    must lie within existing timesteps   
     266          point_id: index of one of the preprocessed points.
     267                    If point_id is None all preprocessed points are computed
     268
     269          FIXME: point_id could also be a slice     
     270          FIXME: One could allow arbitrary x, y coordinates
     271          (requires computation of a new interpolator)
     272          FIXME: What if x and y are vectors?
     273        """
     274
     275        from math import pi, cos, sin, sqrt
     276        from Numeric import zeros, Float
     277
     278        #Find time tau such that
     279        #
     280        # domain.starttime + t == self.starttime + tau
     281       
     282        if self.domain is not None:
     283            tau = self.domain.starttime-self.starttime+t
     284        else:
     285            tau = t
     286               
     287        msg = 'Time interval derived from file %s (%s:%s) does not match model time: %s'\
     288              %(self.filename, self.T[0], self.T[1], tau)
     289        if tau < self.T[0]: raise msg
     290        if tau > self.T[-1]: raise msg       
     291
     292        oldindex = self.index #Time index
     293
     294        #Find time slot
     295        while tau > self.T[self.index]: self.index += 1
     296        while tau < self.T[self.index]: self.index -= 1
     297
     298        #t is now between index and index+1
     299        ratio = (tau - self.T[self.index])/\
     300                (self.T[self.index+1] - self.T[self.index])
     301
     302               
     303        #Compute interpolated values
     304        q = zeros( len(self.quantities), Float)
     305       
     306        for i, name in enumerate(self.quantities):
     307            Q = self.values[name]   
     308
     309            q[i] = Q[self.index, point_id] +\
     310                 ratio*(Q[self.index+1, point_id] - Q[self.index, point_id])
     311
     312           
     313        #Return vector of interpolated values
     314        return q
     315               
    276316             
    277317class File_function_ASCII:
     
    430470        return 'File function'
    431471
    432        
    433 
    434     def __call__(self, t, x=None, y=None):
     472    def __call__(self, t, x=None, y=None, point_id=None):
    435473        """Evaluate f(t,x,y)
    436474
     
    438476        result is a vector of same length as x and y
    439477        FIXME: Naaaa
     478       
     479        FIXME: Rethink semantics when x,y are vectors.
    440480        """
    441481
Note: See TracChangeset for help on using the changeset viewer.