source: anuga_work/development/Rudy_vandrie_2007/culvert_flow.py @ 4440

Last change on this file since 4440 was 4440, checked in by ole, 17 years ago

Examples prepared for Rudy

File size: 5.4 KB
Line 
1"""Example of shallow water wave equation.
2
3Specific methods pertaining to the 2D shallow water equation
4are imported from shallow_water
5for use with the generic finite volume framework
6
7Conserved quantities are h, uh and vh stored as elements 0, 1 and 2 in the
8numerical vector named conserved_quantities.
9"""
10
11#------------------------------------------------------------------------------
12# Import necessary modules
13#------------------------------------------------------------------------------
14from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular
15from anuga.shallow_water import Domain
16from anuga.shallow_water.shallow_water_domain import Reflective_boundary
17from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
18
19#------------------------------------------------------------------------------
20# Setup computational domain
21#------------------------------------------------------------------------------
22
23#N = 120
24N = 40
25points, vertices, boundary = rectangular(N, N)
26domain = Domain(points, vertices, boundary)   
27domain.set_name('kitchen_sink')                 # Output name
28print 'Size', len(domain)
29
30
31#------------------------------------------------------------------------------
32# Setup initial conditions
33#------------------------------------------------------------------------------
34
35domain.set_quantity('elevation', 0.0)  # Zero bed elevation
36domain.set_quantity('stage', 0.015)    # Constant stage
37domain.set_quantity('friction', 0.005) # Constant friction
38
39
40#------------------------------------------------------------------------------
41# Setup specialised forcing terms
42#------------------------------------------------------------------------------
43
44class Inflow:
45    """Class Inflow - general 'rain and drain' forcing term.
46   
47    Useful for implementing flows in and out of the domain.
48   
49    Inflow(center, radius, flow)
50   
51    center [m]: Coordinates at center of flow point
52    radius [m]: Size of circular area
53    flow [m/s]: Rate of change of quantity over the specified area. 
54                This parameter can be either a constant or a function of time.
55                Positive values indicate inflow,
56                negative values indicate outflow.
57   
58    Examples
59   
60    Inflow((0.7, 0.4), 0.07, -0.2) # Constant drain at 0.2 m/s.
61                                   # This corresponds to a flow of
62                                   # 0.07**2*pi*0.2 = 0.00314 m^3/s
63                                   
64    Inflow((0.5, 0.5), 0.001, lambda t: min(4*t, 5)) # Tap turning up to
65                                                     # a maximum inflow of
66                                                     # 5 m/s over the
67                                                     # specified area
68    """
69   
70    # FIXME (OLE): Add a polygon as an alternative.
71    # FIXME (OLE): Generalise to all quantities
72
73    def __init__(self, 
74                 center=None, radius=None,
75                 flow=0.0,
76                 quantity_name = 'stage'):
77                 
78        if center is not None and radius is not None:
79            assert len(center) == 2
80        else:
81            msg = 'Both center and radius must be specified'
82            raise Exception, msg
83   
84        self.center = center
85        self.radius = radius
86        self.flow = flow
87        self.quantity = domain.quantities[quantity_name].explicit_update
88       
89   
90    def __call__(self, domain):
91   
92        # Determine indices in flow area
93        if not hasattr(self, 'indices'):
94            center = self.center
95            radius = self.radius
96           
97            N = len(domain)   
98            self.indices = []
99            coordinates = domain.get_centroid_coordinates()     
100            for k in range(N):
101                x, y = coordinates[k,:] # Centroid
102                if ((x-center[0])**2+(y-center[1])**2) < radius**2:
103                    self.indices.append(k)   
104
105        # Update inflow
106        if callable(self.flow):
107            flow = self.flow(domain.get_time())
108        else:
109            flow = self.flow
110                   
111        for k in self.indices:
112            self.quantity[k] += flow                   
113                   
114
115class Culvert_flow:
116    """Culvert flow - transfer water from one hole to another
117    """ 
118
119    def __init__(self, 
120                 inflow_center=None, inflow_radius=None,                   
121                 outflow_center=None, outflow_radius=None,
122                 transfer_flow=None)
123                 
124        self.inflow=Inflow(center=inflow_center,
125                           radius=inflow_radius,
126                           flow=transfer_flow)
127                           
128        self.outflow=Inflow(center=outflow_center,
129                           radius=outflow_radius,
130                           flow=-transfer_flow) #!!!                       
131                           
132                               
133                 
134    def __call__(self, domain):
135        self.inflow(domain)             
136        self.outflow(domain)                   
137                                                         
138                   
139sink = Inflow(center=[0.7, 0.4], radius=0.0707, flow = 0.0)             
140tap = Inflow(center=(0.5, 0.5), radius=0.0316,
141             flow=lambda t: min(4*t, 5)) # Tap turning up       
142       
143
144domain.forcing_terms.append(tap)
145domain.forcing_terms.append(sink)
146
147#------------------------------------------------------------------------------
148# Setup boundary conditions
149#------------------------------------------------------------------------------
150
151Br = Reflective_boundary(domain)              # Solid reflective wall
152domain.set_boundary({'left': Br, 'right': Br, 'top': Br, 'bottom': Br})
153
154#------------------------------------------------------------------------------
155# Evolve system through time
156#------------------------------------------------------------------------------
157for t in domain.evolve(yieldstep = 0.01, finaltime = 15):
158    domain.write_time()
159   
160    if domain.get_time() >= 4 and tap.flow != 0.0:
161        print 'Turning tap off'
162        tap.flow = 0.0
163       
164    if domain.get_time() >= 3 and sink.flow < 0.0:
165        print 'Turning drain on'
166        sink.flow = -0.8       
167   
Note: See TracBrowser for help on using the repository browser.