Package Guide
SpectralWaves.jl
is a Julia package for simulation of nonlinear waves propagating over arbitrary topography.
Instalation
pkg> add SpectralWaves
julia> using SpectralWaves
Quick start
We begin our introduction with an evolution of a free surface for an initial bump of water in a domain of length ℓ
and still water depth d
. We aim to compare free-surface evolution for the case of constant and uneven bottom.
using SpectralWaves
using CairoMakie # plotting package
d = 1.0 # water depth (m)
ℓ = 10.0 # fluid domain length (m)
We define a number of numerical model parameters.
ℐ = 40 # number of harmonics
Δt = 0.01 # time step (s)
t₀ = 0.0 # initial time (s)
τ = 2.0 # total simulation time (s)
t = range(start = t₀, stop = τ, step = Δt) # time range
We initialize a constant bottom wave problem p₀
and an uneven bottom wave problem p₁
using struct Problem
. Please note that we set a bottom nonlinearity parameter M_b=40
in case of an uneven bottom, while for constant bottom we leave its default (M_b=0
) value.
p₀ = Problem(ℓ, d, ℐ, t)
p₁ = Problem(ℓ, d, ℐ, t; M_b=40)
The free surface corresponds to a Gaussian surface_bump!
of characteristic height h
and length λ
and is applied to both problems p₀
and p₁
, while we add some bottom variation by applying a Gaussian bottom_bump!
of characteristic height h₁
and length λ₁
to problem p₁
.
h = 0.4d # surface bump height (m)
λ = 0.1ℓ # surface bump length (m)
surface_bump!(p₀, h, λ)
surface_bump!(p₁, h, λ)
h₁ = 0.9d # bottom bump height (m)
λ₁ = 0.5ℓ # bottom bump length (m)
bottom_bump!(p₁, h₁, λ₁)
We solve both problems. For that, we use an in-place function solve_problem!
.
solve_problem!(p₀; msg_flag=false)
solve_problem!(p₁; msg_flag=false)
Finally, we may calculate free surface elevation and bottom surface position using water_surface
and bottom_surface
functions
η₀(x, n) = water_surface(p₀, x, n)
η₁(x, n) = water_surface(p₁, x, n)
β(x) = bottom_surface(p₁, x)
and plot the results for a range of spatial points x
.
x = range(start = - ℓ / 2, stop = ℓ / 2, length = 1001) # spatial range
o₀ = Observable(η₀.(x, firstindex(t))) # set free-surface observable for p₀
o₁ = Observable(η₁.(x, firstindex(t))) # set free-surface observable for p₁
title = Observable(L"t = %$(round(t[1], digits=1))\,\mathrm{s}") # set string observable
set_theme!(theme_latexfonts()) # set latex fonts
fig = Figure(size = (700, 300)) # initialize a figure
# left plot p₀
ax0 = Axis(fig[1, 1],
xlabel = L"$x$ (m)",
ylabel = L"$z$ (m)") # define axis with labels
band!(ax0, x, o₀, -d,
color=:azure) # plot water bulk
lines!(ax0, x, o₀,
color=:black,
linewidth = 1) # plot free surface line
band!(ax0, x, -1.1d, - d,
color=:wheat) # plot bottom bulk
hlines!(ax0, -d,
color=:black,
linewidth = 0.7) # plot bottom line
limits!(ax0, x[1], x[end], -1.1d, d) # set limits
# right plot p₁
ax1 = Axis(fig[1, 2],
xlabel = L"$x$ (m)") # define axis with labels
band!(ax1, x, o₁, β.(x) .-d,
color=:azure) # plot water bulk
lines!(ax1, x, o₁,
color=:black,
linewidth = 1) # plot free surface line
band!(ax1, x, β.(x) .- d, - 1.1d,
color=:wheat) # plot bottom bulk
lines!(ax1, x, β.(x) .- d,
color=:black,
linewidth = 1) # plot bottom line
limits!(ax1, x[1], x[end], -1.1d, d) # set limits
Label(fig[0, :], text=title)
# animate free surface
record(fig, "animation.mp4", 1:lastindex(t);
framerate = 30) do n
o₀[] = η₀.(x, n)
o₁[] = η₁.(x, n)
title[] = L"t = %$(round(t[n], digits=1))\,\mathrm{s}"
end
You can define initial conditions, forcing mechanisms, bottom geometry and its kinematics, on your own following functions listed in the API. We are going to add more of them with subsequent updates of the package. Meanwhile go to the next section, where more examples are shown.