Changeset 8853


Ignore:
Timestamp:
Apr 27, 2013, 5:43:35 PM (12 years ago)
Author:
steve
Message:

Added some unit tests for rate operators using spatial rates

Location:
trunk/anuga_core/source/anuga/operators
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/anuga_core/source/anuga/operators/rate_operators.py

    r8852 r8853  
    6363        self.set_default_rate(default_rate)
    6464
     65
    6566        self.default_rate_invoked = False    # Flag
     67
     68        self.set_areas()
     69        self.set_full_indices()
    6670
    6771    def __call__(self):
     
    8892                y = self.coord_c[:,1]
    8993            else:
    90                 x = self.coord_c[indices,0]
    91                 y = self.coord_c[indices,1]
     94                x = self.coord_c[self.indices,0]
     95                y = self.coord_c[self.indices,1]
    9296            rate = self.get_spatial_rate(x,y,t)
    9397        else:
     
    171175
    172176        if x is None:
    173             x = self.coord_c[:,0]
    174 
    175         if y is None:
    176             y = self.coord_c[:,1]
    177 
     177            assert y is None
     178            if self.indices is None:
     179                x = self.coord_c[:,0]
     180                y = self.coord_c[:,1]
     181            else:
     182                x = self.coord_c[self.indices,0]
     183                y = self.coord_c[self.indices,1]
     184
     185        assert x is not None
     186        assert y is not None
    178187        #print x.shape,y.shape
    179188        assert isinstance(t, (int, float))
     
    235244        #print self.rate
    236245        #print self.rate_spatial , self.rate_callable
     246
     247
     248    def set_areas(self):
     249
     250        if self.indices is None:
     251            self.areas = self.domain.areas
     252            return
     253
     254        if self.indices is []:
     255            self.areas = []
     256            return
     257
     258        self.areas = self.domain.areas[self.indices]
     259
     260    def set_full_indices(self):
     261
     262        if self.indices is None:
     263            self.full_indices = num.where(self.domain.tri_full_flag ==1)[0]
     264            return
     265
     266        if self.indices is []:
     267            self.full_indices = []
     268            return
     269
     270        self.full_indices = num.where(self.domain.tri_full_flag[self.indices] == 1)[0]
     271
     272    def get_Q(self, full_only=True):
     273        """ Calculate current overall discharge
     274        """
     275
     276        if full_only:
     277            if self.rate_spatial:
     278                rate = self.get_spatial_rate() # rate is an array
     279                fid = self.full_indices
     280                return num.sum(self.areas[fid]*rate[fid])*self.factor
     281            else:
     282                rate = self.get_non_spatial_rate() # rate is a scalar
     283                return num.sum(self.areas[fid]*rate)*self.factor
     284        else:
     285            if self.rate_spatial:
     286                rate = self.get_spatial_rate() # rate is an array
     287                return num.sum(self.areas*rate)*self.factor
     288            else:
     289                rate = self.get_non_spatial_rate() # rate is a scalar
     290                return num.sum(self.areas*rate)*self.factor
    237291
    238292    def set_default_rate(self, default_rate):
  • trunk/anuga_core/source/anuga/operators/run_rate_spatial_operator.py

    r8852 r8853  
    77# Import necessary modules
    88#------------------------------------------------------------------------------
     9import numpy
    910from anuga import rectangular_cross
    1011from anuga import Domain
     
    2627                                               len1=length, len2=width)
    2728domain = Domain(points, vertices, boundary)
    28 domain.set_name('rate_polygon') # Output name
     29domain.set_name('output_rate_spatial_operator') # Output name
    2930print domain.statistics()
    3031
     
    123124
    124125op1 = Polygonal_rate_operator(domain, rate=10.0, polygon=polygon2)
     126
     127area1 = numpy.sum(domain.areas[op1.indices])
     128Q1 = 10.0*area1
     129print 'op1 Q ',Q1
     130
    125131op2 = Circular_rate_operator(domain, rate=10.0, radius=0.5, center=(10.0, 3.0))
    126 op3 = Rate_operator(domain, rate = lambda x,y,t: 0.01*(x+y))
    127132
    128 for t in domain.evolve(yieldstep=0.1, finaltime=40.0):
     133area2 = numpy.sum(domain.areas[op2.indices])
     134Q2 = 10.0*area2
     135print 'op2 Q ',Q2
     136
     137
     138def rain(x,y,t):
     139    """Function to calculate "rain"
     140    input x,y should be considered to be numpy arrays
     141    abd t a scalar
     142    """
     143    if t<10:
     144        return (x+y)
     145    else:
     146        return 0*x
     147
     148
     149#op3 = Rate_operator(domain, rate = rain, factor=1e-3)
     150area3 = numpy.sum(domain.areas)
     151Q3 = numpy.sum(op3.get_rate(t)*area3)
     152
     153#------------------------------------------------------------------------------
     154# Evolve system through time
     155#------------------------------------------------------------------------------
     156accum = 0.0
     157yieldstep = 0.1
     158finaltime = 40.0
     159for t in domain.evolve(yieldstep=yieldstep, finaltime=finaltime):
    129160    domain.print_timestepping_statistics()
    130161    domain.print_operator_timestepping_statistics()
     
    137168
    138169
     170    print indent + 'Exact accumultion = ', accum
     171    accum += (Q1+Q2)*yieldstep
    139172
    140173
  • trunk/anuga_core/source/anuga/operators/test_rate_operators.py

    r8852 r8853  
    55import unittest, os
    66import anuga
     7import numpy
    78from anuga import Domain
    89from anuga import Reflective_boundary
     
    403404        domain = Domain(points, vertices)
    404405
     406
     407        area = numpy.sum(domain.areas)
     408
    405409        #Flat surface with 1m of water
    406410        domain.set_quantity('elevation', 0.0)
     
    438442        operator()
    439443
     444
    440445        t = operator.get_time()
     446        Q = operator.get_Q()
    441447        x = operator.coord_c[:,0]
    442448        y = operator.coord_c[:,1]
    443         d = operator.get_timestep()*main_spatial_rate(x,y,t)*factor + 1
     449        rate = main_spatial_rate(x,y,t)*factor
     450        Q_ex = num.sum(domain.areas*rate)
     451        d = operator.get_timestep()*rate + 1
    444452
    445453        #print "d"
    446454        #print d
     455        #print area, Q, Q_ex
    447456        stage_ex = num.array([ 1.0,  1.0,   1.0,  1.0])
    448457        stage_ex[:] = d
     
    457466        assert num.allclose(domain.quantities['xmomentum'].centroid_values, 0.0)
    458467        assert num.allclose(domain.quantities['ymomentum'].centroid_values, 0.0)
    459 
    460     def test_rate_operator_functions_spatial_indices(self):
     468        assert num.allclose(Q_ex, Q)
     469
     470    def test_rate_operator_functions_spatial_with_ghost(self):
    461471        from anuga.config import rho_a, rho_w, eta_w
    462472        from math import pi, cos, sin
     
    475485        domain = Domain(points, vertices)
    476486
     487
     488        area = numpy.sum(domain.areas)
     489
    477490        #Flat surface with 1m of water
    478491        domain.set_quantity('elevation', 0.0)
     
    492505
    493506        # Apply operator to these triangles
    494         indices = [0,1,3]
    495507        factor = 10.0
    496508
     
    502514        default_rate = 0.0
    503515
     516        # kludge to make a ghost cell
     517        domain.tri_full_flag[1] = 0
     518
     519        operator = Rate_operator(domain, rate=main_spatial_rate, factor=factor, \
     520                      default_rate = default_rate)
     521
     522 
     523        # Apply Operator
     524        domain.timestep = 2.0
     525        operator()
     526
     527
     528        t = operator.get_time()
     529        Q_all = operator.get_Q(full_only=False)
     530        Q_full = operator.get_Q()
     531        x = operator.coord_c[:,0]
     532        y = operator.coord_c[:,1]
     533        rate = main_spatial_rate(x,y,t)*factor
     534        Q_ex_all = num.sum(domain.areas*rate)
     535        Q_ex_full = num.sum(num.where(domain.tri_full_flag==1,domain.areas*rate,0.0))
     536        d = operator.get_timestep()*rate + 1
     537
     538        #print "d"
     539        #print d
     540        #print Q_ex_full, Q_ex_all
     541        stage_ex = num.array([ 1.0,  1.0,   1.0,  1.0])
     542        stage_ex[:] = d
     543
     544        if verbose:
     545            print domain.quantities['elevation'].centroid_values
     546            print domain.quantities['stage'].centroid_values
     547            print domain.quantities['xmomentum'].centroid_values
     548            print domain.quantities['ymomentum'].centroid_values
     549
     550        assert num.allclose(domain.quantities['stage'].centroid_values, stage_ex)
     551        assert num.allclose(domain.quantities['xmomentum'].centroid_values, 0.0)
     552        assert num.allclose(domain.quantities['ymomentum'].centroid_values, 0.0)
     553        assert num.allclose(Q_ex_all, Q_all)
     554        assert num.allclose(Q_ex_full, Q_full)
     555
     556    def test_rate_operator_functions_spatial_indices(self):
     557        from anuga.config import rho_a, rho_w, eta_w
     558        from math import pi, cos, sin
     559
     560        a = [0.0, 0.0]
     561        b = [0.0, 2.0]
     562        c = [2.0, 0.0]
     563        d = [0.0, 4.0]
     564        e = [2.0, 2.0]
     565        f = [4.0, 0.0]
     566
     567        points = [a, b, c, d, e, f]
     568        #             bac,     bce,     ecf,     dbe
     569        vertices = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     570
     571        domain = Domain(points, vertices)
     572
     573        #Flat surface with 1m of water
     574        domain.set_quantity('elevation', 0.0)
     575        domain.set_quantity('stage', 1.0)
     576        domain.set_quantity('friction', 0.0)
     577
     578        Br = Reflective_boundary(domain)
     579        domain.set_boundary({'exterior': Br})
     580
     581        verbose = False
     582
     583        if verbose:
     584            print domain.quantities['elevation'].centroid_values
     585            print domain.quantities['stage'].centroid_values
     586            print domain.quantities['xmomentum'].centroid_values
     587            print domain.quantities['ymomentum'].centroid_values
     588
     589        # Apply operator to these triangles
     590        indices = [0,1,3]
     591        factor = 10.0
     592
     593
     594        def main_spatial_rate(x,y,t):
     595            # x and y should be an n by 1 array
     596            return x + y
     597
     598        default_rate = 0.0
     599
    504600
    505601        operator = Rate_operator(domain, rate=main_spatial_rate, factor=factor, \
     
    512608
    513609        t = operator.get_time()
     610        Q = operator.get_Q()
    514611        x = operator.coord_c[indices,0]
    515612        y = operator.coord_c[indices,1]
    516         d = operator.get_timestep()*main_spatial_rate(x,y,t)*factor + 1
     613        rate = main_spatial_rate(x,y,t)*factor
     614        Q_ex = num.sum(domain.areas[indices]*rate)
     615        d = operator.get_timestep()*rate + 1
     616
    517617
    518618        #print "d"
     
    530630        assert num.allclose(domain.quantities['xmomentum'].centroid_values, 0.0)
    531631        assert num.allclose(domain.quantities['ymomentum'].centroid_values, 0.0)
    532            
     632        assert num.allclose(Q_ex, Q)
     633
     634    def test_rate_operator_functions_empty_indices(self):
     635        from anuga.config import rho_a, rho_w, eta_w
     636        from math import pi, cos, sin
     637
     638        a = [0.0, 0.0]
     639        b = [0.0, 2.0]
     640        c = [2.0, 0.0]
     641        d = [0.0, 4.0]
     642        e = [2.0, 2.0]
     643        f = [4.0, 0.0]
     644
     645        points = [a, b, c, d, e, f]
     646        #             bac,     bce,     ecf,     dbe
     647        vertices = [[1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     648
     649        domain = Domain(points, vertices)
     650
     651        #Flat surface with 1m of water
     652        domain.set_quantity('elevation', 0.0)
     653        domain.set_quantity('stage', 1.0)
     654        domain.set_quantity('friction', 0.0)
     655
     656        Br = Reflective_boundary(domain)
     657        domain.set_boundary({'exterior': Br})
     658
     659        verbose = False
     660
     661        if verbose:
     662            print domain.quantities['elevation'].centroid_values
     663            print domain.quantities['stage'].centroid_values
     664            print domain.quantities['xmomentum'].centroid_values
     665            print domain.quantities['ymomentum'].centroid_values
     666
     667        # Apply operator to these triangles
     668        indices = []
     669        factor = 10.0
     670
     671
     672        def main_spatial_rate(x,y,t):
     673            # x and y should be an n by 1 array
     674            return x + y
     675
     676        default_rate = 0.0
     677
     678        domain.tri_full_flag[0] = 0
     679        operator = Rate_operator(domain, rate=main_spatial_rate, factor=factor, \
     680                      indices=indices, default_rate = default_rate)
     681
     682
     683        # Apply Operator
     684        domain.timestep = 2.0
     685        operator()
     686
     687        t = operator.get_time()
     688        Q = operator.get_Q()
     689        x = operator.coord_c[indices,0]
     690        y = operator.coord_c[indices,1]
     691        rate = main_spatial_rate(x,y,t)*factor
     692        Q_ex = num.sum(domain.areas[indices]*rate)
     693        d = operator.get_timestep()*rate + 1
     694
     695        #print Q_ex, Q
     696        #print indices
     697        #print "d"
     698        print d
     699        stage_ex = num.array([ 1.0,  1.0,   1.0,  1.0])
     700        stage_ex[indices] = d
     701
     702        if verbose:
     703            print domain.quantities['elevation'].centroid_values
     704            print domain.quantities['stage'].centroid_values
     705            print domain.quantities['xmomentum'].centroid_values
     706            print domain.quantities['ymomentum'].centroid_values
     707
     708        assert num.allclose(domain.quantities['stage'].centroid_values, stage_ex)
     709        assert num.allclose(domain.quantities['xmomentum'].centroid_values, 0.0)
     710        assert num.allclose(domain.quantities['ymomentum'].centroid_values, 0.0)
     711        assert num.allclose(Q_ex, Q)
     712
    533713if __name__ == "__main__":
    534714    suite = unittest.makeSuite(Test_rate_operators, 'test')
Note: See TracChangeset for help on using the changeset viewer.