Skip to content

Commit 6e1b1e6

Browse files
committed
Dingemans
1 parent eb9606f commit 6e1b1e6

File tree

4 files changed

+157
-11
lines changed

4 files changed

+157
-11
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ out*/
88
/docs/build/
99
run
1010
run/*
11+
**/*.code-workspace
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using OrdinaryDiffEq
2+
using DispersiveShallowWater
3+
using SummationByPartsOperators: upwind_operators, periodic_derivative_operator
4+
5+
###############################################################################
6+
# Semidiscretization of the Svärd-Kalisch equations
7+
8+
bathymetry = bathymetry_variable # or bathymetry_mild_slope
9+
equations = SerreGreenNaghdiEquations1D(bathymetry;
10+
gravity_constant = 9.81)
11+
12+
initial_condition = initial_condition_dingemans
13+
boundary_conditions = boundary_condition_periodic
14+
15+
# create homogeneous mesh
16+
coordinates_min = -140.0
17+
coordinates_max = 100.0
18+
N = 512
19+
mesh = Mesh1D(coordinates_min, coordinates_max, N)
20+
21+
# create solver with periodic upwind SBP operators of accuracy order 4
22+
# (note that only central-type with even order are used)
23+
D1 = upwind_operators(periodic_derivative_operator;
24+
derivative_order = 1, accuracy_order = 3,
25+
xmin = xmin(mesh), xmax = xmax(mesh),
26+
N = nnodes(mesh))
27+
solver = Solver(D1, nothing)
28+
29+
# semidiscretization holds all the necessary data structures for the spatial discretization
30+
semi = Semidiscretization(mesh, equations, initial_condition, solver,
31+
boundary_conditions = boundary_conditions)
32+
33+
###############################################################################
34+
# Create `ODEProblem` and run the simulation
35+
tspan = (0.0, 70.0)
36+
ode = semidiscretize(semi, tspan)
37+
summary_callback = SummaryCallback()
38+
analysis_callback = AnalysisCallback(semi; interval = 10,
39+
extra_analysis_errors = (:conservation_error,),
40+
extra_analysis_integrals = (waterheight_total,
41+
momentum,
42+
entropy,
43+
entropy_modified))
44+
45+
callbacks = CallbackSet(analysis_callback, summary_callback)
46+
47+
saveat = range(tspan..., length = 500)
48+
sol = solve(ode, Tsit5(), abstol = 1e-7, reltol = 1e-7,
49+
save_everystep = false, callback = callbacks, saveat = saveat)

src/equations/serre_green_naghdi_1d.jl

+78-11
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,19 @@ end
7777

7878
function SerreGreenNaghdiEquations1D(bathymetry = bathymetry_flat;
7979
gravity_constant, eta0 = 0.0)
80-
eta0 == 0.0 ||
81-
@warn "The still-water surface needs to be 0 for the Serre-Green-Naghdi equations"
8280
SerreGreenNaghdiEquations1D(bathymetry, gravity_constant, eta0)
8381
end
8482

83+
function get_name(equations::SerreGreenNaghdiEquations1D)
84+
name = equations |> typeof |> nameof |> string
85+
bathymetry = equations.bathymetry
86+
if bathymetry isa BathymetryFlat
87+
return name
88+
else # variable bathymetry
89+
return name * "-" * string(nameof(typeof(bathymetry)))
90+
end
91+
end
92+
8593
varnames(::typeof(prim2prim), ::SerreGreenNaghdiEquations1D) = ("η", "v", "D")
8694
varnames(::typeof(prim2cons), ::SerreGreenNaghdiEquations1D) = ("h", "hv", "b")
8795

