Airy Waves

WaveSpec.AiryWaves.generate_interpolable_sea — Method
generate_interpolable_sea(state::AiryState, x, y, z, t; vars=[:η, :ϕ, :u, :v, :w], interp=:linear)

Computes the sea fields on the provided regular grids and returns a NamedTuple of interpolation functions for each requested variable. Each interpolant is a callable taking (x, y, z, t) and returning the interpolated value.

Arguments

  • state: an AiryState produced by AiryState(...) or constructed manually.
  • x, y, z, t: regular 1D coordinate vectors used to compute the fields.
  • vars: which fields to compute, default [:η, :ϕ, :u, :v, :w].
  • interp: interpolation kernel, :linear (default), :cubic, or :nearest.

Examples

using WaveSpec

# (1) Construct an AiryState (example uses a regular monochromatic wave)
spec = WaveSpec.ContinuousSpectrums.RegularWave(1.0, 5.0)                      # H=1 m, T=5 s
ds = WaveSpec.SpectralSpreading.DiscreteSpectralSpreading(spec)                # discrete spectrum
spread = WaveSpec.AngularSpreading.DiscreteAngularSpreading(0.0)              # unidirectional
as = WaveSpec.AiryWaves.AiryState(ds, spread, 50.0)                          # water depth 50 m

# (2) Choose evaluation grid
x = range(0.0, stop=10.0, length=11)
y = [0.0]
z = [0.0]
t = 0.0:0.1:10.0

# (3) Get interpolants (linear by default)
itps = WaveSpec.AiryWaves.generate_interpolable_sea(as, collect(x), collect(y), collect(z), collect(t); vars=[:η])

# (4) Evaluate η at an arbitrary point (not necessarily on the grid)
η_val = itps[:η](1.23, 0.0, 0.0, 2.57)
source
WaveSpec.AiryWaves.generate_sea — Function
generate_sea(state::AiryState, x, y, z, t; vars=[:η, :ϕ, :u, :v, :w])

Evaluate the requested fields on the tensor grid x × y × z × t and return a NamedTuple of 4D arrays. η has size (nx, ny, 1, nt); ϕ, u, v, w have size (nx, ny, nz, nt).

The method is defined in AiryEvaluation.jl, after AiryRealization: the state is realized once and evaluated point by point with the threaded, allocation-free kernels, so memory use is proportional to the output size.

source
WaveSpec.AiryWaves.get_amplitudes — Method
get_amplitudes(state::AiryState)

Return the component-amplitude matrix with shape (state.nω, state.nθ). Rows correspond to frequency bins and columns to direction bins.

source
WaveSpec.AiryWaves.get_random_phases — Method
get_random_phases(state::AiryState)

Return the deterministic component-phase matrix with shape (state.nω, state.nθ). Repeated calls for the same state return the same phases because they are generated from state.seed.

source
WaveSpec.AiryWaves.solve_wavenumber — Method
solve_wavenumber(ω::Real, h::Real)

Solve the finite-depth linear-wave dispersion relation for wavenumber k:

\[\omega^2 = g k \tanh(k h)\]

ω is in rad/s, h is in metres, and the returned k is in rad/m.

source

Components and realizations

WaveSpec.AiryRealization — Type
AiryRealization

A realized Airy-wave field.

Unlike AiryState, which stores the spectral and directional discretization together with a random seed, an AiryRealization stores the fully materialized wave components:

(ω, kx, ky, amplitude, phase)

and therefore represents one deterministic realization of the sea state.

Two realizations generated from the same AiryState will be identical provided the same random seed is used.

AiryRealization(components::WaveComponents{T}, k::Vector{T}, h::T)

Build a realization from explicit components, their wavenumber magnitudes k (one per component) and the water depth h. The depth-independent factors of the kinematic kernels are precomputed once per component here, so that the evaluation kernels only compute the phase and the vertical profile per point:

\[e_{2kh,i} = e^{-2 k_i h}, \quad c_{ϕ,i} =\frac{g}{\omega_i (1 + e^{-2 k_i h})}, \quad c_{w,i} = \frac{\omega_i}{1 - e^{-2 k_i h}}, \quad c_{u,i} = c_{w,i} \frac{k_{x,i}}{k_i}, \quad c_{v,i} = c_{w,i} \frac{k_{y,i}}{k_i}\]

