# source:anuga_work/development/shallow_water_1d/parabolic_cannal.py@4960

Last change on this file since 4960 was 4959, checked in by steve, 16 years ago

Copied John Jakeman's and Sudi Mungkasi's 1d shallow water code

File size: 5.0 KB
Line
1import os
2from math import sqrt, pi, sin, cos
3from shallow_water_1d import *
4from Numeric import allclose, array, zeros, ones, Float, take, sqrt
5from config import g, epsilon
6
7def newLinePlot(title='Simple Plot'):
8    import Gnuplot
9    g = Gnuplot.Gnuplot(persist=0)
10    g.title(title)
11    g('set data style linespoints')
12    g.xlabel('x')
13    g.ylabel('y')
14    return g
15
16def linePlot(g,x1,y1,x2,y2,x3,y3):
17    import Gnuplot
18    plot1 = Gnuplot.PlotItems.Data(x1.flat,y1.flat,with="lines 2")
19    plot2 = Gnuplot.PlotItems.Data(x2.flat,y2.flat,with="lines 3")
20    plot3 = Gnuplot.PlotItems.Data(x3.flat,y3.flat,with="linespoints 1")
21    g.plot(plot1,plot2,plot3)
22
23
24def analytic_cannal(C,t):
25    N = len(C)
26    u = zeros(N,Float)    ## water velocity
27    h = zeros(N,Float)    ## water depth
28    x = C
29    g = 9.81
30
31
32    ## Define Basin Bathymetry
33    z_b = zeros(N,Float) ## elevation of basin
34    z = zeros(N,Float)   ## elevation of water surface
35    z_infty = 10.0       ## max equilibrium water depth at lowest point.
36    L_x = 2500.0         ## width of channel
37
38    A0 = 0.5*L_x                  ## determines amplitudes of oscillations
39    omega = sqrt(2*g*z_infty)/L_x ## angular frequency of osccilation
40
41    #x1 = A0*cos(omega*t)-L_x # left shoreline
42    #x2 = A0*cos(omega*t)+L_x # right shoreline
43
44    for i in range(N):
45        z_b[i] = z_infty*(x[i]**2/L_x**2)
46        u[i] = -A0*omega*sin(omega*t)
47        z[i] = z_infty+2*A0*z_infty/L_x*cos(omega*t)*(x[i]/L_x-0.5*A0/(L_x)*cos(omega*t))
48
49    h = z-z_b
50    return u,h,z,z_b
51
52
53#plot2 = newLinePlot("Momentum")
54
55L_x = 2500.0     # Length of channel (m)
56N = 8         # Number of compuational cells
57cell_len = 4*L_x/N   # Origin = 0.0
58
59points = zeros(N+1,Float)
60for i in range(N+1):
61        points[i] = -2*L_x +i*cell_len
62
63domain = Domain(points)
64
65domain.order = 2 #make this unnecessary
66domain.default_order = 2
67domain.default_time_order = 2
68domain.cfl = 1.0
69domain.beta = 1.0
70#domain.limiter = "minmod_kurganov"
71#domain.limiter = "vanleer"
73#domain.limiter = "superbee"
74domain.limiter = "steve_minmod"
75
76def stage(x):
77
78    z_infty = 10.0       ## max equilibrium water depth at lowest point.
79    L_x = 2500.0         ## width of channel
80    A0 = 0.5*L_x                  ## determines amplitudes of oscillations
81    omega = sqrt(2*g*z_infty)/L_x ## angular frequency of osccilation
82    t=0.0
83    y = zeros(len(x),Float)
84    for i in range(len(x)):
85        #xy[i] = z_infty+2*A0*z_infty/L_x*cos(omega*t)*(x[i]/L_x-0.5*A0/(L_x)*cos(omega*t))
86        y[i] = 12.0
87    return y
88
89def elevation(x):
90    N = len(x)
91    z_infty = 10.0
92    z = zeros(N,Float)
93    L_x = 2500.0
94    A0 = 0.5*L_x
95    omega = sqrt(2*g*z_infty)/L_x
96    for i in range(N):
97        z[i] = z_infty*(x[i]**2/L_x**2)
98    return z
99
100def height(x):
101    z_infty = 10.0       ## max equilibrium water depth at lowest point.
102    L_x = 2500.0         ## width of channel
103    A0 = 0.5*L_x                  ## determines amplitudes of oscillations
104    omega = sqrt(2*g*z_infty)/L_x ## angular frequency of osccilation
105    t=0.0
106    y = zeros(len(x),Float)
107    for i in range(len(x)):
108        y[i] = max(z_infty+2*A0*z_infty/L_x*cos(omega*t)*(x[i]/L_x-0.5*A0/(L_x)*cos(omega*t))-z_infty*(x[i]**2/L_x**2),0.0)
109    return y
110
111
112domain.set_quantity('stage', stage)
113domain.set_quantity('elevation',elevation)
114#domain.set_quantity('height',height)
115
116domain.set_boundary({'exterior': Reflective_boundary(domain)})
117
118import time
119t0 = time.time()
120finaltime = 1122.0*0.75
121yieldstep = finaltime
122yieldstep = 10.0
123plot1 = newLinePlot("Stage")
124plot2 = newLinePlot("Xmomentum")
125C = domain.centroids
126X = domain.vertices
127StageQ = domain.quantities['stage'].vertex_values
128XmomQ = domain.quantities['xmomentum'].vertex_values
129import time
130t0 = time.time()
131for t in domain.evolve(yieldstep = yieldstep, finaltime = finaltime):
132    #pass
133    domain.write_time()
134    u,h,z,z_b = analytic_cannal(X.flat,t)
135    linePlot(plot1,X,z,X,z_b,X,StageQ)
136    linePlot(plot2,X,u*h,X,u*h,X,XmomQ)
137    HeightQ = domain.quantities['stage'].centroid_values-domain.quantities['elevation'].centroid_values
138    u,hc,z,z_b = analytic_cannal(C,t)
139    #for k in range(N):
140    #    if hc[k] < 0.0:
141    #        hc[k] = 0.0
142    error = 1.0/(N)*sum(abs(hc-HeightQ))
143    print 'Error measured at centroids', error
144    #raw_input()
145
146#from Gnuplot import plot,title,xlabel,ylabel,legend,savefig,show,hold,subplot
147from pylab import plot,title,xlabel,ylabel,legend,savefig,show,hold,subplot
148#import Gnuplot
149X = domain.vertices
150u,h,z,z_b = analytic_cannal(X.flat,domain.time)
151StageQ = domain.quantities['stage'].vertex_values
152XmomQ = domain.quantities['xmomentum'].vertex_values
153hold(False)
154plot1 = subplot(211)
155plot(X,h,X,StageQ)
156#plot1.set_ylim([4,11])
157#title('Free Surface Elevation of a Dry Dam-Break')
158xlabel('Position')
159ylabel('Stage')
160legend(('Analytical Solution', 'Numerical Solution'),