1. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
Shallow Water Modelling of a Dam Break over a Rubble Mound
Jawad Khan
School of Computing, Mathematics and Digital Technology
Manchester Metropolitan University
United Kingdom
February 25, 2015
Abstract
In this paper Lax-Friedrichs scheme for the shallow water equations and implement the numerical schemes
by computer programming. Next the numerical data is compared to the experimental data (gauges data
taken from Brufau et al., 2002), to find the accuracy of Lax-Friedrichs scheme for shallow water equation.
This paper also performs grid refinement study (GRS) using grid convergence index (GCI), the method
provides an objective asymptotic approach to quantification of uncertainty of grid convergence. The basic
idea is to approximately relate the results from any grid refinement test to the expected results from a grid
doubling using second order method.
Keywords. Lax-Friedrichs scheme (LF), Shallow Water Equations (SWE), Grid Refinement Study (GRS)
and Grid Convergence Index (GCI).
1 Introduction
The universe is governed by natural laws many of which
can be expressed as systems of PDEs. An important
example are the Navier-Stokes equations that, together
with the Continuity Equation form a system of 6
coupled PDEs which describe fluid flow in 3D. These
equations are difficult to solve even approximately. In
the following, a relatively simple system of PDEs has
been chosen to illustrate the FD approach.
The Shallow Water Equations (SWE) may be
expressed in 1D or 2D and provide a simplified model
of water flow which may be used to simulate many
situations including river flow and tsunami propagation.
For simplicity only one 1D is considered. This is still
useful and there are many 1D SWE software packages
used by hydraulic engineers to make flow calculations
for real life applications.
The 2D shallow water equations have attracted quite
a lot of attention in recent years. Alcrudo and Garcia-
Navarro (1993) developed a high-resolution Godunov-
type MUSCL fine volume sucheme. Glaister (1993) used
a flux splitting scheme and Nadiga (1995) designed an
adaptive discrete-velocity model of the shallow water
equations. Apparently there are many numerical meth-
ods for solving the shallow water equations, in the
paper Lax-Friedrichs scheme is applied and its work
remarkably well.
2 Numerical model
There are a variety of numerical techniques for
approximating equation (2.1) and (2.2), e.g. finite
element methods, finite volume methods, etc. In this
journal, finite difference approach is discussed and
applied (see Shiach, 2014a).
A novel scheme has been developed for data recon-
struction within a Godunov-type method for solving the
shallow-water equations with source terms. In contrast
to conventional data reconstruction methods based on
conservative variables, the water surface level is cho-
sen as the basis for data reconstruction. This provides
accurate values of the conservative variables at cell in-
terfaces so that the fluxes can be accurately calculated
with a Riemann solver. The main advantages are: (1)
a simple centred discretisation is used for the source
terms; (2) the scheme is no more complicated than the
conventional method for the homogeneous terms; (3)
small perturbations in the water surface elevation can
be accurately predicted; and (4) the method is generally
suitable for both steady and unsteady shallow-water
problems. The accuracy of the scheme has been verified
by recourse to both steady and unsteady flow problems.
Excellent agreement has been obtained between the
numerical predictions and analytical solutions. The
results indicate that the new scheme is accurate, simple,
efficient, and robust.
2.1 Shallow Water Equations (SWE)
The SWE (also called Saint-Venant equations) are one
of the simplest form of the equations of motion that
can be used to describe the horizontal structure of an
atmosphere and ocean that model the propagation of
disturbances in fluids. They are widely used to model
the free surface water flows such as periodic flows,
transient wave phenomena (see Brufau et al., 2002)
(tsunamis, flood waves, and dam- break waves) etc.
1
2. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
In fluid dynamics the flow of the fluid is known
as the Navier-Stocks equation. The shallow water
equations are good approximation to the fluid motion
equation when fluid density is homogeneous and depth
is small in comparison to characteristic horizontal
distance. So the most attention will be given to the
flow of shallow water equation (see Littlefield and
Hanselman, 2004). Shallow water equation is a system
of first order partial differential equation.
In one-dimension, the Shallow Water Equations are
a system two PDEs which are written as,
ht + (hu)x = 0 (2.1)
(hu)t + (hu2
+
1
2
gh2
)x = −g
∂zb
∂x
(2.2)
2.1.1 Assumptions
The dam fails instantaneously and completely, clearly
this is incorrect. In reality it would take minutes for
a dam wall to fail and parts of it would then block
the flow. It is assumed that the dam wall simply
disappears. This is unrealistic but does contribute to
the worst-case scenario that is being modelled.
The vertical velocity is negligible in shallow water,
this will not be strictly true. However, studies have
shown that SWE give quite good results for dam
breaks so their use is valid.
The width dimension may be neglected. Since the
reservoir and channel are both narrow this is probably
justified. In reality the flood water would spread out
laterally as it filled up the channel which would increase
the time for the water to reach the village and decrease
the height of the water. Therefore this model is a
worst-case scenario (which is safer because it is better
to underestimate the time for the flood to reach the
village than to overestimate it).
2.1.2 Estimating the wave speeds of the SWE
In the computation, the maximum allowable CFL num-
ber is fixed to 0.9 and calculate t adaptively in each
time step to insure the stability of the explicit method.
When determining the maximum allowable time step for
stability using any explicit method to solve the SWE,
the waves speeds must be taken into account. These
waves dependent upon the water depth h, as h changes
over space and time, as do the waves speeds. Same
value of t for all the points in the domain must be
used to update the solution by one time step, in order to
ensure the stability, the node with the largest absolute
wave speed is chosen. (the worst case scenario is taken
into account)
t ≤ C
x
maxi(|ui| +
√
ghi)
(2.3)
The solution at each time step needs updating, this
is because the values of h will change over time. (see
Shiach, 2014a, page 50 for more on CFL) and here is
the matlab script for maximum allowable time. (Shiach,
2014b). In the function u +
√
gh represent the fastest
or slowest speed possible for the SWE so therefore the
worst case scenario is taken so the biggest velocity is
divided by dx.
function dt = timestep(U,dx,cfl)
% This function calculates the maximum
% allowable timestep for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
dt = cfl*dx/max(abs(u) + sqrt(g*h));
2.2 Lax-Friedrichs Method
The Lax-Friedrichs method, named after Peter Lax and
Kurt O. Friedrichs, is a numerical method for the solu-
tion of hyperbolic partial differential equations based
on finite differences. The method can be described as
the FTCS (forward in time, centred in space) scheme
with an artificial viscosity term of 1
2 . Lax-Friedrichs
method is an alternative to Godunov’s scheme, where
one avoids solving a Riemann problem at each cell inter-
face, at the expense of adding artificial viscosity.The un
i
term in the forward differencing of the time derivative
in the FCTS scheme is replaced by an average of the
two adjacent nodes, i.e.
un+1
i −
un
i−1+un
i+1
2
t
+ v
un
i+1 − un
i1
2 x
= 0 (2.4)
which results in
un+1
i =
1
2
(un
i−1+un
i+1)−
v t
2 x
(un
i+1−un
i−1)+O( t, x)
(2.5)
This is a first-order in space and time finite difference
technique so the accuracy is not very good. Use of
Von Neumann stability analysis shows that the Lax-
Friedrichs method is stable for C 1. For a general
homogeneous conservation system.
∂U
∂t
+
∂F
∂x
= 0. (2.6)
The derivation of Lax-Friedrichs scheme can be
seen in (Barth, 2003) and the matlabnscript for Lax-
Friedrichs is in (appendix A.2).
2.2.1 Boundary Conditions
Lax-Friedrichs scheme needs left and right ghost nodes
so in general to put variables in arrays whose columns
of from i = 1 to i = N + 2. Left and Right ghost nodes
indices are i = 1 and i = N + 2 respectively. Compu-
tational nodes go from i = 2 to i = N + 1 in matlab.
but in Lax-Friedrichs scheme U(1, 1) which is the left
ghost node is equal to U(1, 3) which is the second node
in the computational nodes in matlab this is because
2
3. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
the 2nd
order central difference approximations of df
dx is
being used and the since the last node is U(1, end − 1)
then the right ghost node is U(1, end) which is equal
to U(1, end − 2). U(2, 1) represents velocity the rea-
son U(2,3) is negative because no water will escape on
the left side and the reason it is positive on the right
because water will need to escape on the right side.
2.2.2 Bed Source Terms
Bed source terms are approximated using the function
down below where dzdx in the function calculates the
gradient of the bed source which is dz
dx and g is grav-
itational pull which is 9.81 and U(1, :) represents all
the values in first row and the bed source terms are the
vector source terms.
function S = source(U,dzdx)
% This function calculates the bed source
% terms for the 1D SWE
g = 9.81;
S = zeros(size(U));
S(2,:) = -g*U(1,:).*dzdx;
2.3 Grid Refinement Study (GRS)
The convergent scheme is the one where the error be-
tween the numerical approximations to a PDE and the
exact solution of a PDE converge to zero as t, x
goes to 0. So choosing a smaller value of x will give a
better approximations (see Shiach, 2014a for more on
GRS).
2.3.1 Grid Convergence Index (GCI)
In most cases, it is not possible or very difficult to find
the exact solution for a PDE. But instead difference
between the solutions is calculated using different sized
grids and identify whether the solution is converging
at a rate expected for the order of the method. GCI
measures the convergence to an estimate of the exact
solution between two different sized grids. (GCI is
explained in great detail and how it is applied in Shiach,
2014a) and the matlab for GCI is in (appendix A.2).
3 Model validation
In this section the matlab program will be tested and
modified so it is working fine and it is ready for the
Denbydoo case study.
3.1 Still Water Test
The Program had run for 100s with number of nodes
1000 and the water depth of 8m through out the whole
domain of 1000m as required and it can be seen from
Fig. 1 that the water remained stationary after 100s
with little bit of perturbation about (130,8) and since
the water stays through out the whole domain it show
that the program is working fine.
Figure 1: Water depth of 8m though out the domain.
3.2 Validation Test Problem
Dam break flood wave over a triangle obstacle the
channel geometry is shown in Fig. 2. A triangular
obstacle (6m long and 0.4mm high) is situated 10m
downstream of the dam.
Reservoir
dam
15.5m 10m 6.0m 6.5m
0.4m
0.75m
Figure 2: Geometry of the Laboratory model from
(Brufau et al., 2002)
Four wave gauges measuring water depth above a
datum h + z were situated at 4.0m, 10.0m, 13.0m and
20.0m downstream of the dam location respectively.
After modifying the Matlab program that was
given to us for Shallow water equations by changing
the values of the variables used to define the solution
parameters and the bed surface to set up the code
to model the laboratory experiment for validation
purposes and run the simulation to a time t = 40s. All
the data is collected for the water surface elevation
h + z and time t for each iteration and was exported to
a matlab file for plots later in the journal.
3.3 Grid Convergence Index
The program was first run with N3 = 250, N2 = 500
and N1 = 1000 nodes for Grid Refinement Study such
that r = 2 and h3 = 0.004, h2 = 0.002 and h1 = 0.001
and the water surface elevation data for the numerical
depth gauges was collected at four wave gauges and
it is in Table. 1 down below in column f1, f2 and f3
with number of nodes 1000, 500 and 250 respectively.
Using GCI to determine the smallest grid that gives a
grid independent solution, the GCI was calculated for
a four wave gauges from the domain located at (19.5, 0)
, (25.5, 0), (28.5, 0.4) and (35.5, 0) and these are shown
in Table 1. Since for the point (25.5, 0) and (35.5, 0),
GCI32 = rp
GCI21 which indicates that the h2 grid has
3
4. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
not reached asymptotic convergence (see Shiach, 2014a,
page: 69).
Table 1: Calculation of the GCI for the Shallow water
equations using grid sizes N3 = 250, N2 = 500 and
N1 = 1000.
(x, h + z) fexact f1 f2 f3 p GCI21 GCI32 rpGCI21
(19.5,0) 0.2158 0.2235 0.2292 0.2391 0.80 4.27 7.26 7.45
(25.5,0) -0.2348 0.1375 0.1523 0.1678 0.06 338.44 317.69 351.91
(28.5,0.4) 0.5448 0.5474 0.5515 0.5405 1.40 0.58 1.52 1.53
(35.5,0) 0.0461 0.0560 0.0600 0.0656 0.49 22.08 28.92 30.97
The finite-difference grid was refined further so that
the fine, medium and coarse grids use N3 = 500, N2 =
1000 and N1 = 2000. The GCI for the same grid points
are shown in Table 2. Here, for all the points the
GCI32 ≈ rp
GCI21 which indicates that the h2 grid has
reached asymptotic convergence.
Table 2: Calculation of the GCI for the Shallow water
equations using grid sizes N3 = 500, N2 = 1000 and
N1 = 2000.
(x, h + z) fexact f1 f2 f3 p GCI21 GCI32 rpGCI21
(19.5,0) 0.2009 0.2189 0.2235 0.2292 0.32 10.28 12.61 12.87
(25.5,0) 0.1279 0.1317 0.1375 0.1523 1.35 3.59 8.73 9.12
(28.5,0.4) 0.5336 0.5442 0.5474 0.5515 0.38 2.42 3.14 3.16
(35.5,0) 0.0486 0.0534 0.0560 0.0600 0.62 11.28 16.54 17.34
For four gauges in Fig. 3 showing the water surface
elevation h + z against the time t using the data from
the numerical model and the laboratory experiments
(lab. data Brufau et al., 2002). As it can be seen in
the Fig. 3 that the numerical graphs are similar to the
experiment ones.
Figure 3: Dam break over an obstacle: Numerical data
and experimental lab data plots of the measured time
series for the depth gauges.
There is a tiny bore wave when x is about 24m and
there is no reflective wave, that is because the water
has not reached the rubble mound yet.
At time t = 0 the partition is instantaneously re-
moved and the upstream reservoir causes a bore wave
to form the travels downstream as shown in Fig. 4. The
loss of mass due to this bore wave causes an upstream
travelling rarefaction wave, or depression wave and also
a tiny bore wave.
Figure 4: 1D Shallow water flow after 2s calculated by
Lax-Friedrichs method with N = 2000.
There is a big bore wave about x = 20 and the
bore wave is actually a reflective wave, it is because of
the rubble mound and also there is a rarefaction wave
or depression wave about x = 25. The bore wave is
moving to the left it is because it is reflected by the
rubble mound.
Figure 5: Shallow water flow at time 14s using Lax-
Friedrichs with nodes = 2000.
At time 37s there is one bore wave at x = 19 to
the left of rubble mound and it is moving to the right,
towards the rubble mound this is because it is reflected
by the left side of the dam.
Figure 6: Shallow water flow at time 37s using Lax-
Friedrichs with nodes = 2000.
4
5. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
4 Case study: Denbydoo Flood
Defence
Denbydoo is situated 50m down the dam as it is shown
in Fig. 7, Denbydoo is protected against loss of water
from the dam by a rubble mound. The water company
is proposing to increase the headwater level from height
of 8m to height of 40m. In this case study the program
was modelled to wether it is a good idea to change the
height of the water level to 40m from 8m, and to find in
the case of dam break what will be the maximum height
of the flood and how long will it take for the water wave
to reach the village. The program is structured to solve
the problem in 1D, i.e. worst case scenario taken into
account.
x (m)
dam
0 200 600 800 850 1000950
6m
8m
Figure 7: Diagram of the rubble mound protecting
Denbydoo (village) in the event of a failure of the Dam.
The program was first run with N3 = 1000, N2 =
2000 and N1 = 4000 nodes for Grid Refinement Study
such that r = 2 and h3 = 0.001, h2 = 0.0005 and
h1 = 0.00025 and the water surface elevation data for
the numerical depth gauges was collected at three wave
gauges and it is in Table. 3 down below in column
f1, f2 and f3 with number of nodes 4000, 2000 and
1000 respectively. Using GCI to determine the smallest
grid that gives a grid independent solution, the GCI
was calculated at these wave gauges from the domain
located at (500, 0) , (825, 6) and (950, 0) and these are
shown in Table 3. Since for the point (500, 0) and
(950, 0), GCI32 = rp
GCI21 which indicates that the h2
grid has not yet reached asymptotic convergence (see
Shiach, 2014a, page: 69).
Table 3: Calculation of the GCI for the Shallow water
equations using grid sizes N3 = 1000, N2 = 2000 and
N1 = 4000
(x, h + z) fexact f1 f2 f3 p GCI21 GCI32 rpGCI21
(500,0) 0.4681 0.5674 0.6180 0.6943 0.59 21.86 30.31 33.01
(825,6) 6.1203 6.1650 6.1812 6.2033 0.45 0.91 1.23 1.23
(950,0) 0.0677 0.0833 0.1112 0.1891 1.48 23.44 48.95 65.36
The finite-difference grid was refined further so that
the fine, medium and coarse grids use N3 = 2000,
N2 = 4000 and N1 = 8000. The GCI for the same
grid points are shown in Table 4 . Here all the points
satisfy GCI32 ≈ rp
GCI21 which suggests that the dis-
cretisation using N = 4000 nodes is sufficient for this
case.
Table 4: Calculation of the GCI for the Shallow water
equations using grid sizes N3 = 2000, N2 = 4000 and
N1 = 8000.
(x, h + z) fexact f1 f2 f3 p GCI21 GCI32 rpGCI21
(500,0) 0.4715 0.5343 0.5674 0.6180 0.61 14.68 21.12 22.43
(825,6) 6.1251 6.1535 6.1650 6.1812 0.49 0.58 0.81 0.81
(950,0) 0.0783 0.0791 0.0833 0.1112 2.73 1.18 7.44 7.84
4.1 Toe of the Rubble Mound
The program had run for both 8m and 40m of water
upstream depths as shown in Fig. 8. If the water
company decide to increase the water upstream depth
then if the dam breaks then about 600m, at the toe of
the rubble mound the maximum water wave height will
be approximately 1.8m for 8m upstream height and
that will be 70s after the dam break and above 8.3m
for a 40m of upstream height and that will be 32s after
the dam break. The water wave for upstream height
of 8m will take twice as much or more time to get to
600m compare to 40m of upstream height as shown in
Fig. 8.
Figure 8: Water wave maximum height and the time it
reached the toe of the rubble mound.
4.2 Mid-Point on the top of the Rubble
Mound
The water upstream height (WUH) of 40m takes about
18s to get to the top of the rubble mound while the
WUH of 8m takes twice as much time, about 43s to
get to the same point (top of the rubble mound). If
the program was run for 40 seconds, the water wave for
the WUH of 8m will have not reached to the top of the
rubble mound as shown in Fig. 9. The Maximum height
for both depths upstream of 8m and 40m is about 7.3m
and 12.8m respectively and for the WUH of 40m the
water wave will get to the Denbydoo in very less time
compared to 8m and flood height will be very high as
well.
5
6. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
Figure 9: Flood maximum height and the time, it
reached the top of the rubble mound in one Dimension.
4.3 Between the Rubble Mound and
the town of Denbydoo
As shown in Fig. 10, the water wave reaches the x = 975
in just about 55s for 8m of WUH. if the water company
increases the water depth upstream height to 40m then
it takes only 21.8s for the water wave to get to point
x = 975 which is in the middle of the Denbydoo and
the rubble mound. 8m of WUH gives the Denbydoo
villagers twice more time if the dam breaks and in this
time they can take their children and valuables to safety,
probably upstairs or to the roof of their houses where
they will be safe for the time being and if the water
depth upstream height is 40m then upstairs and the roof
of their houses will not be safe from the flood because
the maximum height of the water wave will be above
5m and 0.5m for the depths of 40m and 8m respectively.
In Fig. 10 the water wave maximum height is about
5m and it decreases linearly which indicates that all the
flood water went to the Denbydoo village and since it
is linearly decreasing the water will have more pressure
and speed and high the height of the water the more
damage it will do to Denbydoo village.
Figure 10: Flood Maximum height and the time it took
to reach the point x = 975.
Answer 1: Time of arrival of the flood wave at
the front edge is 26.5 seconds for 8m of water depth
upstream height and time of arrival of the flood wave
at the front edge is 11.50 seconds for 40m of water
depth upstream height.
Answer 2: If the program is run for 40s then water
wave will not reach the top of the rubble mound
because the time of arrival of the flood wave at the
top of the rubble mound is 42.6 seconds for 8m of
water depth upstream height and the time of arrival
of the flood wave at the top of the rubble mound is
17.9 seconds for 40m of water depth upstream height
so program had run for 100 seconds.
Answer 3: Time of arrival of the flood wave at
Denbydoo will be 55.3 seconds for 8m of water depth
upstream height if the program is run for more than
56.6 seconds otherwise the water wave will not reach
the Denbydoo. The maximum height of the wave for
8m of depth upstream will be 0.47m and time of arrival
of the flood wave at Denbydoo will be 22.8 seconds for
40m of water depth upstream height. The maximum
height of the wave for 40m of depth upstream will be
4.97m.
Answer 4: To stop your cat from sleeping on
rubble mound, place something near the rubble that
makes high-pitched noises because cats do not like
high-pitched sounds or put small boat on the top of the
rubble mound and train them, in case of dam failure
to get on the boat.
Answer 5: Increase in volume of water in not safe if
the dam breaks then it will sink and destroy the whole
Denbydoo village in very less time. The water company
could change the size and height of the rubble mound,
there isn’t much distance between the rubble mound
and the Denbydoo, its only 50m but they can move the
rubble mound to the left, towards the dam and increase
the height of it as well then increasing the water depth
upstream which should be fairly safe because in the
case of dam failure the flood height in the Denbydoo
will not very high, because the rubble mound will stop
most of the water and closer the rubble mound to the
dam is, the less movement there will be in the water
and less pressure too.
5 Conclusions
Validation test show fair agreement to lab experiment
data (Brufau et al., 2002) as shown in Fig. 3 which
shows that the Denbydoo case study should give a
very good approximation. If the dam fails Denbydoo
villagers have about 56.3 seconds if the water depth
upstream height is 8m and about 24.7 seconds if the
WUH is 40m until the flood arrives. The maximum
height of the flood at the Denbydoo village is 0.47m and
4.97m for the WUH of 8m and 40m respectively and
the maximum flood height arrives in about 42 seconds
6
7. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
for 40m and in about 110 seconds for 8m after the
dam break. Increasing the WUH level is not very safe
because in the case of dam break, the flood will do a
lot more damage to the village.
References
Alcrudo, F and P. Garcia-Navarro (1993). A high-
resolution godunov-type scheme in finite volumes
for the 2D shallow water equations. 16:489-505. Int.
J. for Numerical Methods in Fluids.
Barth, T. (2003). High order methods for computa-
tional physics. Springer-Verlag Berlin and Heidelbrg
GmbH.
Brufau, P., M.E. Vazquez-Cendon, and P. Garcia-
Navarro (2002). “A numerical model for flooding
and drying of irregular domains”. In: Int. J. Num.
Meth. Fluids. 39, pp. 247–275.
Glaister, P. (1993). Flux difference splitting for open-
channel flows. 16:629-654. Int. J. for Numerical
Methods in Fluids.
Littlefield, B. and D. Hanselman (2004). Mastering Mat-
lab 7. Upper Saddle River, N.J. : Pearson Prentice
Hall, c2005.
Nadiga, B.T. (1995). An adaptive discrete-velocity
model for the shallow water equations. 121:271-280.
j. Comp. Phys.
Shiach, J.B. (2014a). Finite-Difference Methods for Solv-
ing Partial Differential Equations. Lecture Notes.
Manchester Metropolitan University.
— (2014b). swe.m. MATLAB program. Manchester
Metropolitan University.
7
8. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
Appendices
A Matlab
A.1 STILL WATER TEST
function swe
% This program solves the SWE using the Lax-Friedrichs scheme
% clear workspaces
clear
clc
clf
% define variables
xmin = 0; % lower bound of x
xmax = 1000; % upper bound of x
ymin = 0; % minimum value of y in the plot axis
ymax = 10; % maximum value of y in the plot axis
N = 1000; % number of nodes-1
dam = 1000; % x co-ordinate of dam location
uph = 8; % water depth upstream of the dam
downh = 0; % water depth downstream of the dam
tmax = 100; % time at which the time marching loop will stop
cfl = 0.9; % value used to ensure stability by the cfl condition
% define bed surface co-ordinates
zcoord = [600 0 ; 800 6 ; 850 6 ; 950 0];
% calculate initial conditions
[U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord);
% calculate gradient of bed surface
dx = x(2) - x(1);
dzdx = f_x(z,dx);
% output run data to the command window
fprintf(’----------------------------------------n’)
fprintf(’ 1D SWE solvern’)
fprintf(’----------------------------------------n’)
fprintf(’ Solution parameters:nn’)
fprintf(’ domain length = %6.1fmn’,xmax)
fprintf(’ number of nodes, N = %4in’,N)
fprintf(’ grid spacing, dx = %6.1fmn’,dx)
fprintf(’ dam location, x = %6.1fmn’,dam)
fprintf(’ upstream depth, h = %6.1fmn’,uph)
fprintf(’ downsteam depth, h = %6.1fmn’,downh)
fprintf(’ max value of t = %6.1fsn’,tmax)
fprintf(’ Courant number, CFL = %6.1fnn’,cfl)
fprintf(’ Running program, please wait ...nn’)
% time marching loop
t = 0;
iterations = 0;
tic;
while t < tmax
% calculate dt and ensure that t does not exceed tmax
dt = timestep(U,dx,cfl);
dt = min(dt,tmax - t);
8
9. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
% calculate boundary conditions, flux vector and source terms
U = bc(U);
F = flux(U);
S = source(U,dzdx);
% Lax-Friedrichs scheme
U(:,2:end-1) = 0.5*(U(:,3:end) + U(:,1:end-2)) - 0.5*dt/dx ...
*(F(:,3:end) - F(:,1:end-2)) + dt*S(:,2:end-1);
% zero the velocities where the bed is dry
U = drybed(U);
% update t and iterations
t = t + dt;
iterations = iterations + 1;
% plot solution every 10 iterations (comment out if code is taking
% a long time to run)
if mod(iterations,10) == 0
plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
end
end
% plot final solution
plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
% record cpu time
cpu = toc;
% output computation information
fprintf(’ Computation information:nn’)
fprintf(’ number of iterations = %6in’,iterations)
fprintf(’ CPU time = %6.3fsn’,cpu)
fprintf(’----------------------------------------nn’)
% =========================================================================
function [U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord)
% This function calculates the initial values of U, x, z and dx given the
% number of nodes - 1 (N), the lower and upper bounds of the domain (xmin,
% xmax), the location of the dam (dam), the water depths upstream and
% downstream of the dam (uph, downh) and the co-ordinates defining the bed
% surface (zcoord).
% define spatial array x (including ghost nodes)
dx = (xmax - xmin)/N;
x = xmin - dx : dx : xmax + dx;
% define bed elevation z and calculate derivative of z
z = bed(x,zcoord);
dzdx = f_x(z,dx);
% define conserved variable array U
for i = 1 : length(x)
if x(i) <= dam
% upstream depth
U(1,i) = uph - z(i);
else
% downstream depth
9
10. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
U(1,i) = downh - z(i);
end
U(2,i) = 0;
% prevent negative water depth
if U(1,i) < 0
U(1,i) = 0;
end
end
% =========================================================================
function z = bed(x,zcoord)
% This function calculates the bed surface elevation z depending on the
% node coordinates x and bed coordinates zcoord
z = zeros(size(x));
for i = 1 : size(zcoord,1) - 1
if zcoord(i+1,2) == zcoord(i,2)
m = 0;
else
m = (zcoord(i+1,2) - zcoord(i,2))/(zcoord(i+1,1) - zcoord(i,1));
end
j = find(x > zcoord(i,1) & x <= zcoord(i+1,1));
z(j) = zcoord(i,2) + m*(x(j) - zcoord(i,1));
end
% =========================================================================
function [h,u] = getvariables(U)
% This function gets h and u from U
h = U(1,:);
u = zeros(1,length(h));
i = find(h > 1d-3);
u(i) = U(2,i)./U(1,i);
% =========================================================================
function U = drybed(U)
% This function sets the velocities of nodes where the bed is dry to zero.
[h,u] = getvariables(U);
U(1,:) = h;
U(2,:) = h.*u;
% =========================================================================
function dt = timestep(U,dx,cfl)
% This function calculates the maximum allowable timestep for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
dt = cfl*dx/max(abs(u) + sqrt(g*h));
% =========================================================================
function U = bc(U)
% This function calculates the boundary conditions for the 1D SWE
U(1,1)=U(1,3);
U(2,1)=-U(2,3);
U(1,end)=U(1,end-2);
U(2,end)=U(2,end-2);
% =========================================================================
10
11. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
function F = flux(U)
% This function calculates the flux vector for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
F(1,:) = h.*u;
F(2,:) = h.*u.*u + 0.5*g*h.*h;
% =========================================================================
function S = source(U,dzdx)
% This function calculates the bed source terms for the 1D SWE
g = 9.81;
S = zeros(size(U));
S(2,:) = -g*U(1,:).*dzdx;
% =========================================================================
function y = f_x(f,dx)
% This function calculates the 2nd order central difference approximation
% of df/dx.
y = zeros(size(f));
y(2:end-1) = (f(3:end) - f(1:end-2))/(2*dx);
% =========================================================================
function plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
% This function plots the solution
figure(1)
area(x,U(1,:)+z,’facecolor’,[0 1 1],’edgecolor’,’none’)
hold on
area(x,z,’facecolor’,[0.5 0.5 0.5],’edgecolor’,’none’);
hold off
axis([xmin xmax ymin ymax])
xlabel(’x (m)’,’fontsize’,16)
ylabel(’h+z (m)’,’fontsize’,16)
title(sprintf(’time = %6.2f’,t),’fontsize’,16)
shg
11
12. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
A.2 VALIDATION TEST PROBLEM
% Matlab program for VALIDATION TEST PROBLEM
function swe
clear
clc
clf
% This program solves the SWE using the Lax-Friedrichs scheme
% define variables
xmin = 0; % lower bound of x
xmax = 38; % upper bound of x
ymin = 0; % minimum value of y in the plot axis
ymax = 1; % maximum value of y in the plot axis
N = 250; % number of nodes-1
dam = 15.5; % x co-ordinate of dam location
uph = 0.75; % water depth upstream of the dam
downh = 0; % water depth downstream of the dam
tmax = 40; % time at which the time marching loop will stop
cfl = 0.9; % value used to ensure stability by the cfl condition
% define bed surface co-ordinates
zcoord = [25.5 0 ; 28.5 0.4 ; 31.5 0];
% loop for number of Nodes (N = N*2)
for i = 1 : 3
% calculate initial conditions
[U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord);
% calculate gradient of bed surface
dx = x(2) - x(1);
dzdx = f_x(z,dx);
% % output run data to the command window
% fprintf(’----------------------------------------n’)
% fprintf(’ 1D SWE solvern’)
% fprintf(’----------------------------------------n’)
% fprintf(’ Solution parameters:nn’)
% fprintf(’ domain length = %6.1fmn’,xmax)
fprintf(’ number of nodes, N = %4in’,N)
% fprintf(’ grid spacing, dx = %6.1fmn’,dx)
% fprintf(’ dam location, x = %6.1fmn’,dam)
% fprintf(’ upstream depth, h = %6.1fmn’,uph)
% fprintf(’ downsteam depth, h = %6.1fmn’,downh)
% fprintf(’ max value of t = %6.1fsn’,tmax)
% fprintf(’ Courant number, CFL = %6.1fnn’,cfl)
% fprintf(’ Running program, please wait ...nn’)
% time marching loop
t = 0;
iterations = 0;
tic;
while t < tmax
% calculate dt and ensure that t does not exceed tmax
dt = timestep(U,dx,cfl);
dt = min(dt,tmax - t);
% calculate boundary conditions, flux vector and source terms
12
13. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
U = bc(U);
F = flux(U);
S = source(U,dzdx);
% Lax-Friedrichs scheme
U(:,2:end-1) = 0.5*(U(:,3:end) + U(:,1:end-2)) - 0.5*dt/dx ...
*(F(:,3:end) - F(:,1:end-2)) + dt*S(:,2:end-1);
% zero the velocities where the bed is dry
U = drybed(U);
% update t and iterations
t = t + dt;
iterations = iterations + 1;
% plot solution every 10 iterations (comment out if code is taking
% a long time to run)
if mod(iterations,10) == 0
plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
end
% calculate spatial array
dx_sa = (xmax - xmin)/(N);
% point one at (19.5,0)
y1 = (dam + 4)/dx_sa + 2;
index1 = round(y1);
numgauge1(iterations) = U(1,index1) + z(index1);
% point two at (25.5,0)
y2 = (dam + 10)/dx_sa + 2;
index2 = round(y2);
numgauge2(iterations) = U(1,index2) + z(index2);
% point three at (28.5,0.4)
y3 = (dam + 13)/dx_sa + 2;
index3 = round(y3);
numgauge3(iterations) = U(1,index3) + z(index3);
% point four at (35.5,0)
y4 = (dam + 20)/dx_sa + 2;
index4 = round(y4);
numgauge4(iterations) = U(1,index4) + z(index4);
time(iterations) = t;
end
% output each gauge value at certain points in two columns
% time and numerical gauges
gauges1 = [time’ numgauge1’];
f(1,i) = gauges1(index1,2);
gauges2 = [time’ numgauge2’];
f(2,i) = gauges2(index2,2);
gauges3 = [time’ numgauge3’];
f(3,i) = gauges3(index3,2);
gauges4 = [time’ numgauge4’];
f(4,i) = gauges4(index4,2);
% update number of nodes
N = N*2;
13
14. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
end
% GCI see( Shiach, 2014) page: 69
% note that "f(i,3) = f1(fine)" and "f(i,1) = f3(coarse)"
fprintf(’n’)
fprintf(’ fexact f1 f2 f3 p GCI21 GCI32 rpGCI21n’)
r = 2; % r = h2/h1, e.g. 1/0.5 = 2.
% since we need four sets of f1, f2 and f3 values with different nodes this is the
% loop for that.
for i = 1:4
p = (abs(log(abs((f(i,1) - f(i,2))/(f(i,2) - f(i,3))))))/(log(r));
f_exact = f(i,3) + (f(i,3) - f(i,2))/(r^p - 1);
E_21 = 100*((f(i,2) - f(i,3))/(f(i,3)));
GCI_21 = (1.25*(abs(E_21)))/(r^p - 1);
E_32 = 100*((f(i,1) - f(i,2))/(f(i,2)));
GCI_32 = (1.25*(abs(E_32)))/(r^p - 1);
rpGCI_21 = r^p*GCI_21;
fprintf(’%8.4f %8.4f %8.4f %8.4f %8.2f %8.2f %8.2f %8.2f n’,f_exact,f(i,3),f(i,2),f(i,1),p,GCI_21,GCI_
end
fprintf(’n’)
% plot the final solutions for numerical gauges and experimental gauges
% data using the subplot command in matlab so it will plot all the
% gauges on one figure but four subplots.
figure(1)
plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
figure(2)
hold on
% load experimental lab data
load gauges;
subplot(2,2,1)
plot(time,numgauge1,’b--’,gauge1(:,1),gauge1(:,2),’ro’)
title(’x = 4.00m’)
xlabel(’time (s)’)
ylabel(’h+z (m)’)
subplot(2,2,2)
plot(time,numgauge2,’b--’,gauge2(:,1),gauge2(:,2),’ro’)
title(’x = 10.00m’)
xlabel(’time (s)’)
ylabel(’h+z (m)’)
subplot(2,2,3)
plot(time,numgauge3,’b--’,gauge3(:,1),gauge3(:,2),’ro’)
title(’x = 13.00m’)
xlabel(’time (s)’)
ylabel(’h+z (m)’)
subplot(2,2,4)
plot(time,numgauge4,’b--’,gauge4(:,1),gauge4(:,2),’ro’)
title(’x = 20.00m’)
14
15. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
xlabel(’time (s)’)
ylabel(’h+z (m)’)
hold off
% record cpu time
cpu = toc;
% output computation information
fprintf(’ Computation information:nn’)
fprintf(’ number of iterations = %6in’,iterations)
fprintf(’ CPU time = %6.3fsn’,cpu)
fprintf(’----------------------------------------nn’)
% =======================================================================
function [U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord)
% This function calculates the initial values of U, x, z and dx given the
% number of nodes - 1 (N), the lower and upper bounds of the domain (xmin,
% xmax), the location of the dam (dam), the water depths upstream and
% downstream of the dam (uph, downh) and the co-ordinates defining the bed
% surface (zcoord).
% define spatial array x (including ghost nodes)
dx = (xmax - xmin)/N;
x = xmin - dx : dx : xmax + dx;
% define bed elevation z and calculate derivative of z
z = bed(x,zcoord);
dzdx = f_x(z,dx);
% define conserved variable array U
for i = 1 : length(x)
if x(i) <= dam
% upstream depth
U(1,i) = uph - z(i);
else
% downstream depth
U(1,i) = downh - z(i);
end
U(2,i) = 0;
% prevent negative water depth
if U(1,i) < 0
U(1,i) = 0;
end
end
% =======================================================================
function z = bed(x,zcoord)
% This function calculates the bed surface elevation z depending on the
% node coordinates x and bed coordinates zcoord
z = zeros(size(x));
for i = 1 : size(zcoord,1) - 1
if zcoord(i+1,2) == zcoord(i,2)
m = 0;
else
m = (zcoord(i+1,2) - zcoord(i,2))/(zcoord(i+1,1) - zcoord(i,1));
end
15
16. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
j = find(x > zcoord(i,1) & x <= zcoord(i+1,1));
z(j) = zcoord(i,2) + m*(x(j) - zcoord(i,1));
end
% =======================================================================
function [h,u] = getvariables(U)
% This function gets h and u from U
h = U(1,:);
u = zeros(1,length(h));
i = find(h > 1d-3);
u(i) = U(2,i)./U(1,i);
% =========================================================================
function U = drybed(U)
% This function sets the velocities of nodes where the bed is dry to zero.
[h,u] = getvariables(U);
U(1,:) = h;
U(2,:) = h.*u;
% =========================================================================
function dt = timestep(U,dx,cfl)
% This function calculates the maximum allowable timestep for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
dt = cfl*dx/max(abs(u) + sqrt(g*h));
% =========================================================================
function U = bc(U)
% This function calculates the boundary conditions for the 1D SWE
U(1,1)=U(1,3);
U(2,1)=-U(2,3);
U(1,end)=U(1,end-2);
U(2,end)=U(2,end-2);
% =========================================================================
function F = flux(U)
% This function calculates the flux vector for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
F(1,:) = h.*u;
F(2,:) = h.*u.*u + 0.5*g*h.*h;
% =========================================================================
function S = source(U,dzdx)
% This function calculates the bed source terms for the 1D SWE
g = 9.81;
S = zeros(size(U));
S(2,:) = -g*U(1,:).*dzdx;
% =========================================================================
function y = f_x(f,dx)
% This function calculates the 2nd order central difference approximation
% of df/dx.
y = zeros(size(f));
16
17. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
y(2:end-1) = (f(3:end) - f(1:end-2))/(2*dx);
% =========================================================================
function plotsolution(U,x,z,t,xmin,xmax,ymin,ymax)
% This function plots the solution
figure(1)
area(x,U(1,:)+z,’facecolor’,[0 1 1],’edgecolor’,’none’)
hold on
area(x,z,’facecolor’,[0.5 0.5 0.5],’edgecolor’,’none’);
hold off
axis([xmin xmax ymin ymax])
xlabel(’x (m)’,’fontsize’,16)
ylabel(’h+z (m)’,’fontsize’,16)
title(sprintf(’time = %6.2f’,t),’fontsize’,16)
shg
17
18. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
A.3 DENBYDOO FLOOD DEFENCE CASE STUDY USING GCI METHOD
function swe
% This program solves the SWE using the Lax-Friedrichs scheme
clear
clc
% define variables
xmin = 0; % lower bound of x
xmax = 1000; % upper bound of x
ymin = 0; % minimum value of y in the plot axis
ymax = 10; % maximum value of y in the plot axis
N = 1000; % number of nodes-1
dam = 200; % x co-ordinate of dam location
uph = 8; % water depth upstream of the dam
downh = 0; % water depth downstream of the dam
tmax = 80; % time at which the time marching loop will stop
cfl = 0.9; % value used to ensure stability by the cfl condition
% loop for number of Nodes (N = N*2)
for i = 1 : 3
% define bed surface co-ordinates
zcoord = [600 0 ; 800 6 ; 850 6 ; 950 0];
% calculate initial conditions
[U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord);
% calculate gradient of bed surface
dx = x(2) - x(1);
dzdx = f_x(z,dx);
% % output run data to the command window
% fprintf(’----------------------------------------n’)
% fprintf(’ 1D SWE solvern’)
% fprintf(’----------------------------------------n’)
% fprintf(’ Solution parameters:nn’)
% fprintf(’ domain length = %6.1fmn’,xmax)
fprintf(’ number of nodes, N = %4in’,N)
% fprintf(’ grid spacing, dx = %6.1fmn’,dx)
% fprintf(’ dam location, x = %6.1fmn’,dam)
% fprintf(’ upstream depth, h = %6.1fmn’,uph)
% fprintf(’ downsteam depth, h = %6.1fmn’,downh)
% fprintf(’ max value of t = %6.1fsn’,tmax)
% fprintf(’ Courant number, CFL = %6.1fnn’,cfl)
% fprintf(’ Running program, please wait ...nn’)
% time marching loop
t = 0;
iterations = 0;
tic;
while t < tmax
% calculate dt and ensure that t does not exceed tmax
dt = timestep(U,dx,cfl);
dt = min(dt,tmax - t);
% calculate boundary conditions, flux vector and source terms
U = bc(U);
F = flux(U);
S = source(U,dzdx);
18
19. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
% Lax-Friedrichs scheme
U(:,2:end-1) = 0.5*(U(:,3:end) + U(:,1:end-2)) - 0.5*dt/dx ...
*(F(:,3:end) - F(:,1:end-2)) + dt*S(:,2:end-1);
% zero the velocities where the bed is dry
U = drybed(U);
% update t and iterations
t = t + dt;
iterations = iterations + 1;
% plot solution every 10 iterations (comment out if code is taking
% a long time to run)
if mod(iterations,10) == 0
plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
end
% point one at (500,0)
y1 = (500)/dx + 2;
index1 = round(y1);
numgauge1(iterations) = U(1,index1) + z(index1);
x(index1);
% point two at (825,6)
y2 = (825)/dx + 2;
index2 = round(y2);
numgauge2(iterations) = U(1,index2) + z(index2);
x(index2);
% point three at (950,0)
y3 = (950)/dx + 2;
index3 = round(y3);
numgauge3(iterations) = U(1,index3) + z(index3);
x(index3);
time(iterations) = t; % time for each iteration
end
% output each gauge value at certain points in two columns
% time and numerical gauges
gauges1 = [time’ numgauge1’];
f(1,i) = gauges1(index1,2);
gauges2 = [time’ numgauge2’];
f(2,i) = gauges2(index2,2);
gauges3 = [time’ numgauge3’];
f(3,i) = gauges3(index3,2);
% update number of nodes
N = N*2;
end
% GCI see( Shiach, 2014) page: 69
% note that "f(i,3) = f1(fine)" and "f(i,1) = f3(coarse)"
fprintf(’n’)
fprintf(’ fexact & f1 & f2 & f3 7 p & GCI21 & GCI32 & rpGCI21n’)
r = 2; % r = h2/h1, e.g. 1/0.5 = 2.
% since we need three sets of f1,f2 and f3 values with different nodes this is the
19
20. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
% loop for that.
for i = 1:3
p = (abs(log(abs((f(i,1) - f(i,2))/(f(i,2) - f(i,3))))))/(log(r));
f_exact = f(i,3) + (f(i,3) - f(i,2))/(r^p - 1);
E_21 = 100*((f(i,2) - f(i,3))/(f(i,3)));
GCI_21 = (1.25*(abs(E_21)))/(r^p - 1);
E_32 = 100*((f(i,1) - f(i,2))/(f(i,2)));
GCI_32 = (1.25*(abs(E_32)))/(r^p - 1);
rpGCI_21 = r^p*GCI_21;
fprintf(’%8.4f & %8.4f & %8.4f & %8.4f & %8.2f & %8.2f & %8.2f & %8.2f n’,f_exact,f(i,3),f(i,2),f(i,1)
end
fprintf(’n’)
% plot final solution
plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
% record cpu time
cpu = toc;
% output computation information
fprintf(’ Computation information:nn’)
fprintf(’ number of iterations = %6in’,iterations)
fprintf(’ CPU time = %6.3fsn’,cpu)
fprintf(’----------------------------------------nn’)
% =========================================================================
function [U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord)
% This function calculates the initial values of U, x, z and dx given the
% number of nodes - 1 (N), the lower and upper bounds of the domain (xmin,
% xmax), the location of the dam (dam), the water depths upstream and
% downstream of the dam (uph, downh) and the co-ordinates defining the bed
% surface (zcoord).
% define spatial array x (including ghost nodes)
dx = (xmax - xmin)/N;
x = xmin - dx : dx : xmax + dx;
% define bed elevation z and calculate derivative of z
z = bed(x,zcoord);
dzdx = f_x(z,dx);
% define conserved variable array U
for i = 1 : length(x)
if x(i) <= dam
% upstream depth
U(1,i) = uph - z(i);
else
% downstream depth
U(1,i) = downh - z(i);
end
U(2,i) = 0;
% prevent negative water depth
20
21. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
if U(1,i) < 0
U(1,i) = 0;
end
end
% =========================================================================
function z = bed(x,zcoord)
% This function calculates the bed surface elevation z depending on the
% node coordinates x and bed coordinates zcoord
z = zeros(size(x));
for i = 1 : size(zcoord,1) - 1
if zcoord(i+1,2) == zcoord(i,2)
m = 0;
else
m = (zcoord(i+1,2) - zcoord(i,2))/(zcoord(i+1,1) - zcoord(i,1));
end
j = find(x > zcoord(i,1) & x <= zcoord(i+1,1));
z(j) = zcoord(i,2) + m*(x(j) - zcoord(i,1));
end
% =========================================================================
function [h,u] = getvariables(U)
% This function gets h and u from U
h = U(1,:);
u = zeros(1,length(h));
i = find(h > 1d-3);
u(i) = U(2,i)./U(1,i);
% =========================================================================
function U = drybed(U)
% This function sets the velocities of nodes where the bed is dry to zero.
[h,u] = getvariables(U);
U(1,:) = h;
U(2,:) = h.*u;
% =========================================================================
function dt = timestep(U,dx,cfl)
% This function calculates the maximum allowable timestep for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
dt = cfl*dx/max(abs(u) + sqrt(g*h));
% =========================================================================
function U = bc(U)
% This function calculates the boundary conditions for the 1D SWE
U(1,1)=U(1,3);
U(2,1)=-U(2,3);
U(1,end)=U(1,end-2);
U(2,end)=U(2,end-2);
% =========================================================================
function F = flux(U)
% This function calculates the flux vector for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
21
22. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
F(1,:) = h.*u;
F(2,:) = h.*u.*u + 0.5*g*h.*h;
% =========================================================================
function S = source(U,dzdx)
% This function calculates the bed source terms for the 1D SWE
g = 9.81;
S = zeros(size(U));
S(2,:) = -g*U(1,:).*dzdx;
% =========================================================================
function y = f_x(f,dx)
% This function calculates the 2nd order central difference approximation
% of df/dx.
y = zeros(size(f));
y(2:end-1) = (f(3:end) - f(1:end-2))/(2*dx);
% =========================================================================
function plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
% This function plots the solution
figure(1)
area(x,U(1,:)+z,’facecolor’,[0 1 1],’edgecolor’,’none’)
hold on
area(x,z,’facecolor’,[0.5 0.5 0.5],’edgecolor’,’none’);
hold off
% axis for different uph.
if uph == 8
axis([xmin xmax ymin 10])
elseif uph == 40
axis([xmin xmax ymin 50])
end
xlabel(’x (m)’,’fontsize’,16)
ylabel(’h+z (m)’,’fontsize’,16)
title(sprintf(’time = %6.2f’,t),’fontsize’,16)
shg
22
23. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
A.4 DENBYDOO FLOOD DEFENCE CASE STUDY WITH NUMBER OF
NODES FIXED TO 4000
function swe
% This program solves the SWE using the Lax-Friedrichs scheme
clear
clc
% define variables
xmin = 0; % lower bound of x
xmax = 1000; % upper bound of x
ymin = 0; % minimum value of y in the plot axis
ymax = 10; % maximum value of y in the plot axis
N = 4000; % number of nodes-1
dam = 200; % x co-ordinate of dam location
uph = 40; % water depth upstream of the dam
downh = 0; % water depth downstream of the dam
tmax = 115; % time at which the time marching loop will stop
cfl = 0.9; % value used to ensure stability by the cfl condition
% define bed surface co-ordinates
zcoord = [600 0 ; 800 6 ; 850 6 ; 950 0];
% calculate initial conditions
[U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord);
% calculate gradient of bed surface
dx = x(2) - x(1);
dzdx = f_x(z,dx);
% output run data to the command window
fprintf(’----------------------------------------n’)
fprintf(’ 1D SWE solvern’)
fprintf(’----------------------------------------n’)
fprintf(’ Solution parameters:nn’)
fprintf(’ domain length = %6.1fmn’,xmax)
fprintf(’ number of nodes, N = %4in’,N)
fprintf(’ grid spacing, dx = %6.1fmn’,dx)
fprintf(’ dam location, x = %6.1fmn’,dam)
fprintf(’ upstream depth, h = %6.1fmn’,uph)
fprintf(’ downsteam depth, h = %6.1fmn’,downh)
fprintf(’ max value of t = %6.1fsn’,tmax)
fprintf(’ Courant number, CFL = %6.1fnn’,cfl)
fprintf(’ Running program, please wait ...nn’)
% time marching loop
t = 0;
iterations = 0;
tic;
while t < tmax
% calculate dt and ensure that t does not exceed tmax
dt = timestep(U,dx,cfl);
dt = min(dt,tmax - t);
% calculate boundary conditions, flux vector and source terms
U = bc(U);
F = flux(U);
S = source(U,dzdx);
% Lax-Friedrichs scheme
23
24. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
U(:,2:end-1) = 0.5*(U(:,3:end) + U(:,1:end-2)) - 0.5*dt/dx ...
*(F(:,3:end) - F(:,1:end-2)) + dt*S(:,2:end-1);
% zero the velocities where the bed is dry
U = drybed(U);
% update t and iterations
t = t + dt;
iterations = iterations + 1;
% plot solution every 10 iterations (comment out if code is taking
% a long time to run)
if mod(iterations,10) == 0
plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
end
%
% point one at (600,0) fine grid
y1 = (600)/dx + 2;
index1 = round(y1);
numgauge1(iterations) = U(1,index1) + z(index1);
x(index1);
% point two (825,6) medium grid
y2 = (825)/dx + 2;
index2 = round(y2);
numgauge2(iterations) = U(1,index2) + z(index2);
x(index2);
% point three (975,0) coarse grid
y3 = (975)/dx + 2;
index3 = round(y3);
numgauge3(iterations) = U(1,index3) + z(index3);
x(index3);
% point where the village is
y4 = (1000)/dx + 2;
index4 = round(y4);
numgauge4(iterations) = U(1,index4) + z(index4);
x(index4);
maxheight = max(numgauge4); % maximum height of the wave
time(iterations) = t; % update each iteration
end
% print maximum height
fprintf(’Maxheight = %1.6f n’,maxheight)
% values for 8m and 40m at differnet points and will save it
% to a different file depends on the uph.
if uph == 8
gauges1_8 = [time’ numgauge1’];
gauges2_8 = [time’ numgauge2’];
gauges3_8 = [time’ numgauge3’];
save(’eight_metre’,’gauges1_8’,’gauges2_8’,’gauges3_8’)
elseif uph == 40
gauges1_40 = [time’ numgauge1’];
gauges2_40 = [time’ numgauge2’];
gauges3_40 = [time’ numgauge3’];
save(’fourty_metre’,’gauges1_40’,’gauges2_40’,’gauges3_40’)
24
25. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
end
% plot final solution
plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
% record cpu time
cpu = toc;
% output computation information
fprintf(’n’)
fprintf(’ Computation information:nn’)
fprintf(’ number of iterations = %6in’,iterations)
fprintf(’ CPU time = %6.3fsn’,cpu)
fprintf(’----------------------------------------nn’)
% =========================================================================
function [U,x,z] = initial(N,xmin,xmax,dam,uph,downh,zcoord)
% This function calculates the initial values of U, x, z and dx given the
% number of nodes - 1 (N), the lower and upper bounds of the domain (xmin,
% xmax), the location of the dam (dam), the water depths upstream and
% downstream of the dam (uph, downh) and the co-ordinates defining the bed
% surface (zcoord).
% define spatial array x (including ghost nodes)
dx = (xmax - xmin)/N;
x = xmin - dx : dx : xmax + dx;
% define bed elevation z and calculate derivative of z
z = bed(x,zcoord);
dzdx = f_x(z,dx);
% define conserved variable array U
for i = 1 : length(x)
if x(i) <= dam
% upstream depth
U(1,i) = uph - z(i);
else
% downstream depth
U(1,i) = downh - z(i);
end
U(2,i) = 0;
% prevent negative water depth
if U(1,i) < 0
U(1,i) = 0;
end
end
% =========================================================================
function z = bed(x,zcoord)
% This function calculates the bed surface elevation z depending on the
% node coordinates x and bed coordinates zcoord
z = zeros(size(x));
for i = 1 : size(zcoord,1) - 1
if zcoord(i+1,2) == zcoord(i,2)
m = 0;
else
m = (zcoord(i+1,2) - zcoord(i,2))/(zcoord(i+1,1) - zcoord(i,1));
25
26. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
end
j = find(x > zcoord(i,1) & x <= zcoord(i+1,1));
z(j) = zcoord(i,2) + m*(x(j) - zcoord(i,1));
end
% =========================================================================
function [h,u] = getvariables(U)
% This function gets h and u from U
h = U(1,:);
u = zeros(1,length(h));
i = find(h > 1d-3);
u(i) = U(2,i)./U(1,i);
% =========================================================================
function U = drybed(U)
% This function sets the velocities of nodes where the bed is dry to zero.
[h,u] = getvariables(U);
U(1,:) = h;
U(2,:) = h.*u;
% =========================================================================
function dt = timestep(U,dx,cfl)
% This function calculates the maximum allowable timestep for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
dt = cfl*dx/max(abs(u) + sqrt(g*h));
% =========================================================================
function U = bc(U)
% This function calculates the boundary conditions for the 1D SWE
U(1,1)=U(1,3);
U(2,1)=-U(2,3);
U(1,end)=U(1,end-2);
U(2,end)=U(2,end-2);
% =========================================================================
function F = flux(U)
% This function calculates the flux vector for the 1D SWE
g = 9.81;
[h,u] = getvariables(U);
F(1,:) = h.*u;
F(2,:) = h.*u.*u + 0.5*g*h.*h;
% =========================================================================
function S = source(U,dzdx)
% This function calculates the bed source terms for the 1D SWE
g = 9.81;
S = zeros(size(U));
S(2,:) = -g*U(1,:).*dzdx;
% =========================================================================
function y = f_x(f,dx)
% This function calculates the 2nd order central difference approximation
% of df/dx.
26
27. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
y = zeros(size(f));
y(2:end-1) = (f(3:end) - f(1:end-2))/(2*dx);
% =========================================================================
function plotsolution(U,x,z,t,xmin,xmax,ymin,uph)
% This function plots the solution
figure(1)
area(x,U(1,:)+z,’facecolor’,[0 1 1],’edgecolor’,’none’)
hold on
area(x,z,’facecolor’,[0.5 0.5 0.5],’edgecolor’,’none’);
hold off
% axis for different uph.
if uph == 8
axis([xmin xmax ymin 10])
elseif uph == 40
axis([xmin xmax ymin 50])
end
xlabel(’x (m)’,’fontsize’,16)
ylabel(’h+z (m)’,’fontsize’,16)
title(sprintf(’time = %6.2f’,t),’fontsize’,16)
shg
27
28. Journal of Flood Risk Management & Control • February 2014 • Vol. XV, No. 1
A.5 PLOTS FOR THE 2 CONFIGURATIONS
% two configrations for Denbydoo
%clear workspaces
clear
clc
clf
% loading files for different uph.
load eight_metre
load fourty_metre
% plots for 8m and 40m uph at three different points
figure(1)
plot(gauges1_8(:,1),gauges1_8(:,2),’r-’,gauges1_40(:,1),gauges1_40(:,2),’b-’)
title(’Toe of the Rubbe Mound (x = 600.00m) for 8m and 40m of depths upstream of the dam’)
xlabel(’time (s)’)
ylabel(’h+z (m)’)
axis([0 85 -0.01 8.5])
legend(’water depth upstream of 8m’,’water depth upstream of 40m’)
hold on
figure(2)
plot(gauges2_8(:,1),gauges2_8(:,2),’r-’,gauges2_40(:,1),gauges2_40(:,2),’b-’)
title(’Mid point on the top of the Rubbe Mound (x = 825.00m) for 8m and 40m of depths upstream of t
xlabel(’time (s)’)
ylabel(’h+z (m)’)
axis([0 100 5.99 13])
legend(’water depth upstream of 8m’,’water depth upstream of 40m’)
figure(3)
plot(gauges3_8(:,1),gauges3_8(:,2),’r-’,gauges3_40(:,1),gauges3_40(:,2),’b-’)
title(’Location between the rubble mound and the town of Denbydoo (x = 975.00m) for 8m and 40m’)
xlabel(’time (s)’)
ylabel(’h+z (m)’)
axis([0 115 -0.01 5.2])
legend(’water depth upstream of 8m’,’water depth upstream of 40m’)
hold off
28