1 | """ |
---|
2 | Periodic water flows using ANUGA, |
---|
3 | where water driven up a linear sloping beach and time varying boundary. |
---|
4 | Ref1: Carrier and Greenspan, Journal of Fluid Mechanics, 1958 |
---|
5 | Ref2: Mungkasi and Roberts, Int. J. Numerical Methods in Fluids, 2012 |
---|
6 | """ |
---|
7 | |
---|
8 | #------------------------------------------------------------------------------ |
---|
9 | # Import necessary modules |
---|
10 | #------------------------------------------------------------------------------ |
---|
11 | import sys |
---|
12 | import anuga |
---|
13 | from anuga import Domain as Domain |
---|
14 | from math import cos |
---|
15 | from numpy import zeros, array, float |
---|
16 | from time import localtime, strftime, gmtime |
---|
17 | from scipy.optimize import fsolve |
---|
18 | from math import sin, pi, exp, sqrt |
---|
19 | from scipy.special import jn |
---|
20 | #from run_carrier_greenspan_analytic import * |
---|
21 | #from balanced_dev import * |
---|
22 | |
---|
23 | |
---|
24 | #------------------------------------------------------------------------------- |
---|
25 | # Copy scripts to time stamped output directory and capture screen |
---|
26 | # output to file |
---|
27 | #------------------------------------------------------------------------------- |
---|
28 | time = strftime('%Y%m%d_%H%M%S',localtime()) |
---|
29 | |
---|
30 | #output_dir = 'carrier_greenspan_'+time |
---|
31 | output_dir = '.' |
---|
32 | output_file = 'carrier_greenspan' |
---|
33 | |
---|
34 | #anuga.copy_code_files(output_dir,__file__) |
---|
35 | #start_screen_catcher(output_dir+'_') |
---|
36 | |
---|
37 | |
---|
38 | #------------------------------------------------------------------------------ |
---|
39 | # Setup domain |
---|
40 | #------------------------------------------------------------------------------ |
---|
41 | #DIMENSIONAL PARAMETERS |
---|
42 | dx = 100. |
---|
43 | dy = dx |
---|
44 | L = 5e4 # Length of channel (m) |
---|
45 | W = 5*dx # Width of channel (m) |
---|
46 | h0 = 5e2 # Height at origin when the water is still |
---|
47 | Tp = 900.0 # Period of oscillation |
---|
48 | a = 1.0 # Amplitude at origin |
---|
49 | g = 9.81 # Gravity |
---|
50 | |
---|
51 | # Bessel functions |
---|
52 | def j0(x): |
---|
53 | return jn(0.0, x) |
---|
54 | |
---|
55 | def j1(x): |
---|
56 | return jn(1.0, x) |
---|
57 | |
---|
58 | #DIMENSIONLESS PARAMETERS |
---|
59 | eps = a/h0 |
---|
60 | T = Tp*sqrt(g*h0)/L |
---|
61 | A = eps/j0(4.0*pi/T) |
---|
62 | |
---|
63 | # structured mesh |
---|
64 | #points, vertices, boundary = anuga.rectangular_cross(int(1.1*L/dx), int(W/dy), 1.1*L, W, (-1.1*L/2.0, -W/2.0)) |
---|
65 | points, vertices, boundary = anuga.rectangular_cross(int(1.1*L/dx), int(W/dy), 1.1*L, W, (0.0, 0.0)) |
---|
66 | |
---|
67 | domain = Domain(points, vertices, boundary) |
---|
68 | domain.set_name(output_file) |
---|
69 | domain.set_datadir(output_dir) |
---|
70 | |
---|
71 | #------------------------------------------------------------------------------ |
---|
72 | # Setup Algorithm, either using command line arguments |
---|
73 | # or override manually yourself |
---|
74 | #------------------------------------------------------------------------------ |
---|
75 | from anuga.utilities.argparsing import parse_standard_args |
---|
76 | alg, cfl = parse_standard_args() |
---|
77 | domain.set_flow_algorithm(alg) |
---|
78 | domain.set_CFL(cfl) |
---|
79 | |
---|
80 | #------------------------------------------------------------------------------ |
---|
81 | # Setup initial conditions |
---|
82 | #------------------------------------------------------------------------------ |
---|
83 | domain.set_quantity('friction', 0.0) |
---|
84 | |
---|
85 | def elevation(x,y): |
---|
86 | N = len(x) |
---|
87 | z = zeros(N, float) |
---|
88 | for i in range(N): |
---|
89 | z[i] = (h0/L)*x[i] - h0 |
---|
90 | return z |
---|
91 | domain.set_quantity('elevation', elevation) |
---|
92 | |
---|
93 | def height(x,y): |
---|
94 | N = len(x) |
---|
95 | h = zeros(N, float) |
---|
96 | for i in range(N): |
---|
97 | h[i] = h0 - (h0/L)*x[i] |
---|
98 | if h[i] < 0.0: |
---|
99 | h[i] = 0.0 |
---|
100 | return h |
---|
101 | domain.set_quantity('height', height) |
---|
102 | |
---|
103 | def stage(x,y): |
---|
104 | h = height(x,y) |
---|
105 | z = elevation(x,y) |
---|
106 | return h+z |
---|
107 | domain.set_quantity('stage', stage) |
---|
108 | |
---|
109 | |
---|
110 | |
---|
111 | #----------------------------------------------------------------------------- |
---|
112 | # Setup boundary conditions |
---|
113 | #------------------------------------------------------------------------------ |
---|
114 | ##def shore(t): |
---|
115 | ## def g(u): |
---|
116 | ## return u + 2.0*A*pi/T*sin(2.0*pi/T*(t+u)) |
---|
117 | ## u = fsolve(g,0.0) |
---|
118 | ## xi = -0.5*u*u + A*cos(2.0*pi/T*(t+u)) |
---|
119 | ## position = 1.0 + xi |
---|
120 | ## return position, u # dimensionless |
---|
121 | |
---|
122 | def prescribe(x,t): |
---|
123 | q = zeros(2) |
---|
124 | def fun(q): # Here q=(w, u) |
---|
125 | f = zeros(2) |
---|
126 | f[0] = q[0] + 0.5*q[1]**2.0 - A*j0(4.0*pi/T*(1.0+q[0]-x)**0.5)*cos(2.0*pi/T*(t+q[1])) |
---|
127 | f[1] = q[1] + A*j1(4.0*pi/T*(1.0+q[0]-x)**0.5)*sin(2.0*pi/T*(t+q[1]))/(1+q[0]-x)**0.5 |
---|
128 | return f |
---|
129 | q = fsolve(fun,q) |
---|
130 | return q[0], q[1] # dimensionless |
---|
131 | |
---|
132 | def f_CG(t): |
---|
133 | timing = t*sqrt(g*h0)/L # dimensionless |
---|
134 | w, u = prescribe(0.0,timing) # dimensionless |
---|
135 | wO = w*h0 # dimensional |
---|
136 | uO = u*sqrt(g*h0) # dimensional |
---|
137 | zO = -h0 # dimensional |
---|
138 | hO = wO - zO # dimensional |
---|
139 | pO = uO * hO # dimensional |
---|
140 | #[ 'stage', 'Xmomentum', 'Ymomentum'] |
---|
141 | return [wO, pO, 0.0] # dimensional |
---|
142 | |
---|
143 | Br = anuga.Reflective_boundary(domain) # Solid reflective wall |
---|
144 | Bt = anuga.Transmissive_boundary(domain) # Continue all values on boundary |
---|
145 | #Bd = anuga.Dirichlet_boundary([1,0.,0.]) # Constant boundary values |
---|
146 | BTime = anuga.Time_boundary(domain,f_CG) |
---|
147 | # Associate boundary tags with boundary objects |
---|
148 | domain.set_boundary({'left': BTime, 'right': Bt, 'top': Br, 'bottom': Br}) |
---|
149 | |
---|
150 | |
---|
151 | #=============================================================================== |
---|
152 | ##from anuga.visualiser import RealtimeVisualiser |
---|
153 | ##vis = RealtimeVisualiser(domain) |
---|
154 | ##vis.render_quantity_height("stage", zScale =h0*500, dynamic=True) |
---|
155 | ##vis.colour_height_quantity('stage', (0.0, 0.5, 1.0)) |
---|
156 | ##vis.start() |
---|
157 | #=============================================================================== |
---|
158 | |
---|
159 | |
---|
160 | #------------------------------------------------------------------------------ |
---|
161 | # Evolve system through time |
---|
162 | #------------------------------------------------------------------------------ |
---|
163 | for t in domain.evolve(yieldstep = Tp/6, finaltime = 10*Tp): |
---|
164 | #print domain.timestepping_statistics(track_speeds=True) |
---|
165 | print domain.timestepping_statistics() |
---|
166 | #vis.update() |
---|
167 | |
---|
168 | |
---|
169 | #test against know data |
---|
170 | |
---|
171 | #vis.evolveFinished() |
---|
172 | |
---|