@@ -107,6 +115,46 @@ function initial_condition_convergence_test(x, t, equations::SerreGreenNaghdiEqu
107115
return SVector(h, v, 0)
108116
end
109117

118+
"""
119+
initial_condition_dingemans(x, t, equations::SerreGreenNaghdiEquations1D, mesh)
120+
121+
The initial condition that uses the dispersion relation of the Euler equations
122+
to approximate waves generated by a wave maker as it is done by experiments of
123+
Dingemans. The topography is a trapezoidal. It is assumed that `equations.eta0 = 0.8`.
124+
125+
References:
126+
- Magnus Svärd, Henrik Kalisch (2023)
127+
A novel energy-bounded Boussinesq model and a well-balanced and stable numerical discretization
128+
[arXiv: 2302.09924](https://arxiv.org/abs/2302.09924)
129+
- Maarten W. Dingemans (1994)
130+
Comparison of computations with Boussinesq-like models and laboratory measurements
131+
[link](https://repository.tudelft.nl/islandora/object/uuid:c2091d53-f455-48af-a84b-ac86680455e9/datastream/OBJ/download)
132+
"""
133+
function initial_condition_dingemans(x, t, equations::SerreGreenNaghdiEquations1D, mesh)
134+
h0 = 0.8
135+
A = 0.02
136+
# omega = 2*pi/(2.02*sqrt(2))
137+
k = 0.8406220896381442 # precomputed result of find_zero(k -> omega^2 - equations.gravity * k * tanh(k * h0), 1.0) using Roots.jl
138+
if x < -34.5 * pi / k || x > -8.5 * pi / k
139+
h = 0.0
140+
else
141+
h = A * cos(k * x)
142+
end
143+
v = sqrt(equations.gravity / k * tanh(k * h0)) * h / h0
144+
if 11.01 <= x && x < 23.04
145+
b = 0.6 * (x - 11.01) / (23.04 - 11.01)
146+
elseif 23.04 <= x && x < 27.04
147+
b = 0.6
148+
elseif 27.04 <= x && x < 33.07
149+
b = 0.6 * (33.07 - x) / (33.07 - 27.04)
150+
else
151+
b = 0.0
152+
end
153+
eta = h + h0
154+
D = equations.eta0 - b
155+
return SVector(eta, v, D)
156+
end
157+
110158
# flat bathymetry
111159
function create_cache(mesh,
112160
equations::SerreGreenNaghdiEquations1D{BathymetryFlat},
@@ -245,15 +293,15 @@ function create_cache(mesh,
245293

246294
factorization = cholesky(system_matrix)
247295

248-
cache = (; h_x, v_x, v_x_upwind, h_hpb_x, b, b_x, hv_x, v2_x,
296+
cache = (; h, h_x, v_x, v_x_upwind, h_hpb_x, b, b_x, hv_x, v2_x,
249297
h2_v_vx_x, h_vx_x, p_h, p_0, p_x, tmp,
250298
M_h_p_h_bx2, M_h3_3, M_h2_bx,
251299
D, Dmat_minus, factorization)
252300
else
253301
if D isa FourierDerivativeOperator
254302
Dmat = Matrix(D)
255303

256-
cache = (; h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
304+
cache = (; h, h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
257305
h2_v_vx_x, h_vx_x, p_h, p_x, tmp,
258306
M_h_p_h_bx2, M_h3_3, M_h2_bx,
259307
D, Dmat)
@@ -285,7 +333,7 @@ function create_cache(mesh,
285333

286334
factorization = cholesky(system_matrix)
287335

288-
cache = (; h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
336+
cache = (; h, h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
289337
h2_v_vx_x, h_vx_x, p_h, p_x, tmp,
290338
M_h_p_h_bx2, M_h3_3, M_h2_bx,
291339
D, Dmat, factorization)
@@ -531,20 +579,21 @@ function rhs_sgn_central!(dq, q, equations, source_terms, cache,
531579

532580
# `q` and `dq` are `ArrayPartition`s. They collect the individual
533581
# arrays for the water height `h` and the velocity `v`.
534-
h, v = q.x
582+
eta, v = q.x
535583
dh, dv, dD = dq.x
536584
fill!(dD, zero(eltype(dD)))
537585

538586
@trixi_timeit timer() "hyperbolic terms" begin
539587
# Compute all derivatives required below
540-
(; h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
588+
(; h, h_x, v_x, h_hpb_x, b, b_x, hv_x, v2_x,
541589
h2_v_vx_x, h_vx_x, p_h, p_x, tmp,
542590
M_h_p_h_bx2, M_h3_3, M_h2_bx) = cache
543591
if equations.bathymetry isa BathymetryVariable
544592
(; ψ) = cache
545593
end
546594

547595
@. b = equations.eta0 - q.x[3]
596+
@. h = eta - b
548597
mul!(b_x, D, b)
549598

550599
mul!(h_x, D, h)
@@ -662,20 +711,21 @@ function rhs_sgn_upwind!(dq, q, equations, source_terms, cache,
662711

663712
# `q` and `dq` are `ArrayPartition`s. They collect the individual
664713
# arrays for the water height `h` and the velocity `v`.
665-
h, v, b = q.x
714+
eta, v, b = q.x
666715
dh, dv, db = dq.x
667716
fill!(db, zero(eltype(db)))
668717

669718
@trixi_timeit timer() "hyperbolic terms" begin
670719
# Compute all derivatives required below
671-
(; h_x, v_x, v_x_upwind, h_hpb_x, b, b_x, hv_x, v2_x,
720+
(; h, h_x, v_x, v_x_upwind, h_hpb_x, b, b_x, hv_x, v2_x,
672721
h2_v_vx_x, h_vx_x, p_h, p_0, p_x, tmp,
673722
M_h_p_h_bx2, M_h3_3, M_h2_bx) = cache
674723
if equations.bathymetry isa BathymetryVariable
675724
(; ψ) = cache
676725
end
677726

678727
@. b = equations.eta0 - q.x[3]
728+
@. h = eta - b
679729
mul!(b_x, D, b)
680730

681731
mul!(h_x, D, h)
@@ -856,14 +906,31 @@ function energy_total_modified(q_global,
856906
N = length(v)
857907
e = zeros(eltype(q_global), N)
858908

859-
# 1/2 g h^2 + 1/2 h v^2 + 1/6 h^3 v_x^2
909+
# 1/2 g h^2 + 1/2 h v^2 + 1/6 h^3 w^2
910+
# and + 1/8 h (v b_x)^2 for full bathymetry without mild-slope approximation
860911
if D isa PeriodicUpwindOperators
861912
mul!(v_x, D.minus, v)
862913
else
863914
mul!(v_x, D, v)
864915
end
865916

866-
@. e = 1 / 2 * g * h^2 + 1 / 2 * h * v^2 + 1 / 6 * h^3 * v_x^2
917+
if equations.bathymetry isa BathymetryFlat
918+
b_x = cache.tmp
919+
fill!(b_x, zero(eltype(b_x)))
920+
else
921+
(; b, b_x) = cache
922+
@. b = equations.eta0 - q_global.x[3]
923+
if D isa PeriodicUpwindOperators
924+
mul!(b_x, D.central, b)
925+
else
926+
mul!(b_x, D, b)
927+
end
928+
end
929+
930+
@. e = 1 / 2 * g * h^2 + 1 / 2 * h * v^2 + 1 / 6 * h * (-h * v_x + 1.5 * v * b_x)^2
931+
if equations.bathymetry isa BathymetryVariable
932+
@. e += 1 / 8 * h * (v * b_x)^2
933+
end
867934

868935
return e
869936
end

test/test_serre_green_naghdi_1d.jl

+29
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,35 @@ EXAMPLES_DIR = joinpath(examples_dir(), "serre_green_naghdi_1d")
179179

180180
@test_allocations(semi, sol, allocs=850_000)
181181
end
182+
183+
@trixi_testset "serre_green_naghdi_dingemans.jl" begin
184+
@test_trixi_include(joinpath(EXAMPLES_DIR,
185+
"serre_green_naghdi_dingemans.jl"),
186+
tspan=(0.0, 1.0),
187+
l2=[0.2463295492331802, 0.805357513755897, 0.0],
188+
linf=[0.036265772921736605, 0.11763218152350845, 0.0],
189+
cons_error=[5.684341886080802e-14, 3.509473432346808e-5, 0.0],
190+
change_waterheight=5.684341886080802e-14,
191+
change_entropy=1.9489684518703143e-5,
192+
change_entropy_modified=-1.2177679309388623e-8)
193+
194+
@test_allocations(semi, sol, allocs=750_000)
195+
end
196+
197+
@trixi_testset "serre_green_naghdi_dingemans.jl with bathymetry_mild_slope" begin
198+
@test_trixi_include(joinpath(EXAMPLES_DIR,
199+
"serre_green_naghdi_dingemans.jl"),
200+
tspan=(0.0, 1.0),
201+
equations = SerreGreenNaghdiEquations1D(bathymetry_mild_slope; gravity_constant = 9.81),
202+
l2=[0.2463295492331802, 0.805357513755897, 0.0],
203+
linf=[0.036265772921736605, 0.11763218152350845, 0.0],
204+
cons_error=[5.684341886080802e-14, 3.509473432346624e-5, 0.0],
205+
change_waterheight=5.684341886080802e-14,
206+
change_entropy=1.9489684518703143e-5,
207+
change_entropy_modified=-1.2177679309388623e-8)
208+
209+
@test_allocations(semi, sol, allocs=750_000)
210+
end
182211
end
183212

184213
end # module

0 commit comments

Comments
 (0)