source: trunk/anuga_core/source/anuga/structures/structure_operator.py @ 7998

Last change on this file since 7998 was 7998, checked in by habili, 14 years ago

deal with boyd pipes

File size: 6.6 KB
Line 
1from anuga.geometry.polygon import inside_polygon, polygon_area
2from anuga.config import g
3import numpy as num
4import math
5import inlet
6
7class Structure_operator:
8    """Structure Operator - transfer water from one rectangular box to another.
9    Sets up the geometry of problem
10   
11    This is the base class for culverts. Inherit from this class (and overwrite
12    compute_discharge method for specific subclasses)
13   
14    Input: Two points, pipe_size (either diameter or width, height),
15    mannings_rougness,
16    """ 
17
18    def __init__(self,
19                 domain,
20                 end_point0, 
21                 end_point1,
22                 width,
23                 height,
24                 apron,
25                 manning,
26                 enquiry_gap,
27                 description,
28                 verbose):
29       
30        self.domain = domain
31        self.domain.set_fractional_step_operator(self)
32        self.end_points = [end_point0, end_point1]
33       
34        if height is None:
35            height = width
36
37        if apron is None:
38            apron = width
39
40        self.width  = width
41        self.height = height
42        self.apron  = apron
43        self.manning = manning
44        self.enquiry_gap = enquiry_gap
45        self.description = description
46        self.verbose = verbose
47
48        self.discharge = 0.0
49        self.velocity = 0.0
50        self.delta_total_energy = 0.0
51        self.driving_energy = 0.0
52       
53        self.__create_exchange_polygons()
54
55        self.inlets = []
56        polygon0 = self.inlet_polygons[0]
57        enquiry_point0 = self.inlet_equiry_points[0]
58        outward_vector0 = self.culvert_vector
59        self.inlets.append(inlet.Inlet(self.domain, polygon0, enquiry_point0, outward_vector0))
60
61        polygon1 = self.inlet_polygons[1]
62        exchange_polygon1 = self.inlet_equiry_points[1]
63        outward_vector1  = - self.culvert_vector
64        self.inlets.append(inlet.Inlet(self.domain, polygon1, exchange_polygon1, outward_vector1))
65
66    def __call__(self):
67
68        pass
69
70    def __create_exchange_polygons(self):
71
72        """Create polygons at the end of a culvert inlet and outlet.
73        At either end two polygons will be created; one for the actual flow to pass through and one a little further away
74        for enquiring the total energy at both ends of the culvert and transferring flow.
75        """
76
77        # Calculate geometry
78        x0, y0 = self.end_points[0]
79        x1, y1 = self.end_points[1]
80
81        dx = x1 - x0
82        dy = y1 - y0
83
84        self.culvert_vector = num.array([dx, dy])
85        self.culvert_length = math.sqrt(num.sum(self.culvert_vector**2))
86        assert self.culvert_length > 0.0, 'The length of culvert is less than 0'
87
88        # Unit direction vector and normal
89        self.culvert_vector /= self.culvert_length                      # Unit vector in culvert direction
90        self.culvert_normal = num.array([-dy, dx])/self.culvert_length  # Normal vector
91
92        # Short hands
93        w = 0.5*self.width*self.culvert_normal # Perpendicular vector of 1/2 width
94        h = self.apron*self.culvert_vector    # Vector of length=height in the
95                             # direction of the culvert
96
97        gap = (1 + self.enquiry_gap)*h
98
99        self.inlet_polygons = []
100        self.inlet_equiry_points = []
101
102        # Build exchange polygon and enquiry point
103        for i in [0, 1]:
104            i0 = (2*i-1)
105            p0 = self.end_points[i] + w
106            p1 = self.end_points[i] - w
107            p2 = p1 + i0*h
108            p3 = p0 + i0*h
109            ep = self.end_points[i] + i0*gap
110
111            self.inlet_polygons.append(num.array([p0, p1, p2, p3]))
112            self.inlet_equiry_points.append(ep)
113
114        # Check that enquiry points are outside inlet polygons
115        for i in [0,1]:
116            polygon = self.inlet_polygons[i]
117            ep = self.inlet_equiry_points[i]
118           
119            area = polygon_area(polygon)
120           
121            msg = 'Polygon %s ' %(polygon)
122            msg += ' has area = %f' % area
123            assert area > 0.0, msg
124
125            msg = 'Enquiry point falls inside an exchange polygon.'
126            assert not inside_polygon(ep, polygon), msg
127   
128           
129        #print '   outflow volume ',outflow.get_total_water_volume()
130       
131
132    def print_stats(self):
133
134        print '====================================='
135        print 'Generic Culvert Operator'
136        print '====================================='
137
138        print 'Culvert'
139        print self.culvert
140
141        print 'Culvert Routine'
142        print self.routine
143       
144        for i, inlet in enumerate(self.inlets):
145            print '-------------------------------------'
146            print 'Inlet %i' % i
147            print '-------------------------------------'
148
149            print 'inlet triangle indices and centres'
150            print inlet.triangle_indices
151            print self.domain.get_centroid_coordinates()[inlet.triangle_indices]
152       
153            print 'polygon'
154            print inlet.polygon
155
156        print '====================================='
157
158
159    def structure_statistics(self):
160
161        message = '---------------------------\n'
162        message += 'Structure report for structure %s:\n' % self.description
163        message += '--------------------------\n'
164        message += 'Discharge [m^3/s]: %.2f\n' % self.discharge
165        message += 'Velocity  [m/s]: %.2f\n' % self.velocity
166        message += 'Inlet Driving Energy %.2f\n' % self.driving_energy
167        message += 'delta total energy %.2f\n' % self.delta_total_energy
168#        message += 'Net boundary flow by tags [m^3/s]\n'
169#        for tag in boundary_flows:
170#            message += '    %s [m^3/s]: %.2f\n' % (tag, boundary_flows[tag])
171#
172#        message += 'Total net boundary flow [m^3/s]: %.2f\n' % \
173#                    (total_boundary_inflow + total_boundary_outflow)
174#        message += 'Total volume in domain [m^3]: %.2f\n' % \
175#                    self.compute_total_volume()
176#
177#        # The go through explicit forcing update and record the rate of change
178#        # for stage and
179#        # record into forcing_inflow and forcing_outflow. Finally compute
180#        # integral of depth to obtain total volume of domain.
181#
182        # FIXME(Ole): This part is not yet done.
183
184        return message
185
186    def get_inlets(self):
187       
188        return self.inlets
189       
190       
191    def get_culvert_length(self):
192       
193        return self.culvert_length
194       
195       
196    def get_culvert_width(self):
197       
198        return self.width
199       
200       
201    def get_culvert_diameter(self):
202   
203            return self.width
204       
205       
206    def get_culvert_height(self):
207   
208        return self.height
209
210
211    def get_culvert_apron(self):
212
213        return self.apron
Note: See TracBrowser for help on using the repository browser.