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

Last change on this file since 7839 was 7804, checked in by James Hudson, 15 years ago

Fixed up failing tests, updated user guide with new API (first few chapters only).

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