Changeset 5873


Ignore:
Timestamp:
Oct 28, 2008, 5:19:47 PM (16 years ago)
Author:
ole
Message:

Implemented default_rate to allow ANUGA to continue beyond data used by forcing functions such as Rainfall
This should address ticket:265

Location:
anuga_core/source/anuga/shallow_water
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/shallow_water/shallow_water_domain.py

    r5866 r5873  
    109109from anuga.config import use_centroid_velocities
    110110
     111from anuga.fit_interpolate.interpolate import Modeltime_too_late, Modeltime_too_early
    111112
    112113from anuga.utilities.polygon import inside_polygon, polygon_area, is_inside_polygon
    113114
     115from types import IntType, FloatType
    114116
    115117
     
    16431645    radius [m]: Size of circular area
    16441646    polygon:    Arbitrary polygon.
     1647    default_rate: Rate to be used if rate fails (e.g. if model time exceeds its data)
     1648                  Admissible types: None, constant number or function of t
    16451649
    16461650
     
    16601664                 center=None, radius=None,
    16611665                 polygon=None,
     1666                 default_rate=None,
    16621667                 verbose=False):
    16631668                     
     
    17681773                msg += 'specified region: %s' %inlet_region
    17691774                raise Exception, msg
    1770 
     1775           
     1776        # Check and store default_rate
     1777        msg = 'Keyword argument default_rate must be either None '
     1778        msg += 'or a function of time.\n I got %s' %(str(default_rate))
     1779        assert default_rate is None or \
     1780               type(default_rate) in [IntType, FloatType] or \
     1781               callable(default_rate), msg
     1782       
     1783        if default_rate is not None:
     1784
     1785            # If it is a constant, make it a function
     1786            if not callable(default_rate):
     1787                tmp = default_rate
     1788                default_rate = lambda t: tmp
     1789
     1790           
     1791            # Check that default_rate is a function of one argument
     1792            try:
     1793                default_rate(0.0)
     1794            except:
     1795                raise Exception, msg
     1796
     1797        self.default_rate = default_rate
     1798       
    17711799
    17721800    def __call__(self, domain):
     
    17751803
    17761804        # Call virtual method allowing local modifications
    1777         rate = self.update_rate(domain.get_time())
     1805
     1806        t = domain.get_time()
     1807        try:
     1808            rate = self.update_rate(t)
     1809        except (Modeltime_too_late, Modeltime_too_early), e:
     1810            if self.default_rate is None:
     1811                raise Exception, e # Reraise exception
     1812            else:
     1813                # FIXME: Issue a warning first time this happens (See changeset:5657)
     1814                rate = self.default_rate(t)
     1815               
     1816
    17781817        if rate is None:
    17791818            msg = 'Attribute rate must be specified in General_forcing'
     
    18791918                 center=None, radius=None,
    18801919                 polygon=None,
     1920                 default_rate=None,                 
    18811921                 verbose=False):
    18821922
     
    18851925            rain = lambda t: rate(t)/1000.0
    18861926        else:
    1887             rain = rate/1000.0           
     1927            rain = rate/1000.0
     1928
     1929        if default_rate is not None:   
     1930            if callable(default_rate):
     1931                default_rain = lambda t: default_rate(t)/1000.0
     1932            else:
     1933                default_rain = default_rate/1000.0
     1934        else:
     1935            default_rain = None
     1936
     1937
     1938           
    18881939           
    18891940        General_forcing.__init__(self,
     
    18931944                                 center=center, radius=radius,
    18941945                                 polygon=polygon,
     1946                                 default_rate=default_rain,                                 
    18951947                                 verbose=verbose)
    18961948
     
    19552007                 center=None, radius=None,
    19562008                 polygon=None,
     2009                 default_rate=None,                                                 
    19572010                 verbose=False):                 
    19582011
     
    19652018                                 center=center, radius=radius,
    19662019                                 polygon=polygon,
     2020                                 default_rate=default_rate,
    19672021                                 verbose=verbose)
    19682022
     
    19752029        """
    19762030
    1977        
    1978        
    19792031        if callable(self.rate):
    19802032            _rate = self.rate(t)/self.exchange_area
  • anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py

    r5862 r5873  
    24012401
    24022402
    2403         # FIXME: Do Time dependent rainfall
    2404 
    2405 
    24062403
    24072404    def test_rainfall_restricted_by_polygon(self):
     
    24452442        assert allclose(domain.quantities['stage'].explicit_update[2:], 0)       
    24462443       
    2447         # FIXME: Do Time dependent rainfall with poly
     2444
     2445
     2446    def test_time_dependent_rainfall_restricted_by_polygon(self):
     2447
     2448        a = [0.0, 0.0]
     2449        b = [0.0, 2.0]
     2450        c = [2.0, 0.0]
     2451        d = [0.0, 4.0]
     2452        e = [2.0, 2.0]
     2453        f = [4.0, 0.0]
     2454
     2455        points = [a, b, c, d, e, f]
     2456        #bac, bce, ecf, dbe
     2457        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     2458
     2459
     2460        domain = Domain(points, vertices)
     2461
     2462        #Flat surface with 1m of water
     2463        domain.set_quantity('elevation', 0)
     2464        domain.set_quantity('stage', 1.0)
     2465        domain.set_quantity('friction', 0)
     2466
     2467        Br = Reflective_boundary(domain)
     2468        domain.set_boundary({'exterior': Br})
     2469
     2470        # Setup only one forcing term, time dependent rainfall restricted to a polygon enclosing triangle #1 (bce)
     2471        domain.forcing_terms = []
     2472        R = Rainfall(domain, rate=lambda t: 3*t + 7, polygon = [[1,1], [2,1], [2,2], [1,2]])
     2473
     2474        assert allclose(R.exchange_area, 1)
     2475       
     2476        domain.forcing_terms.append(R)
     2477
     2478
     2479        domain.time = 10.
     2480
     2481        domain.compute_forcing_terms()
     2482        #print domain.quantities['stage'].explicit_update
     2483       
     2484        assert allclose(domain.quantities['stage'].explicit_update[1], (3*domain.time+7)/1000)
     2485        assert allclose(domain.quantities['stage'].explicit_update[0], 0)
     2486        assert allclose(domain.quantities['stage'].explicit_update[2:], 0)       
     2487       
     2488
     2489
     2490    def test_time_dependent_rainfall_restricted_by_polygon_with_default(self):
     2491        """test_time_dependent_rainfall_restricted_by_polygon_with_default
     2492
     2493        Test that default rainfall can be used when given rate runs out of data.
     2494        """
     2495        a = [0.0, 0.0]
     2496        b = [0.0, 2.0]
     2497        c = [2.0, 0.0]
     2498        d = [0.0, 4.0]
     2499        e = [2.0, 2.0]
     2500        f = [4.0, 0.0]
     2501
     2502        points = [a, b, c, d, e, f]
     2503        #bac, bce, ecf, dbe
     2504        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     2505
     2506
     2507        domain = Domain(points, vertices)
     2508
     2509        #Flat surface with 1m of water
     2510        domain.set_quantity('elevation', 0)
     2511        domain.set_quantity('stage', 1.0)
     2512        domain.set_quantity('friction', 0)
     2513
     2514        Br = Reflective_boundary(domain)
     2515        domain.set_boundary({'exterior': Br})
     2516
     2517        # Setup only one forcing term, time dependent rainfall that expires at t==20
     2518        from anuga.fit_interpolate.interpolate import Modeltime_too_late
     2519        def main_rate(t):
     2520            if t > 20:
     2521                msg = 'Model time exceeded.'
     2522                raise Modeltime_too_late, msg
     2523            else:
     2524                return 3*t + 7
     2525       
     2526        domain.forcing_terms = []
     2527        R = Rainfall(domain, rate=main_rate, polygon = [[1,1], [2,1], [2,2], [1,2]],
     2528                     default_rate=5.0)
     2529
     2530        assert allclose(R.exchange_area, 1)
     2531       
     2532        domain.forcing_terms.append(R)
     2533
     2534
     2535        domain.time = 10.
     2536
     2537        domain.compute_forcing_terms()
     2538        #print domain.quantities['stage'].explicit_update
     2539       
     2540        assert allclose(domain.quantities['stage'].explicit_update[1], (3*domain.time+7)/1000)
     2541        assert allclose(domain.quantities['stage'].explicit_update[0], 0)
     2542        assert allclose(domain.quantities['stage'].explicit_update[2:], 0)       
     2543
     2544
     2545        domain.time = 100.
     2546        domain.quantities['stage'].explicit_update[:] = 0.0  # Reset
     2547        domain.compute_forcing_terms()
     2548        #print domain.quantities['stage'].explicit_update
     2549       
     2550        assert allclose(domain.quantities['stage'].explicit_update[1], 5.0/1000) # Default value
     2551        assert allclose(domain.quantities['stage'].explicit_update[0], 0)
     2552        assert allclose(domain.quantities['stage'].explicit_update[2:], 0)       
     2553       
    24482554
    24492555
     
    60136119    #suite = unittest.makeSuite(Test_Shallow_Water,'test_tight_slope_limiters')
    60146120    #suite = unittest.makeSuite(Test_Shallow_Water,'test_get_maximum_inundation_from_sww')
    6015     #suite = unittest.makeSuite(Test_Shallow_Water,'test_temp')   
     6121    #suite = unittest.makeSuite(Test_Shallow_Water,'test_time_dependent_rainfall_restricted_by_polygon')   
    60166122   
    60176123
Note: See TracChangeset for help on using the changeset viewer.