source: trunk/anuga_core/source/anuga/structures/culvert.py @ 7984

Last change on this file since 7984 was 7984, checked in by steve, 13 years ago

Added enquiry points to culverts

File size: 4.2 KB
Line 
1from anuga.geometry.polygon import inside_polygon, polygon_area
2from anuga.config import g
3import anuga.utilities.log as log
4import inlet
5import numpy as num
6import math
7
8class Culvert:
9    """Culvert flow - transfer water from one rectangular box to another.
10    Sets up the geometry of problem
11   
12    This is the base class for culverts. Inherit from this class (and overwrite
13    compute_discharge method for specific subclasses)
14   
15    Input: Two points, pipe_size (either diameter or width, height),
16    mannings_rougness,
17    """ 
18
19    def __init__(self,
20                 domain,
21                 end_points, 
22                 width,
23                 height,
24                 apron,
25                 enquiry_gap,
26                 verbose):
27       
28        # Input check
29       
30        self.domain = domain
31        self.end_points = end_points
32        self.width  = width
33        self.height = height
34        self.apron  = apron
35        self.enquiry_gap = enquiry_gap
36        self.verbose=verbose
37       
38        # Create the fundamental culvert polygons and create inlet objects
39        self.__create_culvert_polygons()
40
41        #FIXME (SR) Put this into a foe loop to deal with more inlets
42
43        self.inlets = []
44        polygon0 = self.inlet_polygons[0]
45        ep0 = self.inlet_equiry_pts[0]
46        outward_vector0 = self.culvert_vector
47        self.inlets.append(inlet.Inlet(self.domain, polygon0, ep0, outward_vector0))
48
49        polygon1 = self.inlet_polygons[1]
50        ep1 = self.inlet_equiry_pts[1]
51        outward_vector1  = - self.culvert_vector
52        self.inlets.append(inlet.Inlet(self.domain, polygon1, ep1, outward_vector1))
53
54
55    def __call__(self):
56        msg = 'Method __call__ must be overridden by Culvert subclass'
57        raise Exception, msg
58
59    def __create_culvert_polygons(self):
60
61        """Create polygons at the end of a culvert inlet and outlet.
62        At either end two polygons will be created; one for the actual flow to pass through and one a little further away
63        for enquiring the total energy at both ends of the culvert and transferring flow.
64        """
65
66        # Calculate geometry
67        x0, y0 = self.end_points[0]
68        x1, y1 = self.end_points[1]
69
70        dx = x1 - x0
71        dy = y1 - y0
72
73        self.culvert_vector = num.array([dx, dy])
74        self.culvert_length = math.sqrt(num.sum(self.culvert_vector**2))
75        assert self.culvert_length > 0.0, 'The length of culvert is less than 0'
76
77        # Unit direction vector and normal
78        self.culvert_vector /= self.culvert_length                      # Unit vector in culvert direction
79        self.culvert_normal = num.array([-dy, dx])/self.culvert_length  # Normal vector
80
81        # Short hands
82        w = 0.5*self.width*self.culvert_normal # Perpendicular vector of 1/2 width
83        h = self.apron*self.culvert_vector    # Vector of length=height in the
84                             # direction of the culvert
85
86        gap = (1 + self.enquiry_gap)*h
87
88        self.inlet_polygons = []
89        self.inlet_equiry_pts = []
90
91        # Build exchange polygon and enquiry point
92        for i in [0, 1]:
93            i0 = (2*i-1)
94            p0 = self.end_points[i] + w
95            p1 = self.end_points[i] - w
96            p2 = p1 + i0*h
97            p3 = p0 + i0*h
98            ep = self.end_points[i] + i0*gap
99
100            self.inlet_polygons.append(num.array([p0, p1, p2, p3]))
101            self.inlet_equiry_pts.append(ep)
102
103        # Check that enquiry points are outside inlet polygons
104        for i in [0,1]:
105            polygon = self.inlet_polygons[i]
106            ep = self.inlet_equiry_pts[i]
107           
108            area = polygon_area(polygon)
109           
110            msg = 'Polygon %s ' %(polygon)
111            msg += ' has area = %f' % area
112            assert area > 0.0, msg
113
114            msg = 'Enquiry point falls inside an exchange polygon.'
115            assert not inside_polygon(ep, polygon), msg
116   
117    def get_inlets(self):
118       
119        return self.inlets
120       
121       
122    def get_culvert_length(self):
123       
124        return self.culvert_length
125       
126       
127    def get_culvert_width(self):
128       
129        return self.width
130       
131       
132    def get_culvert_height(self):
133   
134        return self.height
135
136
137    def get_culvert_apron(self):
138
139        return self.apron
140       
Note: See TracBrowser for help on using the repository browser.