source: trunk/anuga_core/anuga/structures/inlet.py @ 9679

Last change on this file since 9679 was 9357, checked in by davies, 11 years ago

Adding towradgi results.tex + a validation test bugfix

File size: 7.9 KB
Line 
1import anuga.geometry.polygon
2from anuga.geometry.polygon import inside_polygon, is_inside_polygon, line_intersect
3from anuga.config import velocity_protection, g
4from anuga import Region
5
6import math
7
8
9import numpy as num
10
11class Inlet:
12    """Contains information associated with each inlet
13    """
14
15    def __init__(self, domain, poly, verbose=False):
16
17        self.domain = domain
18        self.domain_bounding_polygon = self.domain.get_boundary_polygon()
19        self.verbose = verbose
20       
21       
22        # poly can be either a line, polygon or a regions
23        if isinstance(poly,Region):
24            self.region = poly
25        else:
26            self.region = Region(domain,poly=poly,expand_polygon=True)
27
28
29       
30        #self.line = True
31        #if len(self.poly) > 2:
32        #    self.line = False
33
34        self.triangle_indices = self.region.indices
35
36        #print self.triangle_indices
37        #print poly
38        #print self.triangle_indices
39       
40        #self.compute_triangle_indices()
41        self.compute_area()
42        #self.compute_inlet_length()
43
44
45
46    ## def compute_triangle_indices(self):
47
48    ##     # Get boundary (in absolute coordinates)
49    ##     bounding_polygon = self.domain_bounding_polygon
50    ##     domain_centroids = self.domain.get_centroid_coordinates(absolute=True)
51    ##     vertex_coordinates = self.domain.get_vertex_coordinates(absolute=True)
52
53    ##     if self.line: # poly is a line
54    ##         # Check that line lies within the mesh.
55    ##         for point in self.poly:
56    ##             msg = 'Point %s ' %  str(point)
57    ##             msg += ' did not fall within the domain boundary.'
58    ##             assert is_inside_polygon(point, bounding_polygon), msg
59               
60    ##         self.triangle_indices = line_intersect(vertex_coordinates, self.poly)
61
62    ##     else: # poly is a polygon
63
64    ##         tris_0 = line_intersect(vertex_coordinates, [self.poly[0],self.poly[1]])
65    ##         tris_1 = inside_polygon(domain_centroids, self.poly)
66    ##         #print 40*"="
67    ##         #print tris_0
68    ##         #print tris_1
69    ##         self.triangle_indices = num.union1d(tris_0, tris_1)
70    ##         #print self.triangle_indices
71
72    ##     if len(self.triangle_indices) == 0:
73    ##         msg = 'Inlet poly=%s ' % (self.poly)
74    ##         msg += 'No triangle centroids intersecting poly '
75    ##         raise Exception, msg
76
77
78
79
80    def compute_area(self):
81       
82        # Compute inlet area as the sum of areas of triangles identified
83        # by line. Must be called after compute_inlet_triangle_indices().
84        if len(self.triangle_indices) == 0:
85            region = 'Inlet line=%s' % (self.inlet_line)
86            msg = 'No triangles have been identified in region '
87            raise Exception, msg
88       
89#        self.area = 0.0
90#        for j in self.triangle_indices:
91#            self.area += self.domain.areas[j]
92
93        self.area = num.sum(self.domain.areas[self.triangle_indices])
94
95        msg = 'Inlet exchange area has area = %f' % self.area
96        assert self.area > 0.0
97
98
99#    def compute_inlet_length(self):
100#        """ Compute the length of the inlet (as
101#        defined by the input line
102#        """
103#
104#        self.inlet_length = anuga.geometry.polygon.line_length(self.poly)
105
106
107#    def get_inlet_length(self):
108#
109#        return self.inlet_length
110
111
112
113    def get_poly(self):
114
115        return self.poly
116       
117    def get_area(self):
118
119        return self.area
120
121   
122    def get_areas(self):
123       
124        # Must be called after compute_inlet_triangle_indices().
125        return self.domain.areas.take(self.triangle_indices)
126   
127       
128    def get_stages(self):
129       
130        return self.domain.quantities['stage'].centroid_values.take(self.triangle_indices)
131       
132       
133    def get_average_stage(self):
134
135        return num.sum(self.get_stages()*self.get_areas())/self.area
136       
137    def get_elevations(self):   
138       
139        return self.domain.quantities['elevation'].centroid_values.take(self.triangle_indices)
140       
141    def get_average_elevation(self):
142
143        return num.sum(self.get_elevations()*self.get_areas())/self.area
144   
145   
146    def get_xmoms(self):
147   
148        return self.domain.quantities['xmomentum'].centroid_values.take(self.triangle_indices)
149       
150       
151    def get_average_xmom(self):
152
153        return num.sum(self.get_xmoms()*self.get_areas())/self.area
154       
155   
156    def get_ymoms(self):
157       
158        return self.domain.quantities['ymomentum'].centroid_values.take(self.triangle_indices)
159 
160 
161    def get_average_ymom(self):
162       
163        return num.sum(self.get_ymoms()*self.get_areas())/self.area
164   
165
166    def get_depths(self):
167   
168        return self.get_stages() - self.get_elevations()
169   
170   
171    def get_total_water_volume(self):
172       
173       return num.sum(self.get_depths()*self.get_areas())
174 
175
176    def get_average_depth(self):
177   
178        return self.get_total_water_volume()/self.area
179       
180       
181    def get_velocities(self):
182       
183            depths = self.get_depths()
184            u = self.get_xmoms()/(depths + velocity_protection/depths)
185            v = self.get_ymoms()/(depths + velocity_protection/depths)
186           
187            return u, v
188
189
190    def get_xvelocities(self):
191
192            depths = self.get_depths()
193            return self.get_xmoms()/(depths + velocity_protection/depths)
194
195    def get_yvelocities(self):
196
197            depths = self.get_depths()
198            return self.get_ymoms()/(depths + velocity_protection/depths)
199           
200           
201    def get_average_speed(self):
202 
203            u, v = self.get_velocities()
204           
205            average_u = num.sum(u*self.get_areas())/self.area
206            average_v = num.sum(v*self.get_areas())/self.area
207           
208            return math.sqrt(average_u**2 + average_v**2)
209
210
211    def get_average_velocity_head(self):
212
213        return 0.5*self.get_average_speed()**2/g
214
215
216    def get_average_total_energy(self):
217       
218        return self.get_average_velocity_head() + self.get_average_stage()
219       
220   
221    def get_average_specific_energy(self):
222       
223        return self.get_average_velocity_head() + self.get_average_depth()
224
225
226
227    def set_depths(self,depth):
228
229        self.domain.quantities['stage'].centroid_values.put(self.triangle_indices, self.get_elevations() + depth)
230
231
232    def set_stages(self,stage):
233
234        self.domain.quantities['stage'].centroid_values.put(self.triangle_indices, stage)
235
236
237    def set_xmoms(self,xmom):
238
239        self.domain.quantities['xmomentum'].centroid_values.put(self.triangle_indices, xmom)
240
241
242    def set_ymoms(self,ymom):
243
244        self.domain.quantities['ymomentum'].centroid_values.put(self.triangle_indices, ymom)
245
246
247    def set_elevations(self,elevation):
248
249        self.domain.quantities['elevation'].centroid_values.put(self.triangle_indices, elevation)
250
251    def set_stages_evenly(self,volume):
252        """ Distribute volume of water over
253        inlet exchange region so that stage is level
254        """
255
256        assert volume >= 0.0
257
258        areas = self.get_areas()
259        stages = self.get_stages()
260        depths = self.get_depths()
261
262        stages_order = stages.argsort()
263
264        # accumulate areas of cells ordered by stage
265        summed_areas = num.cumsum(areas[stages_order])
266       
267        # accumulate the volume need to fill cells
268        summed_volume = num.zeros_like(areas)       
269        summed_volume[1:] = num.cumsum(summed_areas[:-1]*num.diff(stages[stages_order]))
270
271        index = num.nonzero(summed_volume<=volume)[0][-1]
272
273        # calculate stage needed to fill chosen cells with given volume of water
274        depth = (volume - summed_volume[index])/summed_areas[index]
275        stages[stages_order[0:index+1]] = stages[stages_order[index]]+depth
276
277        self.set_stages(stages)
278
279
280
281
282    def set_depths_evenly(self,volume):
283        """ Distribute volume over all exchange
284        cells with equal depth of water
285        """
286           
287        new_depth = self.get_average_depth() + (volume/self.get_area())
288        self.set_depths(new_depth)
289
Note: See TracBrowser for help on using the repository browser.