1 | """Idealised urban flow example using ANUGA |
---|
2 | Water flowing over a floodplain with buildings |
---|
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 import create_domain_from_regions as create_domain_from_regions |
---|
12 | #from anuga.structures.inlet_operator import Inlet_operator |
---|
13 | |
---|
14 | #from balanced_dev import * |
---|
15 | #from balanced_dev import create_domain_from_regions as create_domain_from_regions |
---|
16 | from anuga_tsunami import * |
---|
17 | from anuga_tsunami import create_domain_from_regions as create_domain_from_regions |
---|
18 | #------------------------------------------------------------------------------ |
---|
19 | # Useful parameters for controlling this case |
---|
20 | #------------------------------------------------------------------------------ |
---|
21 | |
---|
22 | floodplain_length = 35.80 # Model domain length |
---|
23 | floodplain_width = 3.60 # Model domain width |
---|
24 | floodplain_slope = 0.0 #1./3000. |
---|
25 | #chan_initial_depth = 0.8 # Initial depth of water in the channel |
---|
26 | #chan_bankfull_depth = 1.0 # Bankfull depth of the channel |
---|
27 | #chan_width = 10.0 # Bankfull width of the channel |
---|
28 | #bankwidth = 2. # Width of the bank regions -- note that these protrude into the channel |
---|
29 | man_n=0.01 # Manning's n |
---|
30 | l0 = 0.05 #0.2501 # Length scale associated with triangle side length in channel (min_triangle area = 0.5*l0^2) |
---|
31 | |
---|
32 | #assert chan_width < floodplain_width, \ |
---|
33 | # ' ERROR: Channel width is greater than floodplain width' |
---|
34 | |
---|
35 | #assert bankwidth < chan_width/2., \ |
---|
36 | # 'ERROR: The bank width must be less than half the channel width' |
---|
37 | |
---|
38 | #------------------------------------------------------------------------------ |
---|
39 | # Setup computational domain |
---|
40 | #------------------------------------------------------------------------------ |
---|
41 | |
---|
42 | # Define boundary polygon -- in this case clockwise around the proposed boundary |
---|
43 | boundary_polygon = [ [0.,0.], |
---|
44 | [0., floodplain_width], |
---|
45 | [floodplain_length, floodplain_width], |
---|
46 | [floodplain_length, 0.], |
---|
47 | ] |
---|
48 | |
---|
49 | |
---|
50 | # Define domain with appropriate boundary conditions |
---|
51 | domain = create_domain_from_regions( boundary_polygon, |
---|
52 | boundary_tags={'left': [0], |
---|
53 | 'top': [1], |
---|
54 | 'right': [2], |
---|
55 | 'bottom': [3]}, |
---|
56 | maximum_triangle_area = 1.0*l0*l0, |
---|
57 | minimum_triangle_angle = 28, |
---|
58 | mesh_filename = 'urban_flow1.msh', |
---|
59 | use_cache=False, |
---|
60 | verbose=True) |
---|
61 | |
---|
62 | |
---|
63 | domain.set_name('urban_flow0p05') # Output name |
---|
64 | #domain.extrapolate_velocity_second_order=False |
---|
65 | #------------------------------------------------------------------------------ |
---|
66 | # |
---|
67 | # Setup initial conditions |
---|
68 | # |
---|
69 | #------------------------------------------------------------------------------ |
---|
70 | |
---|
71 | ## Snippet of code to test the topography function |
---|
72 | ## We define x,y, then look at z(x,y) to see if it is correct (I use |
---|
73 | ## pyplot.scatter for this) |
---|
74 | ## Predefine x,y to be long enough |
---|
75 | #increm=0.05 |
---|
76 | #x = numpy.ones(int(((floodplain_length)/increm+1.0)*((floodplain_width)/increm+1.0) )) |
---|
77 | #y = numpy.ones(int(((floodplain_length)/increm+1.0)*((floodplain_width)/increm+1.0) )) |
---|
78 | ## Fill out x,y |
---|
79 | #counter=0 |
---|
80 | #for i in numpy.arange(0.0,floodplain_length, increm): |
---|
81 | # for j in numpy.arange(0.0, floodplain_width, increm): |
---|
82 | # x[counter]=i |
---|
83 | # y[counter]=j |
---|
84 | # counter=counter+1 |
---|
85 | # |
---|
86 | #z = topography(x,y) |
---|
87 | |
---|
88 | # Function for topography, based on S. Soares Frazao, Noel and Zech, |
---|
89 | # Experiments of dam break flow in the presence of obstables. |
---|
90 | # J. Hydraulic Research |
---|
91 | def topography(x, y): |
---|
92 | #import pdb |
---|
93 | #pdb.set_trace() |
---|
94 | # Define 'bare-earth' topography |
---|
95 | structure_height=0.8 |
---|
96 | elev1= 0.0*y #-y*floodplain_slope |
---|
97 | # Define constriction |
---|
98 | elev2 = (x>6.9)*(x<7.7)*(y<1.3)*structure_height + \ |
---|
99 | (x>6.9)*(x<7.7)*(3.6-y<1.3)*structure_height |
---|
100 | |
---|
101 | # Add sloping edges |
---|
102 | elev2b = (0.34 - y)*(0.155/0.34)*(y<0.34) + (0.155 - (floodplain_width-y)*(0.155/0.34))*(y>=floodplain_width-0.34) |
---|
103 | |
---|
104 | # Define building. |
---|
105 | # Do this by using rotated coordinates. |
---|
106 | alpha = 64.0/180.0*numpy.pi |
---|
107 | short_side = 0.4 |
---|
108 | long_side=0.8 |
---|
109 | # The lower left building corner is at (11.10, 1.75) |
---|
110 | ll = (11.10, 1.75) |
---|
111 | # The lower right building corner is at (11.10, 1.75) + 0.4*(numpy.sin(alpha), -numpy.cos(alpha)) |
---|
112 | lr = (ll[0] + short_side*numpy.sin(alpha), ll[1] -short_side*numpy.cos(alpha)) |
---|
113 | # The upper left building corner is at (11.10, 1.75) + 0.8*(numpy.cos(64./180.), numpy.sin(64./180.)) |
---|
114 | ul = (ll[0] + long_side*numpy.cos(alpha), ll[1] + long_side*numpy.sin(alpha)) |
---|
115 | c1 = y-numpy.tan(alpha)*x # Coordinate parallel to the long side of the building |
---|
116 | c2 = y +1.0/(numpy.tan(alpha))*x # Coordinate parallel to the short side of the building |
---|
117 | elev3 = (c1 < (ll[1] - numpy.tan(alpha)*ll[0]) )*\ |
---|
118 | (c1 > (lr[1] - numpy.tan(alpha)*lr[0]) )*\ |
---|
119 | (c2 < (ul[1] + 1.0/numpy.tan(alpha)*ul[0]) )*\ |
---|
120 | (c2 > (ll[1] + 1.0/numpy.tan(alpha)*ll[0]) )*\ |
---|
121 | structure_height |
---|
122 | return elev1 + elev2 + elev2b + elev3 |
---|
123 | |
---|
124 | #Function for stage |
---|
125 | def stagetopo(x,y): |
---|
126 | return (x<7.7)*0.39 + 0.01 |
---|
127 | |
---|
128 | domain.set_quantity('elevation', topography) # 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 | |
---|
133 | #------------------------------------------------------------------------------ |
---|
134 | # |
---|
135 | # Setup boundary conditions |
---|
136 | # |
---|
137 | #------------------------------------------------------------------------------ |
---|
138 | |
---|
139 | # Trial a set_stage_transmissive_momentum inflow boundary |
---|
140 | def inflow_stage_boundary(t): |
---|
141 | return chan_initial_depth - chan_bankfull_depth |
---|
142 | # transmissive_momentum_set_stage |
---|
143 | Bin_tmss = anuga.shallow_water.boundaries.Transmissive_momentum_set_stage_boundary(domain=domain, function = inflow_stage_boundary) |
---|
144 | |
---|
145 | # Standard boundary conditions |
---|
146 | Br = anuga.Reflective_boundary(domain) # Solid reflective wall |
---|
147 | Bt = anuga.Transmissive_boundary(domain) # Transmissive boundary |
---|
148 | # Outflow boundary conditions |
---|
149 | def outflow_stage_boundary(t): |
---|
150 | return -floodplain_length*floodplain_slope \ |
---|
151 | + chan_initial_depth - chan_bankfull_depth |
---|
152 | Bout_tmss = anuga.shallow_water.boundaries.Transmissive_momentum_set_stage_boundary(domain, function = outflow_stage_boundary) |
---|
153 | |
---|
154 | # Define boundary conditions |
---|
155 | domain.set_boundary({'left': Br, |
---|
156 | 'right': Br, |
---|
157 | 'top': Br, |
---|
158 | 'bottom': Br}) |
---|
159 | |
---|
160 | |
---|
161 | # To monitor the boundary conditions, let's find centroid points representing sub and super critical flows. |
---|
162 | #inpt = numpy.argmin( ( abs(domain.centroid_coordinates[:,0] - floodplain_width/2.) + \ |
---|
163 | # abs(domain.centroid_coordinates[:,1] - 0.0) ) ) |
---|
164 | #outpt = numpy.argmin( ( abs(domain.centroid_coordinates[:, 0] - floodplain_width/2.) +\ |
---|
165 | # abs(domain.centroid_coordinates[:, 1] - floodplain_length) ) ) |
---|
166 | |
---|
167 | #------------------------------------------------------------------------------ |
---|
168 | # |
---|
169 | # Evolve system through time |
---|
170 | # |
---|
171 | #------------------------------------------------------------------------------ |
---|
172 | |
---|
173 | for t in domain.evolve(yieldstep=0.3, finaltime=40.0): |
---|
174 | print domain.timestepping_statistics() |
---|
175 | |
---|