Ir al contenido

underwater.numerical_propagation

Esta página aún no está disponible en tu idioma.

Numerical models of underwater sound propagation (range-independent ocean).

Three complementary numerical solvers for the acoustic field in a horizontally-stratified ocean waveguide, complementing the closed-form transmission loss of phonometry.underwater.propagation:

  • normal_modes — the normal-mode expansion. Solves the depth-separated Sturm-Liouville eigenvalue problem by finite differences and assembles the transmission loss from the propagating modes.
  • ray_trace — ray tracing. Integrates the ray-trajectory equations through a sound-speed profile (Runge-Kutta), returning the ray paths.
  • parabolic_equation — the standard (Tappert) parabolic equation, solved with the split-step Fourier algorithm, returning the transmission-loss field.

All three are implemented clean-room from Jensen, Kuperman, Porter & Schmidt, Computational Ocean Acoustics (2nd ed., Springer 2011): the modal derivation (Ch. 5, Eqs. 5.3-5.17), the ray equations (Ch. 3, Eqs. 3.23-3.24) and the split-step Fourier PE (Ch. 6). They are validated against analytic oracles: the ideal (pressure-release) waveguide’s exact modes, the circular-arc ray paths of a linear sound-speed gradient, and mutual agreement of the PE and normal-mode transmission loss for a range-independent waveguide.

Densities are in kg/m3, sound speeds in m/s, depths and ranges in metres, frequencies in Hz. The water column has a pressure-release surface at z = 0.

Auto-generated from the source docstrings by scripts/generate_api_docs.py (make api-docs). Do not edit by hand.

normal_modes(
frequency_hz: float,
depths: NDArray[np.float64] | list[float],
sound_speeds: NDArray[np.float64] | list[float],
*,
source_depth: float,
receiver_depth: float,
ranges_m: NDArray[np.float64] | list[float] | None = None,
density: float = 1000.0,
bottom: str = 'pressure-release',
n_depth_points: int | None = None,
) -> NormalModeResult

Normal-mode transmission loss for a range-independent waveguide.

Solves the depth-separated Sturm-Liouville problem (Jensen Eq. 5.3) on a uniform finite-difference grid, then assembles the coherent transmission loss from the propagating modes (Eq. 5.17).

The finite-difference eigenvalues carry an O(dz²) error that grows with the mode’s vertical wavenumber, so near-cutoff modes need a fine grid. Two guards apply: eigenvalues inside the scheme’s error band (kr² ≤ max(k²)²·dz²/12) are discarded as numerically indistinguishable from cutoff, and a PhonometryWarning is emitted when a retained mode sits within ten times that band (increase n_depth_points to resolve it).

Parameters

NameDescription
frequency_hzSource frequency, in Hz.
depthsDepth samples of the sound-speed profile, in metres, starting at the surface z = 0 and strictly increasing to the bottom.
sound_speedsSound speed at each depth, in m/s.
source_depthSource depth zs, in metres.
receiver_depthReceiver depth for the transmission-loss slice, in m.
ranges_mRanges at which to evaluate the loss, in metres; defaults to 100 m to 10 km.
densityWater density (constant), in kg/m3.
bottom"pressure-release" (default) or "rigid".
n_depth_pointsNumber of finite-difference depth points. Default (None): derived from the physics as max(400, ceil(60·D·f/c_min)), which keeps the near-cutoff eigenvalue error small at any frequency/depth combination, capped at 20 000 points (very high f·D products exceed the cap; the near-cutoff warning then indicates whether the capped grid suffices, and an explicit n_depth_points overrides the cap).

Returns: A NormalModeResult.

Raises

ExceptionWhen
ValueErrorIf the inputs are invalid.
NormalModeResult(
frequency: float,
wavenumbers: NDArray[np.float64],
mode_depths: NDArray[np.float64],
mode_functions: NDArray[np.float64],
ranges: NDArray[np.float64],
transmission_loss: NDArray[np.float64],
receiver_depth: float,
source_depth: float,
)

Normal-mode solution of a range-independent waveguide.

Attributes

