source: trunk/anuga_core/source/anuga/structures/boyd_pipe_operator.py @ 8092

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

Added in a unit test for inlet operator

  • Property svn:executable set to *
File size: 13.2 KB
Line 
1import anuga
2import math
3import types
4
5class Boyd_pipe_operator(anuga.Structure_operator):
6    """Culvert flow - transfer water from one location to another via a circular pipe culvert.
7    Sets up the geometry of problem
8   
9    This is the base class for culverts. Inherit from this class (and overwrite
10    compute_discharge method for specific subclasses)
11   
12    Input: Two points, pipe_size (diameter),
13    mannings_rougness,
14    """ 
15
16    def __init__(self,
17                 domain,
18                 losses,
19                 end_points=None,
20                 exchange_lines=None,
21                 enquiry_points=None,
22                 diameter=None,
23                 apron=0.1,
24                 manning=0.013,
25                 enquiry_gap=0.2,
26                 use_momentum_jet=True,
27                 use_velocity_head=True,
28                 description=None,
29                 label=None,
30                 structure_type='boyd_pipe',
31                 logging=False,
32                 verbose=False):
33                     
34        anuga.Structure_operator.__init__(self,
35                                          domain,
36                                          end_points,
37                                          exchange_lines,
38                                          enquiry_points,
39                                          width=diameter,
40                                          depth=None,
41                                          apron=apron,
42                                          manning=manning,
43                                          enquiry_gap=enquiry_gap,                                                       
44                                          description=description,
45                                          label=label,
46                                          structure_type=structure_type,
47                                          logging=logging,
48                                          verbose=verbose)           
49
50 
51        if type(losses) == types.DictType:
52            self.sum_loss = sum(losses.values())
53        elif type(losses) == types.ListType:
54            self.sum_loss = sum(losses)
55        else:
56            self.sum_loss = losses
57       
58        self.use_momentum_jet = use_momentum_jet
59        self.use_velocity_head = use_velocity_head
60       
61        self.culvert_length = self.get_culvert_length()
62        self.culvert_diameter = self.get_culvert_diameter()
63
64        self.max_velocity = 10.0
65
66        self.inlets = self.get_inlets()
67
68        # Stats
69       
70        self.discharge = 0.0
71        self.velocity = 0.0
72       
73        self.case = 'N/A'
74       
75
76    def __determine_inflow_outflow(self):
77        # Determine flow direction based on total energy difference
78
79        if self.use_velocity_head:
80            self.delta_total_energy = self.inlets[0].get_enquiry_total_energy() - self.inlets[1].get_enquiry_total_energy()
81        else:
82            self.delta_total_energy = self.inlets[0].get_enquiry_stage() - self.inlets[1].get_enquiry_stage()
83
84        self.inflow  = self.inlets[0]
85        self.outflow = self.inlets[1]
86
87        if self.delta_total_energy < 0:
88            self.inflow  = self.inlets[1]
89            self.outflow = self.inlets[0]
90            self.delta_total_energy = -self.delta_total_energy
91
92    def discharge_routine(self):
93
94        self.__determine_inflow_outflow()
95
96        local_debug ='false'
97       
98        #import pdb
99        #pdb.set_trace()
100       
101        if self.inflow.get_enquiry_depth() > 0.01: #this value was 0.01: Remember this needs to be compared to the Invert Lvl
102            if local_debug =='true':
103                anuga.log.critical('Specific E & Deltat Tot E = %s, %s'
104                             % (str(self.inflow.get_enquiry_specific_energy()),
105                                str(self.delta_total_energy)))
106                anuga.log.critical('culvert type = %s' % str(culvert_type))
107            # Water has risen above inlet
108
109
110            msg = 'Specific energy at inlet is negative'
111            assert self.inflow.get_enquiry_specific_energy() >= 0.0, msg
112
113            if self.use_velocity_head :
114                self.driving_energy = self.inflow.get_enquiry_specific_energy()
115            else:
116                self.driving_energy = self.inflow.get_enquiry_depth()
117                """
118        For a circular pipe the Boyd method reviews 3 conditions
119        1. Whether the Pipe Inlet is Unsubmerged (acting as weir flow into the inlet)
120        2. Whether the Pipe Inlet is Fully Submerged (acting as an Orifice)
121        3. Whether the energy loss in the pipe results in the Pipe being controlled by Channel Flow of the Pipe
122
123        For these conditions we also would like to assess the pipe flow characteristics as it leaves the pipe
124        """
125
126        diameter = self.culvert_diameter
127
128        local_debug ='false'
129        if self.inflow.get_average_depth() > 0.01: #this should test against invert
130            if local_debug =='true':
131                anuga.log.critical('Specific E & Deltat Tot E = %s, %s'
132                             % (str(self.inflow.get_average_specific_energy()),
133                                str(self.delta_total_energy)))
134                anuga.log.critical('culvert type = %s' % str(culvert_type))
135            # Water has risen above inlet
136
137
138            msg = 'Specific energy at inlet is negative'
139            assert self.inflow.get_average_specific_energy() >= 0.0, msg
140
141            # Calculate flows for inlet control for circular pipe
142            Q_inlet_unsubmerged = 0.421*anuga.g**0.5*diameter**0.87*self.inflow.get_average_specific_energy()**1.63 # Inlet Ctrl Inlet Unsubmerged
143            Q_inlet_submerged = 0.530*anuga.g**0.5*diameter**1.87*self.inflow.get_average_specific_energy()**0.63   # Inlet Ctrl Inlet Submerged
144            # Note for to SUBMERGED TO OCCUR self.inflow.get_average_specific_energy() should be > 1.2 x diameter.... Should Check !!!
145
146
147            Q = min(Q_inlet_unsubmerged, Q_inlet_submerged)
148
149            # THE LOWEST Value will Control Calcs From here
150            # Calculate Critical Depth Based on the Adopted Flow as an Estimate
151            dcrit1 = diameter/1.26*(Q/anuga.g**0.5*diameter**2.5)**(1/3.75)
152            dcrit2 = diameter/0.95*(Q/anuga.g**0.5*diameter**2.5)**(1/1.95)
153            # From Boyd Paper ESTIMATE of Dcrit has 2 criteria as
154            if dcrit1/diameter  > 0.85:
155                outlet_culvert_depth = dcrit2
156            else:
157                outlet_culvert_depth = dcrit1
158            #outlet_culvert_depth = min(outlet_culvert_depth, diameter)
159            # Now determine Hydraulic Radius Parameters Area & Wetted Perimeter
160            if outlet_culvert_depth >= diameter:
161                outlet_culvert_depth = diameter  # Once again the pipe is flowing full not partfull
162                flow_area = (diameter/2)**2 * math.pi  # Cross sectional area of flow in the culvert
163                perimeter = diameter * math.pi
164                flow_width= diameter
165                self.case = 'Inlet CTRL Outlet submerged Circular PIPE FULL'
166                if local_debug == 'true':
167                    anuga.log.critical('Inlet CTRL Outlet submerged Circular '
168                                 'PIPE FULL')
169            else:
170                #alpha = anuga.acos(1 - outlet_culvert_depth/diameter)    # Where did this Come From ????/
171                alpha = anuga.acos(1-2*outlet_culvert_depth/diameter)*2
172                #flow_area = diameter**2 * (alpha - sin(alpha)*cos(alpha))        # Pipe is Running Partly Full at the INLET   WHRE did this Come From ?????
173                flow_area = diameter**2/8*(alpha - math.sin(alpha))   # Equation from  GIECK 5th Ed. Pg. B3
174                flow_width= diameter*math.sin(alpha/2.0)
175                perimeter = alpha*diameter/2.0
176                self.case = 'INLET CTRL Culvert is open channel flow we will for now assume critical depth'
177                if local_debug =='true':
178                    anuga.log.critical('INLET CTRL Culvert is open channel flow '
179                                 'we will for now assume critical depth')
180                    anuga.log.critical('Q Outlet Depth and ALPHA = %s, %s, %s'
181                                 % (str(Q), str(outlet_culvert_depth),
182                                    str(alpha)))
183            if self.delta_total_energy < self.inflow.get_average_specific_energy():  #  OUTLET CONTROL !!!!
184                # Calculate flows for outlet control
185
186                # Determine the depth at the outlet relative to the depth of flow in the Culvert
187                if self.outflow.get_average_depth() > diameter:       # Outlet is submerged Assume the end of the Pipe is flowing FULL
188                    outlet_culvert_depth=diameter
189                    flow_area = (diameter/2)**2 * math.pi  # Cross sectional area of flow in the culvert
190                    perimeter = diameter * math.pi
191                    flow_width= diameter
192                    self.case = 'Outlet submerged'
193                    if local_debug =='true':
194                        anuga.log.critical('Outlet submerged')
195                else:   # Culvert running PART FULL for PART OF ITS LENGTH   Here really should use the Culvert Slope to calculate Actual Culvert Depth & Velocity
196                    # IF  self.outflow.get_average_depth() < diameter
197                    dcrit1 = diameter/1.26*(Q/anuga.g**0.5*diameter**2.5)**(1/3.75)
198                    dcrit2 = diameter/0.95*(Q/anuga.g**0.5*diameter**2.5)**(1/1.95)
199                    if dcrit1/diameter >0.85:
200                        outlet_culvert_depth= dcrit2
201                    else:
202                        outlet_culvert_depth = dcrit1
203                    if outlet_culvert_depth > diameter:
204                        outlet_culvert_depth = diameter  # Once again the pipe is flowing full not partfull
205                        flow_area = (diameter/2)**2 * math.pi  # Cross sectional area of flow in the culvert
206                        perimeter = diameter * math.pi
207                        flow_width= diameter
208                        self.case = 'Outlet unsubmerged PIPE FULL'
209                        if local_debug =='true':
210                            anuga.log.critical('Outlet unsubmerged PIPE FULL')
211                    else:
212                        alpha = anuga.acos(1-2*outlet_culvert_depth/diameter)*2
213                        flow_area = diameter**2/8*(alpha - math.sin(alpha))   # Equation from  GIECK 5th Ed. Pg. B3
214                        flow_width= diameter*math.sin(alpha/2.0)
215                        perimeter = alpha*diameter/2.0
216                        self.case = 'Outlet is open channel flow we will for now assume critical depth'
217                        if local_debug == 'true':
218                            anuga.log.critical('Q Outlet Depth and ALPHA = %s, %s, %s'
219                                         % (str(Q), str(outlet_culvert_depth),
220                                            str(alpha)))
221                            anuga.log.critical('Outlet is open channel flow we '
222                                         'will for now assume critical depth')
223            if local_debug == 'true':
224                anuga.log.critical('FLOW AREA = %s' % str(flow_area))
225                anuga.log.critical('PERIMETER = %s' % str(perimeter))
226                anuga.log.critical('Q Interim = %s' % str(Q))
227            hyd_rad = flow_area/perimeter
228
229
230
231            # Outlet control velocity using tail water
232            if local_debug =='true':
233                anuga.log.critical('GOT IT ALL CALCULATING Velocity')
234                anuga.log.critical('HydRad = %s' % str(hyd_rad))
235            # Calculate Pipe Culvert Outlet Control Velocity.... May need initial Estimate First ??
236           
237            culvert_velocity = math.sqrt(self.delta_total_energy/((self.sum_loss/2/anuga.g)+(self.manning**2*self.culvert_length)/hyd_rad**1.33333))
238            Q_outlet_tailwater = flow_area * culvert_velocity
239           
240           
241            if local_debug =='true':
242                anuga.log.critical('VELOCITY = %s' % str(culvert_velocity))
243                anuga.log.critical('Outlet Ctrl Q = %s' % str(Q_outlet_tailwater))
244
245            Q = min(Q, Q_outlet_tailwater)
246            if local_debug =='true':
247                anuga.log.critical('%s,%.3f,%.3f'
248                             % ('dcrit 1 , dcit2 =',dcrit1,dcrit2))
249                anuga.log.critical('%s,%.3f,%.3f,%.3f'
250                             % ('Q and Velocity and Depth=', Q,
251                                culvert_velocity, outlet_culvert_depth))
252
253            culv_froude=math.sqrt(Q**2*flow_width/(anuga.g*flow_area**3))
254            if local_debug =='true':
255                anuga.log.critical('FLOW AREA = %s' % str(flow_area))
256                anuga.log.critical('PERIMETER = %s' % str(perimeter))
257                anuga.log.critical('Q final = %s' % str(Q))
258                anuga.log.critical('FROUDE = %s' % str(culv_froude))
259
260            # Determine momentum at the outlet
261            barrel_velocity = Q/(flow_area + anuga.velocity_protection/flow_area)
262
263        else: # self.inflow.get_average_depth() < 0.01:
264            Q = barrel_velocity = outlet_culvert_depth = 0.0
265
266        # Temporary flow limit
267        if barrel_velocity > self.max_velocity:
268            barrel_velocity = self.max_velocity
269            Q = flow_area * barrel_velocity
270
271        return Q, barrel_velocity, outlet_culvert_depth
272
273       
274       
275       
Note: See TracBrowser for help on using the repository browser.