source: anuga_work/development/classroom/ripcurrent.py @ 7587

Last change on this file since 7587 was 7587, checked in by ole, 14 years ago

Rohan's comments and additions

File size: 8.7 KB
Line 
1"""ANUGA simulation of simple rip current.
2
3Source: Geometry and wave properties loosely based on those presented in
4OBSERVATIONS OF LABORATORY RIP CURRENTS by Brian K. Sapp,
5School of Civil and Environmental Engineering
6Georgia Institute of Technology
7May 2006
8
9I will need to make a version which has the exact same geometry as the Georgia Tech wavetank
10if we wish to use a comparison to the results of this study as ANUGA validation as i played
11with the geometry somewhat as i completed this model.
12"""
13
14#------------------------------------------------------------------------------
15# Import necessary modules
16#------------------------------------------------------------------------------
17from anuga.interface import create_domain_from_regions
18from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
19from anuga.shallow_water.shallow_water_domain import Reflective_boundary
20from anuga.shallow_water.shallow_water_domain import Time_boundary
21from anuga.shallow_water.data_manager import get_mesh_and_quantities_from_file
22from pylab import figure, quiver, show, cos, sin, pi
23import numpy
24import csv
25import time
26
27
28#------------------------------------------------------------------------------
29# Parameters
30#------------------------------------------------------------------------------
31
32filename = "WORKING-RIP-LAB_Expt-Geometry_Triangular_Mesh"
33
34location_of_shore = 140 # The position along the y axis of the shorefront
35sandbar = 1.2           # Height of sandbar
36sealevel = 0            # Height of coast above sea level
37steepness = 8000        # Period of sandbar -
38                        # larger number gives smoother slope - longer period
39halfchannelwidth = 5
40bank_slope = 0.1
41simulation_length = 1
42timestep = 1
43
44
45#------------------------------------------------------------------------------
46# Setup computational domain
47#------------------------------------------------------------------------------
48length = 120
49width = 170
50seafloor_resolution = 60.0 # Resolution: Max area of triangles in the mesh
51feature_resolution = 1.0
52beach_resolution = 10.0
53
54sea_boundary_polygon = [[0,0],[length,0],[length,width],[0,width]]
55feature_boundary_polygon = [[0,100],[length,100],[length,150],[0,150]]
56beach_interior_polygon = [[0,150],[length,150],[length,width],[0,width]]
57
58meshname = str(filename)+'.msh'
59
60# Interior regions
61feature_regions = [[feature_boundary_polygon, feature_resolution],
62                   [beach_interior_polygon, beach_resolution]]
63
64domain = create_domain_from_regions(sea_boundary_polygon,
65                                    boundary_tags={'bottom': [0],
66                                                   'right' : [1],
67                                                   'top' :   [2],
68                                                   'left':   [3]},
69                                    maximum_triangle_area=seafloor_resolution,
70                                    mesh_filename=meshname,
71                                    interior_regions=feature_regions,
72                                    use_cache=True,
73                                    verbose=True)
74                                   
75domain.set_name(filename) # Output name
76print domain.statistics()
77
78
79#------------------------------------------------------------------------------
80# Setup initial conditions
81#------------------------------------------------------------------------------
82def topography(x,y):
83    """Complex topography defined by a function of vectors x and y."""
84
85    # General slope, sets the shore at the location defined previously
86    z=0.05*(y-location_of_shore)
87
88    #Creates a steeper slope close to the seaward boundary giving a region of deepwater
89    N = len(x)
90    for i in range(N):
91        if y[i] < 25:
92            z[i] = 0.2*(y[i]-25) + 0.05*(y[i]-location_of_shore)
93    #Creates a steeper slope close to the landward boundary, simulating a beach etc
94    #(helps to prevent too much reflection of wave energy off the landward boundary)         
95    for i in range(N):
96        if y[i]>150:
97            z[i] = 0.1*(y[i]-150) + 0.05*(y[i]-location_of_shore)
98
99    return z
100
101
102def topography3(x,y):
103    z=0*x
104   
105    N = len(x)
106   
107    # Sets up the left hand side of the sandbank
108    #amount which it deviates from parallel with the beach is controlled by 'bank_slope'
109    #width of the channel (the gap between the two segments of the sandbank) is controlled by 'halfchannelwidth'
110    #the height of the sandbar is controlled by 'sandbar'
111    #'steepness' provides control over the slope of the soundbar (smaller values give a more rounded shape, if too small will produce peaks and troughs)
112   
113    for i in range(N):
114        ymin = -bank_slope*x[i] + 112 
115        ymax = -bank_slope*x[i] + 124
116        xmin = 0
117        xmax = length/2-halfchannelwidth
118        if ymin < y[i] < ymax and xmin < x[i]< xmax:
119            z[i] += sandbar*cos((y[i]-118)/steepness)
120   
121    # Sets up the right hand side of the sandbank
122    #changing the sign in y min and y max allows the two halves of the sandbank to form a v shape
123   
124    for i in range(N):
125        ymin = -bank_slope*(x[i]-length/2) - bank_slope*length/2 + 112
126        ymax = -bank_slope*(x[i]-length/2) - bank_slope*length/2 + 124
127        xmin = length/2+halfchannelwidth
128        xmax = 183
129        if ymin < y[i] < ymax and xmin < x[i] < xmax:
130            z[i] += sandbar*cos((y[i]-118)/steepness)
131           
132    return z
133
134domain.set_quantity('elevation', topography)  # Apply base elevation function
135domain.add_quantity('elevation', topography3) # Add elevation modification
136domain.set_quantity('friction', 0.01)         # Constant friction
137domain.set_quantity('stage', 0)               # Constant initial condition at mean sea level
138
139
140#------------------------------------------------------------------------------
141# Setup boundary conditions
142#------------------------------------------------------------------------------
143Bi = Dirichlet_boundary([0.4, 0, 0])          # Inflow
144Br = Reflective_boundary(domain)              # Solid reflective wall
145Bo = Dirichlet_boundary([-5, 0, 0])           # Outflow
146
147def wave(t):
148    """Define wave driving the system
149    """
150   
151    A = 0.4  # Amplitude of wave [m] (wave height)
152    T = 5    # Wave period [s]
153
154    if t < 30000000000:
155        return [A*sin(2*pi*t/T) + 1, 0, 0] 
156    else:
157        return [0.0, 0, 0]
158
159Bt = Time_boundary(domain, f=wave)
160
161
162domain.set_boundary({'left': Br, 'right': Br, 'top': Bo, 'bottom': Bt})
163
164
165#------------------------------------------------------------------------------
166# Evolve system through time
167#------------------------------------------------------------------------------
168
169# Read in gauge locations for interpolation and convert them to floats
170gauge_file = open('New_gauges.csv', 'r')
171G = [(float(x[0]), float(x[1])) for x in csv.reader(gauge_file,
172                                                    dialect='excel', 
173                                                    delimiter=',')]
174gauges = numpy.array(G)
175number_of_gauges = len(gauges)
176
177# Allocate space for velocity values
178u = numpy.zeros(number_of_gauges)
179v = numpy.zeros(number_of_gauges)
180
181t0 = time.time()
182for t in domain.evolve(yieldstep = timestep, finaltime = simulation_length):
183    print domain.timestepping_statistics()
184    S = domain.get_quantity('stage').get_values(interpolation_points=gauges)
185    E = domain.get_quantity('elevation').get_values(interpolation_points=gauges)
186    depth = S-E
187
188    uh = domain.get_quantity('xmomentum').get_values(interpolation_points=gauges)
189    vh = domain.get_quantity('ymomentum').get_values(interpolation_points=gauges)
190    u += uh/depth
191    v += vh/depth
192
193   
194#------------------------------------------------------------------------------
195# Post processing
196#------------------------------------------------------------------------------
197
198n_time_intervals = simulation_length/timestep
199print 'There were %i time steps' % n_time_intervals
200
201U = u/n_time_intervals
202V = v/n_time_intervals
203X = gauges[:,0] 
204Y = gauges[:,1] 
205
206
207print 'Computation took %.2f seconds' % (time.time()-t0)
208
209key_auto_length = (max(V))/5     #makes the key vector a sensible length not sure how to label it with the correct value though
210
211from matplotlib import *
212from pylab import *
213
214figure()
215Q = quiver(X,Y,U,V)
216qk = quiverkey(Q,0.8,0.05,key_auto_length,r'$unknown \frac{m}{s}$',labelpos='E',        #need to get the label to show the value of key_auto_length
217               coordinates='figure', fontproperties={'weight': 'bold'})
218axis([-10,length + 10, -10, width +10])
219title('Simulation of a Rip-Current, Average Velocity Vector Field')
220
221axhline(y=25,color='b')
222axhline(y=(location_of_shore),color='r')
223
224x1 = arange(0,55,1)
225y1 = -(bank_slope)*x1 + 112
226y12 = -(bank_slope)*x1 + 124
227
228x2 = arange(65,length,1)
229y2 = -(bank_slope)*x2 + 112
230y22 = -(bank_slope)*x2 + 124
231
232plot(x1,y1,x1,y12,x2,y2,x2,y22,color='g')
233show()
234
235
Note: See TracBrowser for help on using the repository browser.