[8308] | 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 |
---|
[9053] | 12 | from anuga import create_domain_from_regions |
---|
[8308] | 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. |
---|
[8353] | 20 | chan_initial_depth = 0.65 # Initial depth of water in the channel |
---|
[8308] | 21 | chan_bankfull_depth = 1.0 # Bankfull depth of the channel |
---|
[9252] | 22 | chan_width = 10. # Bankfull width of the channel |
---|
[8308] | 23 | bankwidth = 2. # Width of the bank regions -- note that these protrude into the channel |
---|
| 24 | man_n=0.03 # Manning's n |
---|
[9252] | 25 | l0 = 2.000 # Length scale associated with triangle side length in channel (min_triangle area = 0.5*l0^2) |
---|
[8308] | 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 | |
---|
[9252] | 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. |
---|
[8308] | 51 | |
---|
[9252] | 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 | } |
---|
[8308] | 62 | |
---|
[9252] | 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 | |
---|
[8308] | 69 | # Define domain with appropriate boundary conditions |
---|
[9252] | 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) |
---|
[8308] | 86 | |
---|
[9252] | 87 | domain=anuga.create_domain_from_file('channel_floodplain1.msh') |
---|
[8308] | 88 | |
---|
[8446] | 89 | domain.set_name('channel_floodplain1') # Output name |
---|
[9252] | 90 | domain.set_store_vertices_uniquely(True) |
---|
[9056] | 91 | domain.set_flow_algorithm('DE1') |
---|
[8308] | 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 | |
---|
[9252] | 128 | domain.set_quantity('elevation', topography,location='centroids') # Use function for elevation |
---|
[8308] | 129 | domain.set_quantity('friction', man_n) # Constant friction |
---|
| 130 | domain.set_quantity('stage', stagetopo) # Use function for stage |
---|
[9053] | 131 | |
---|
[8308] | 132 | # Define inlet operator |
---|
[8446] | 133 | flow_in_yval=10.0 |
---|
[8308] | 134 | if True: |
---|
[8353] | 135 | line1 = [ [floodplain_width/2. - chan_width/2., flow_in_yval],\ |
---|
| 136 | [floodplain_width/2. + chan_width/2., flow_in_yval] \ |
---|
[8308] | 137 | ] |
---|
[9252] | 138 | Qin=4.5 |
---|
[8308] | 139 | |
---|
| 140 | Inlet_operator(domain, line1, Qin) |
---|
| 141 | |
---|
[9252] | 142 | print 'Discharge in = ', Qin |
---|
[8308] | 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 |
---|
[8353] | 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 | |
---|
[8308] | 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 | |
---|
[8353] | 177 | for t in domain.evolve(yieldstep=2.0, finaltime=3200.0): |
---|
[8308] | 178 | print domain.timestepping_statistics() |
---|
[8353] | 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########' |
---|
[8446] | 190 | s0 = domain.get_flow_through_cross_section([[0., 10.0], [floodplain_width, 10.]]) |
---|
[8353] | 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 | |
---|
[8446] | 194 | print 'Cross sectional flows: ', s0, s1, s2 |
---|
[8353] | 195 | print '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$' |
---|
| 196 | |
---|
[8308] | 197 | |
---|