Changeset 609


Ignore:
Timestamp:
Nov 22, 2004, 4:05:25 PM (20 years ago)
Author:
ole
Message:

First unit tests of wind field

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

Legend:

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

    r566 r609  
    975975                    phi = self.phi                 
    976976
     977       
     978
    977979                #Convert to radians
    978980                phi = phi*pi/180
    979        
     981
     982               
    980983                #Compute velocity vector (u, v)
    981984                u = s*cos(phi)
  • inundation/ga/storm_surge/pyvolution/test_shallow_water.py

    r443 r609  
    77from Numeric import allclose, array, zeros, ones, Float
    88from shallow_water import *
     9
     10
     11
     12#Variable windfield implemented using functions
     13def speed(x,y,t):
     14    """Large speeds halfway between center and edges
     15    Low speeds at center and edges
     16    """
     17   
     18    from math import sqrt, exp, cos, pi
     19   
     20    r = sqrt(x**2 + y**2)
     21
     22    factor = exp( -(r-0.15)**2 )
     23
     24    return 4000 * factor * (cos(t*2*pi/150) + 2)
     25
     26
     27def angle(x,y,t):
     28    """Rotating field
     29    """
     30    from math import sqrt, atan, pi
     31
     32    r = sqrt(x**2 + y**2)   
     33   
     34    angle = atan(y/x)
     35
     36    if x < 0:
     37        angle+=pi #atan in ]-pi/2; pi/2[
     38
     39    #Take normal direction
     40    angle -= pi/2
     41   
     42    #Ensure positive radians   
     43    if angle < 0:
     44        angle += 2*pi
     45
     46    return angle/pi*180
     47
    948
    1049       
     
    586625        assert allclose(domain.quantities['ymomentum'].explicit_update, 0)
    587626       
     627       
     628    def test_manning_friction(self):
     629        from config import g
     630       
     631        a = [0.0, 0.0]
     632        b = [0.0, 2.0]
     633        c = [2.0, 0.0]
     634        d = [0.0, 4.0]
     635        e = [2.0, 2.0]
     636        f = [4.0, 0.0]
     637
     638        points = [a, b, c, d, e, f]
     639        #bac, bce, ecf, dbe
     640        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     641       
     642        domain = Domain(points, vertices)
     643
     644        #Set up for a gradient of (3,0) at mid triangle         
     645        def slope(x, y):
     646            return 3*x
     647
     648        h = 0.1
     649        def level(x,y):
     650            return slope(x,y)+h
     651
     652        eta = 0.07
     653        domain.set_quantity('elevation', slope)
     654        domain.set_quantity('level', level)
     655        domain.set_quantity('friction', eta)       
     656
     657        for name in domain.conserved_quantities:
     658            assert allclose(domain.quantities[name].explicit_update, 0)
     659            assert allclose(domain.quantities[name].semi_implicit_update, 0)
     660           
     661        domain.compute_forcing_terms()                                   
     662
     663        assert allclose(domain.quantities['level'].explicit_update, 0)
     664        assert allclose(domain.quantities['xmomentum'].explicit_update, -g*h*3)
     665        assert allclose(domain.quantities['ymomentum'].explicit_update, 0)
     666
     667        assert allclose(domain.quantities['level'].semi_implicit_update, 0)
     668        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, 0)
     669        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)       
     670
     671        #Create some momentum for friction to work with
     672        domain.set_quantity('xmomentum', 1)
     673        S = -g * eta**2 / h**(7.0/3)
     674
     675        domain.compute_forcing_terms()                                   
     676        assert allclose(domain.quantities['level'].semi_implicit_update, 0)
     677        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, S)
     678        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 0)       
     679
     680        #A more complex example
     681        domain.quantities['level'].semi_implicit_update[:] = 0.0
     682        domain.quantities['xmomentum'].semi_implicit_update[:] = 0.0
     683        domain.quantities['ymomentum'].semi_implicit_update[:] = 0.0       
     684       
     685        domain.set_quantity('xmomentum', 3)
     686        domain.set_quantity('ymomentum', 4)       
     687
     688        S = -g * eta**2 * 5 / h**(7.0/3)
     689
     690
     691        domain.compute_forcing_terms()
     692
     693        assert allclose(domain.quantities['level'].semi_implicit_update, 0)
     694        assert allclose(domain.quantities['xmomentum'].semi_implicit_update, 3*S)
     695        assert allclose(domain.quantities['ymomentum'].semi_implicit_update, 4*S)       
     696
     697    def test_constant_wind_stress(self):
     698        from config import rho_a, rho_w, eta_w
     699        from math import pi, cos, sin, sqrt
     700
     701        a = [0.0, 0.0]
     702        b = [0.0, 2.0]
     703        c = [2.0, 0.0]
     704        d = [0.0, 4.0]
     705        e = [2.0, 2.0]
     706        f = [4.0, 0.0]
     707
     708        points = [a, b, c, d, e, f]
     709        #bac, bce, ecf, dbe
     710        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     711
     712       
     713        domain = Domain(points, vertices)
     714
     715        #Flat surface with 1m of water
     716        domain.set_quantity('elevation', 0)
     717        domain.set_quantity('level', 1.0)
     718        domain.set_quantity('friction', 0)       
     719
     720        Br = Reflective_boundary(domain)
     721        domain.set_boundary({'exterior': Br})
     722
     723        #Setup only one forcing term, constant wind stress
     724        s = 100
     725        phi = 135
     726        domain.forcing_terms = []
     727        domain.forcing_terms.append( Wind_stress(s, phi) )
     728       
     729        domain.compute_forcing_terms()
     730
     731
     732        const = eta_w*rho_a/rho_w
     733       
     734        #Convert to radians
     735        phi = phi*pi/180
     736       
     737        #Compute velocity vector (u, v)
     738        u = s*cos(phi)
     739        v = s*sin(phi)
     740
     741        #Compute wind stress
     742        S = const * sqrt(u**2 + v**2)
     743
     744        assert allclose(domain.quantities['level'].explicit_update, 0)
     745        assert allclose(domain.quantities['xmomentum'].explicit_update, S*u)
     746        assert allclose(domain.quantities['ymomentum'].explicit_update, S*v)
     747
     748
     749    def test_variable_wind_stress(self):
     750        from config import rho_a, rho_w, eta_w
     751        from math import pi, cos, sin, sqrt
     752
     753        a = [0.0, 0.0]
     754        b = [0.0, 2.0]
     755        c = [2.0, 0.0]
     756        d = [0.0, 4.0]
     757        e = [2.0, 2.0]
     758        f = [4.0, 0.0]
     759
     760        points = [a, b, c, d, e, f]
     761        #bac, bce, ecf, dbe
     762        vertices = [ [1,0,2], [1,2,4], [4,2,5], [3,1,4]]
     763
     764        domain = Domain(points, vertices)
     765
     766        #Flat surface with 1m of water
     767        domain.set_quantity('elevation', 0)
     768        domain.set_quantity('level', 1.0)
     769        domain.set_quantity('friction', 0)       
     770
     771        Br = Reflective_boundary(domain)
     772        domain.set_boundary({'exterior': Br})
     773
     774
     775        domain.time = 5.54 #Take a random time (not zero)
     776
     777        #Setup only one forcing term, constant wind stress
     778        s = 100
     779        phi = 135
     780        domain.forcing_terms = []
     781        domain.forcing_terms.append( Wind_stress(s = speed, phi = angle) )
     782       
     783        domain.compute_forcing_terms()
     784
     785        #Compute reference solution
     786        const = eta_w*rho_a/rho_w
     787       
     788        N = domain.number_of_elements
     789
     790        xc = domain.get_centroid_coordinates()
     791        t = domain.time
     792
     793        for k in range(N):
     794            x, y = xc[k,:]   
     795
     796            s = speed(x,y,t)
     797            phi = angle(x,y,t)
     798
     799
     800            #Convert to radians
     801            phi = phi*pi/180
     802       
     803            #Compute velocity vector (u, v)
     804            u = s*cos(phi)
     805            v = s*sin(phi)
     806
     807            #Compute wind stress
     808            S = const * sqrt(u**2 + v**2)
     809
     810            assert allclose(domain.quantities['level'].explicit_update[k], 0)
     811            assert allclose(domain.quantities['xmomentum'].explicit_update[k], S*u)
     812            assert allclose(domain.quantities['ymomentum'].explicit_update[k], S*v)
     813
     814
     815
     816
     817        #FIXME: Do this when I get a minute of peace - goddammit
     818       
     819
    588820       
    589821
Note: See TracChangeset for help on using the changeset viewer.