NameDescription
frequencySource frequency, in Hz.
wavenumbersHorizontal wavenumbers krm of the propagating modes, in rad/m (descending order).
mode_depthsDepth grid of the mode functions, in metres.
mode_functionsOrthonormalised mode shapes Ψm(z), shape (n_modes, n_depths).
rangesRanges at which the transmission loss is evaluated, in metres.
transmission_lossCoherent transmission loss at receiver_depth per range, in dB.
receiver_depthReceiver depth of the transmission-loss slice, in m.
source_depthSource depth, in metres.
NormalModeResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the transmission loss versus range (loss increasing downward).

parabolic_equation(
frequency_hz: float,
depths: NDArray[np.float64] | list[float],
sound_speeds: NDArray[np.float64] | list[float],
*,
source_depth: float,
max_range: float = 10000.0,
range_step: float = 10.0,
n_depth_points: int = 1024,
) -> ParabolicEquationResult

Transmission-loss field from the standard (Tappert) parabolic equation.

Marches the split-step Fourier solution (Jensen Ch. 6) in range with a discrete sine transform in depth, enforcing a pressure-release surface at z = 0 and bottom at z = water_depth. The envelope is related to pressure by p = ψ e^{i(k0 r − π/4)}/√r and TL = −20·log10(|ψ|/√r) (Eqs. 6.70-6.71), using a Gaussian starter.

The standard PE is paraxial: it is accurate for propagation within roughly ±15-20° of the horizontal (Jensen §6.2). Steep modes therefore carry a phase error that shows at short and intermediate range in shallow-waveguide problems (a few dB against the exact field below a few water depths of range), converging at long range; the free-field calibration itself is exact to ~1e-4 dB at the default range_step.

Parameters

NameDescription
frequency_hzSource frequency, in Hz.
depthsDepth samples of the profile, in metres, from z = 0.
sound_speedsSound speed at each depth, in m/s.
source_depthSource depth, in metres.
max_rangeMaximum range, in metres.
range_stepRange marching step Δr, in metres.
n_depth_pointsNumber of depth points (interior sine-transform grid).

Returns: A ParabolicEquationResult.

Raises

ExceptionWhen
ValueErrorIf the inputs are invalid.
ParabolicEquationResult(
frequency: float,
ranges: NDArray[np.float64],
depths: NDArray[np.float64],
transmission_loss: NDArray[np.float64],
source_depth: float,
)

Parabolic-equation transmission-loss field.

Attributes

NameDescription
frequencySource frequency, in Hz.
rangesRange grid, in metres.
depthsDepth grid, in metres.
transmission_lossTransmission-loss field TL(z, r), in dB, shape (n_depths, n_ranges).
source_depthSource depth, in metres.
ParabolicEquationResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the transmission-loss field (depth increasing downward).

ray_trace(
depths: NDArray[np.float64] | list[float],
sound_speeds: NDArray[np.float64] | list[float],
*,
source_depth: float,
launch_angles_deg: NDArray[np.float64] | list[float],
max_range: float = 10000.0,
n_steps: int = 2000,
) -> RayTraceResult

Trace acoustic rays through a range-independent sound-speed profile.

Integrates the ray-trajectory equations (Jensen Eqs. 3.23-3.24) with a fixed-step fourth-order Runge-Kutta scheme, reflecting at the pressure-release surface (z = 0) and the bottom (z = water_depth).

Parameters

NameDescription
depthsDepth samples of the profile, in metres, from z = 0.
sound_speedsSound speed at each depth, in m/s.
source_depthSource depth, in metres.
launch_angles_degLaunch angles from the horizontal, in degrees (positive downward).
max_rangeMaximum horizontal range to trace, in metres.
n_stepsNumber of integration steps per ray.

Returns: A RayTraceResult.

Raises

ExceptionWhen
ValueErrorIf the inputs are invalid.
RayTraceResult(
launch_angles: NDArray[np.float64],
ranges: NDArray[np.float64],
depths: NDArray[np.float64],
source_depth: float,
water_depth: float,
)

Ray-tracing solution through a sound-speed profile.

Attributes

NameDescription
launch_anglesLaunch angles from the horizontal, in degrees.
rangesPer-ray horizontal ranges, in metres, shape (n_rays, n_steps).
depthsPer-ray depths, in metres, shape (n_rays, n_steps).
source_depthSource depth, in metres.
water_depthWater-column depth, in metres.
RayTraceResult.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the ray paths (depth increasing downward).