1 | from scipy import sin, cos, sqrt, linspace, pi, dot |
---|
2 | from numpy import zeros, array |
---|
3 | from scipy.special import jn |
---|
4 | from scipy.optimize import fsolve |
---|
5 | from gaussPivot import * |
---|
6 | |
---|
7 | |
---|
8 | #Parameters |
---|
9 | g = 9.81 |
---|
10 | |
---|
11 | def j0(x): |
---|
12 | return jn(0.0, x) |
---|
13 | |
---|
14 | def j1(x): |
---|
15 | return jn(1.0, x) |
---|
16 | |
---|
17 | def analytic_cg(points, t=0.0, h0=5e2, L=5e4, a=1.0, Tp=900.0): |
---|
18 | # |
---|
19 | #Exact solution of the Carrier-Greenspan periodic solution. |
---|
20 | #Ref1: Carrier and Greenspan, J. Fluid Mech., 1958 |
---|
21 | #Ref2: Mungkasi and Roberts, Int. J. Numer. Meth. Fluids, 2012 |
---|
22 | #Here, points are the spatial evaluating points, t is time variable, h0 is the water depth at Origin |
---|
23 | #L is the horizontal length considered, a is the amplitude of perturbation at Origin |
---|
24 | #Tp is the period of oscillation. |
---|
25 | # |
---|
26 | #Analytical computations################################################################# |
---|
27 | def shore(t): |
---|
28 | def g(u): |
---|
29 | return u + 2.0*A*pi/T*sin(2.0*pi/T*(t+u)) |
---|
30 | u = fsolve(g,0.0) |
---|
31 | xi = -0.5*u*u + A*cos(2.0*pi/T*(t+u)) |
---|
32 | position = 1.0 + xi |
---|
33 | return position, u |
---|
34 | |
---|
35 | def func(q): #Here q=(w, u) |
---|
36 | f = zeros(2) |
---|
37 | 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*(tim+q[1])) |
---|
38 | f[1] = q[1] + A*j1(4.0*pi/T*(1.0+q[0]-x)**0.5)*sin(2.0*pi/T*(tim+q[1]))/(1+q[0]-x)**0.5 |
---|
39 | return f |
---|
40 | |
---|
41 | def newtonRaphson2(f,q,tol=1.0e-15): ##1.0e-9 may be too large |
---|
42 | for i in range(50): |
---|
43 | h = 1.0e-4 ##1.0e-4 may be too large. |
---|
44 | n = len(q) |
---|
45 | jac = zeros((n,n)) |
---|
46 | if 1.0+q[0]-x<0.0: |
---|
47 | print "Problem occurs i=",i |
---|
48 | print "PROBLEM OCCURS.......... 1.0+q[0]-x=",1.0+q[0]-x |
---|
49 | q[0] = x-1.0 + 0.0001 |
---|
50 | print "NOW problem is fixed as 1.0+q[0]-x=",1.0+q[0]-x |
---|
51 | f0 = f(q) |
---|
52 | for i in range(n): |
---|
53 | temp = q[i] |
---|
54 | q[i] = temp + h |
---|
55 | f1 = f(q) |
---|
56 | q[i] = temp |
---|
57 | jac[:,i] = (f1 - f0)/h |
---|
58 | if sqrt(dot(f0,f0)/len(q)) < tol: return q |
---|
59 | dq = gaussPivot(jac,-f0) |
---|
60 | q = q + dq |
---|
61 | if sqrt(dot(dq,dq)) < tol*max(max(abs(q)),1.0): return q |
---|
62 | print 'Too many iterations' |
---|
63 | ################################################################################## |
---|
64 | N = len(points) |
---|
65 | |
---|
66 | eps = a/h0 # Dimensionless amplitude |
---|
67 | T = Tp*sqrt(g*h0)/L # Dimensionless period |
---|
68 | tim = t*sqrt(g*h0)/L # Dimensionless time |
---|
69 | A = eps/j0(4.0*pi/T) # Dimensionless max horizontal displacement of shore |
---|
70 | |
---|
71 | W = zeros(N) # Dimensional stage |
---|
72 | P = zeros(N) # Dimensional momentum |
---|
73 | Z = zeros(N) # Dimensional bed |
---|
74 | H = zeros(N) # Dimensional height |
---|
75 | U = zeros(N) # Dimensional velocity |
---|
76 | |
---|
77 | q = zeros(2) |
---|
78 | pos_shore, vel_shore = shore(tim) # Dimensionless shore |
---|
79 | #q[0] = pos_shore |
---|
80 | #q[1] = vel_shore |
---|
81 | |
---|
82 | for m in range(N): |
---|
83 | i = N - m-1 |
---|
84 | X = points[i] # Dimensional |
---|
85 | if X >= pos_shore*L: # Dimensional |
---|
86 | W[i] = (h0/L)*X - h0 # Dimensional |
---|
87 | U[i] = 0.0 # Dimensional |
---|
88 | Z[i] = (h0/L)*X - h0 # Dimensional |
---|
89 | H[i] = 0.0 # Dimensional |
---|
90 | P[i] = 0.0 # Dimensional |
---|
91 | else: |
---|
92 | x = X/L # Dimensionless |
---|
93 | #q = fsolve(func,q) # Dimensionless (too sensitive and not good) |
---|
94 | q = newtonRaphson2(func,q) # Dimensionless (better than fsolve) |
---|
95 | W[i] = q[0]*h0 # Dimensional |
---|
96 | U[i] = q[1] # It needs dimensionalisation |
---|
97 | Z[i] = (h0/L)*X - h0# Dimensional |
---|
98 | H[i] = W[i] - Z[i] # Dimensional |
---|
99 | P[i] = H[i]*U[i] # It needs dimensionalisation |
---|
100 | U = U*sqrt(g*h0) #This is the dimensionalisation |
---|
101 | P = P*sqrt(g*h0) #This is the dimensionalisation |
---|
102 | return W, P, Z, H, U |
---|
103 | |
---|
104 | |
---|
105 | if __name__ == "__main__": |
---|
106 | points = linspace(0.0, 55000.0, 1000) |
---|
107 | W, P, Z, H, U = analytic_cg(points,t=300.0, h0=5e2, L=5e4, a=1.0, Tp=900.0) |
---|
108 | |
---|
109 | from pylab import clf,plot,title,xlabel,ylabel,legend,savefig,show,hold,subplot,ion |
---|
110 | hold(False) |
---|
111 | clf() |
---|
112 | plot1 = subplot(311) |
---|
113 | plot(points/1e+4,W, points/1e+4,Z) |
---|
114 | ylabel('Stage') |
---|
115 | |
---|
116 | plot2 = subplot(312) |
---|
117 | plot(points/1e+4,P,'b-') |
---|
118 | ylabel('Momentum') |
---|
119 | |
---|
120 | plot3 = subplot(313) |
---|
121 | plot(points/1e+4,U,'b-') |
---|
122 | xlabel('Position / 10,000') |
---|
123 | ylabel('Velocity') |
---|
124 | legend(('Analytical Solution','Numerical Solution'), |
---|
125 | 'upper center', shadow=False) |
---|
126 | |
---|
127 | show() |
---|