1 | """Simple water flow example using ANUGA |
---|
2 | Water flowing down a channel with a floodplain |
---|
3 | """ |
---|
4 | |
---|
5 | #------------------------------------------------------------------------------ |
---|
6 | # Import necessary modules |
---|
7 | #------------------------------------------------------------------------------ |
---|
8 | # Import standard shallow water domain and standard boundaries. |
---|
9 | import anuga |
---|
10 | import numpy |
---|
11 | from anuga.structures.inlet_operator import Inlet_operator |
---|
12 | from anuga import create_domain_from_regions |
---|
13 | #------------------------------------------------------------------------------ |
---|
14 | # Useful parameters for controlling this case |
---|
15 | #------------------------------------------------------------------------------ |
---|
16 | |
---|
17 | floodplain_length = 1000.0 # Model domain length |
---|
18 | floodplain_width = 14.0 # Model domain width |
---|
19 | floodplain_slope = 1./300. |
---|
20 | chan_initial_depth = 0.65 # Initial depth of water in the channel |
---|
21 | chan_bankfull_depth = 1.0 # Bankfull depth of the channel |
---|
22 | chan_width = 10. # Bankfull width of the channel |
---|
23 | bankwidth = 2. # Width of the bank regions -- note that these protrude into the channel |
---|
24 | man_n=0.03 # Manning's n |
---|
25 | l0 = 2.000 # Length scale associated with triangle side length in channel (min_triangle area = 0.5*l0^2) |
---|
26 | |
---|
27 | assert chan_width < floodplain_width, \ |
---|
28 | ' ERROR: Channel width is greater than floodplain width' |
---|
29 | |
---|
30 | assert bankwidth < chan_width/2., \ |
---|
31 | 'ERROR: The bank width must be less than half the channel width' |
---|
32 | |
---|
33 | #------------------------------------------------------------------------------ |
---|
34 | # Setup computational domain |
---|
35 | #------------------------------------------------------------------------------ |
---|
36 | |
---|
37 | # Define boundary polygon -- in this case clockwise around the proposed boundary |
---|
38 | boundary_polygon = [ [0.,0.], |
---|
39 | [0., floodplain_length], |
---|
40 | [floodplain_width/2. - chan_width/2., floodplain_length], |
---|
41 | [floodplain_width/2. + chan_width/2., floodplain_length], |
---|
42 | [floodplain_width, floodplain_length], |
---|
43 | [floodplain_width, 0.], |
---|
44 | [floodplain_width/2. + chan_width/2., 0.], |
---|
45 | [floodplain_width/2. - chan_width/2., 0.] |
---|
46 | ] |
---|
47 | |
---|
48 | ## Define channel polygon, where we can optionally refine the resolution. |
---|
49 | ## Note that we set this a distance l0 inside the boundary polygon, so the polygons |
---|
50 | ## do not overlap. |
---|
51 | |
---|
52 | breakLines={'n1':[[floodplain_width/2.- chan_width/2., floodplain_length], |
---|
53 | [floodplain_width/2. - chan_width/2.,0.]], |
---|
54 | 'n2':[[floodplain_width/2.+ chan_width/2., floodplain_length], |
---|
55 | [floodplain_width/2. + chan_width/2.,0.]], |
---|
56 | # These ones are inside the channel |
---|
57 | 'n3':[[floodplain_width/2.- chan_width/2.+bankwidth, floodplain_length], |
---|
58 | [floodplain_width/2. - chan_width/2.+bankwidth,0.]], |
---|
59 | 'n4':[[floodplain_width/2.+ chan_width/2.-bankwidth, floodplain_length], |
---|
60 | [floodplain_width/2. + chan_width/2-bankwidth,0.]] |
---|
61 | } |
---|
62 | |
---|
63 | regionPtAreas=[[0.01, 0.01, 0.5*l0*l0], |
---|
64 | [floodplain_width/2.-chan_width/2.+0.01, 0.01, 0.5*l0*l0*0.25], |
---|
65 | [floodplain_width/2.-chan_width/2.+bankwidth+0.01, 0.01, 0.5*l0*l0], |
---|
66 | [floodplain_width/2.+chan_width/2.-bankwidth+0.01, 0.01, 0.5*l0*l0*0.25], |
---|
67 | [floodplain_width/2.+chan_width/2.+0.01, 0.01, 0.5*l0*l0]] |
---|
68 | |
---|
69 | # Define domain with appropriate boundary conditions |
---|
70 | anuga.create_mesh_from_regions(boundary_polygon, |
---|
71 | boundary_tags={'left': [0], |
---|
72 | 'top1': [1], |
---|
73 | 'chan_out': [2], |
---|
74 | 'top2': [3], |
---|
75 | 'right': [4], |
---|
76 | 'bottom1': [5], |
---|
77 | 'chan_in': [6], |
---|
78 | 'bottom2': [7] }, |
---|
79 | maximum_triangle_area = 0.5*l0*l0, |
---|
80 | minimum_triangle_angle = 28.0, |
---|
81 | filename = 'channel_floodplain1.msh', |
---|
82 | breaklines=breakLines.values(), |
---|
83 | regionPtArea=regionPtAreas, |
---|
84 | use_cache=False, |
---|
85 | verbose=True) |
---|
86 | |
---|
87 | domain=anuga.create_domain_from_file('channel_floodplain1.msh') |
---|
88 | |
---|
89 | domain.set_name('channel_floodplain1') # Output name |
---|
90 | domain.set_store_vertices_uniquely(True) |
---|
91 | domain.set_flow_algorithm('DE1') |
---|
92 | #------------------------------------------------------------------------------ |
---|
93 | # |
---|
94 | # Setup initial conditions |
---|
95 | # |
---|
96 | #------------------------------------------------------------------------------ |
---|
97 | |
---|
98 | # Function for topography |
---|
99 | def topography(x, y): |
---|
100 | # Longitudinally sloping floodplain with channel in centre |
---|
101 | elev1= -y*floodplain_slope - chan_bankfull_depth*\ |
---|
102 | (x>(floodplain_width/2. - chan_width/2.))*\ |
---|
103 | (x<(floodplain_width/2. + chan_width/2.)) |
---|
104 | # Add banks |
---|
105 | if(bankwidth>0.0): |
---|
106 | leftbnk = floodplain_width/2. - chan_width/2. |
---|
107 | rightbnk = floodplain_width/2. + chan_width/2. |
---|
108 | # Left bank |
---|
109 | elev2 = elev1 + (chan_bankfull_depth \ |
---|
110 | - chan_bankfull_depth/bankwidth*(x - leftbnk))*\ |
---|
111 | (x>leftbnk)*(x < leftbnk + bankwidth) |
---|
112 | # Right bank |
---|
113 | elev2 = elev2 + (chan_bankfull_depth \ |
---|
114 | + chan_bankfull_depth/bankwidth*(x - rightbnk))*\ |
---|
115 | (x>rightbnk-bankwidth)*(x < rightbnk) |
---|
116 | |
---|
117 | if(bankwidth==0.0): |
---|
118 | elev2 = elev1 |
---|
119 | # |
---|
120 | return elev2 |
---|
121 | |
---|
122 | # |
---|
123 | |
---|
124 | #Function for stage |
---|
125 | def stagetopo(x,y): |
---|
126 | return -y*floodplain_slope -chan_bankfull_depth + chan_initial_depth |
---|
127 | |
---|
128 | domain.set_quantity('elevation', topography,location='centroids') # Use function for elevation |
---|
129 | domain.set_quantity('friction', man_n) # Constant friction |
---|
130 | domain.set_quantity('stage', stagetopo) # Use function for stage |
---|
131 | |
---|
132 | # Define inlet operator |
---|
133 | flow_in_yval=10.0 |
---|
134 | if True: |
---|
135 | line1 = [ [floodplain_width/2. - chan_width/2., flow_in_yval],\ |
---|
136 | [floodplain_width/2. + chan_width/2., flow_in_yval] \ |
---|
137 | ] |
---|
138 | Qin=4.5 |
---|
139 | |
---|
140 | Inlet_operator(domain, line1, Qin) |
---|
141 | |
---|
142 | print 'Discharge in = ', Qin |
---|
143 | #------------------------------------------------------------------------------ |
---|
144 | # |
---|
145 | # Setup boundary conditions |
---|
146 | # |
---|
147 | #------------------------------------------------------------------------------ |
---|
148 | |
---|
149 | Br = anuga.Reflective_boundary(domain) # Solid reflective wall |
---|
150 | Bt = anuga.Transmissive_boundary(domain) # Transmissive boundary |
---|
151 | Bout_sub = anuga.Dirichlet_boundary( \ |
---|
152 | [-floodplain_length*floodplain_slope - chan_bankfull_depth + \ |
---|
153 | chan_initial_depth, 0., 0.]) #An outflow boundary for subcritical steady flow |
---|
154 | |
---|
155 | def outflow_stage_boundary(t): |
---|
156 | return -floodplain_length*floodplain_slope \ |
---|
157 | + chan_initial_depth - chan_bankfull_depth |
---|
158 | |
---|
159 | Bout_tmss = anuga.shallow_water.boundaries.Transmissive_momentum_set_stage_boundary(domain, function = outflow_stage_boundary) |
---|
160 | |
---|
161 | domain.set_boundary({'left': Br, |
---|
162 | 'right': Br, |
---|
163 | 'top1': Bt, |
---|
164 | 'top2': Bt, |
---|
165 | 'bottom1': Br, |
---|
166 | 'bottom2': Br, |
---|
167 | 'chan_out': Bout_tmss, |
---|
168 | 'chan_in': Br}) |
---|
169 | |
---|
170 | |
---|
171 | #------------------------------------------------------------------------------ |
---|
172 | # |
---|
173 | # Evolve system through time |
---|
174 | # |
---|
175 | #------------------------------------------------------------------------------ |
---|
176 | |
---|
177 | for t in domain.evolve(yieldstep=2.0, finaltime=3200.0): |
---|
178 | print domain.timestepping_statistics() |
---|
179 | xx=domain.quantities['ymomentum'].centroid_values |
---|
180 | dd=(domain.quantities['stage'].centroid_values - domain.quantities['elevation'].centroid_values) |
---|
181 | dd=dd*(dd>0.) |
---|
182 | |
---|
183 | tmp = xx/(dd+1.0e-06)*(dd>0.0) |
---|
184 | print tmp.max(), tmp.argmax(), tmp.min(), tmp.argmin() |
---|
185 | |
---|
186 | # Compute flow through cross-section -- check that the inflow boundary condition is doing its job |
---|
187 | # This also provides another useful steady-state check |
---|
188 | if( numpy.floor(t/100.) == t/100. ): |
---|
189 | print '#### COMPUTING FLOW THROUGH CROSS-SECTIONS########' |
---|
190 | s0 = domain.get_flow_through_cross_section([[0., 10.0], [floodplain_width, 10.]]) |
---|
191 | s1 = domain.get_flow_through_cross_section([[0., floodplain_length-300.0], [floodplain_width, floodplain_length-300.0]]) |
---|
192 | s2 = domain.get_flow_through_cross_section([[0., floodplain_length-1.0], [floodplain_width, floodplain_length-1.0]]) |
---|
193 | |
---|
194 | print 'Cross sectional flows: ', s0, s1, s2 |
---|
195 | print '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' |
---|
196 | |
---|
197 | |
---|