source
WaveSpec.realize — Function
realize(state::AiryWaves.AiryState)

Build a persistent realization from state. The operation only reorganizes existing Airy-state data and fixes the deterministic random phases associated with state.seed; it does not evaluate the wave field.

Components are stored with the direction index varying fastest: component n = (i - 1) * nθ + j corresponds to frequency ω[i] and direction θ[j].

source
WaveSpec.evaluate_η — Function
evaluate_η(realization, x, y, t)

Evaluate free-surface elevation η at a single point and time using a precomputed Airy realization. It assumes that the free surface is located at z = 0. The formula for the free-surface elevation η is given by:

\[η(x, y, t) = \sum_{i} A_i \cos(k_{x,i} x + k_{y,i} y - \omega_i t + \phi_i)\]

The implementation is intentionally component-wise and allocation-free.

source
WaveSpec.evaluate_ϕ — Function
evaluate_ϕ(realization::AiryRealization, x::Real, y::Real, z::Real, t::Real)

Evaluate the velocity potential ϕ at a single point and time using a precomputed Airy realization. The formula for the velocity potential ϕ is given by:

\[ϕ(x, y, z, t) = \sum_{i} A_i \frac{g}{\omega_i} \frac{\cosh(k_i (z + h))}{\cosh(k_i h)} \sin(k_{x,i} x + k_{y,i} y - \omega_i t + \phi_i)\]

The implementation is intentionally component-wise and allocation-free.

source
WaveSpec.evaluate_u — Function
evaluate_u(realization::AiryRealization, x::Real, y::Real, z::Real, t::Real)

Evaluate the horizontal velocity component u at a single point and time using a precomputed Airy realization. The formula for the horizontal velocity component u is given by:

\[u(x, y, z, t) = \sum_{i} A_i \omega_i \frac{k_{x,i}}{k_i} \frac{\cosh(k_i (z + h))}{\sinh(k_i h)} \cos(k_{x,i} x + k_{y,i} y - \omega_i t + \phi_i)\]

The implementation is intentionally component-wise and allocation-free.

source
WaveSpec.evaluate_v — Function
evaluate_v(realization::AiryRealization, x::Real, y::Real, z::Real, t::Real)

Evaluate the horizontal velocity component v at a single point and time using a precomputed Airy realization. The formula for the horizontal velocity component v is given by:

\[v(x, y, z, t) = \sum_{i} A_i \omega_i \frac{k_{y,i}}{k_i} \frac{\cosh(k_i (z + h))}{\sinh(k_i h)} \cos(k_{x,i} x + k_{y,i} y - \omega_i t + \phi_i)\]

The implementation is intentionally component-wise and allocation-free.

source
WaveSpec.evaluate_w — Function
evaluate_w(realization::AiryRealization, x::Real, y::Real, z::Real, t::Real)

Evaluate the vertical velocity component w at a single point and time using a precomputed Airy realization. The formula for the vertical velocity component w is given by:

\[w(x, y, z, t) = \sum_{i} A_i \omega_i \frac{\sinh(k_i (z + h))}{\sinh(k_i h)} \sin(k_{x,i} x + k_{y,i} y - \omega_i t + \phi_i)\]

The implementation is intentionally component-wise and allocation-free.

source
WaveSpec.evaluate_fields — Function
evaluate_fields(realization::AiryRealization, x::Real, y::Real, z::Real, t::Real)

Evaluate all Airy fields at a single point and time in one pass over the components and return them as a NamedTuple (η, ϕ, u, v, w). η is the free-surface elevation (independent of z); ϕ, u, v, w are evaluated at z.

Each component's phase, sincos and vertical profile are computed once and shared by the five fields, so this costs about as much as a single evaluate_ϕ call instead of five separate evaluations.

source
WaveSpec.evaluate_fields! — Function
evaluate_fields!(η, ϕ, u, v, w, realization, x, y, z, t)

In-place, multi-threaded version of evaluate_fields over the points (x[j], y[j], z[j], t[j]). All arrays must share the same axes.

source