<!-- canonical: https://jmrplens.github.io/phonometry/es/guides/underwater-propagation/ -->
Source: https://jmrplens.github.io/phonometry/es/guides/underwater-propagation/

Propagación submarina de forma cerrada, complemento de los niveles de referencia
de la página de [Acústica submarina](/phonometry/es/guides/underwater-acoustics/):
la **pérdida por transmisión**, la **velocidad del sonido** en agua de mar, la
**ecuación del sonar**, la **pérdida por reflexión en el fondo** y el espectro de
**ruido ambiental oceánico**.

## Pérdida por transmisión

La pérdida por transmisión es

$$
TL = \text{ensanchamiento} + \alpha R .
$$

El ensanchamiento geométrico es $20 \lg R$ (esférico), $10 \lg R$ (cilíndrico)
o esférico hasta una distancia de transición $R_0$ y cilíndrico más allá
de esta (`"practical"`). El coeficiente de absorción de volumen $\alpha$ (dB/km)
procede de **Francois–Garrison** (1982, por
defecto y de referencia), **Ainslie–McColm** (1998) o **Thorp** (1967, solo
frecuencia); los dos primeros coinciden en ~10 % entre 100 Hz y 1 MHz.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# 10 kHz a 10 °C, 35 ppt y 100 m de profundidad; ensanchamiento "practical" con R0 = 1000 m.
ranges = np.linspace(10.0, 20_000.0, 400)
tl = underwater.transmission_loss(ranges, 10e3, law="practical",
                                  transition_range=1000.0, temperature=10.0,
                                  salinity=35.0, depth=100.0)
print(f"alpha = {tl.absorption_coefficient:.2f} dB/km")   # alpha = 0.95 dB/km
tl.plot(language="es")   # TL total con las contribuciones de ensanchamiento y absorción
plt.show()
```

</details>

```python

from phonometry import underwater

ranges = np.linspace(10.0, 20_000.0, 400)
tl = underwater.transmission_loss(ranges, 10e3, law="practical", transition_range=1000.0,
                          temperature=10.0, salinity=35.0, depth=100.0)
print(tl.absorption_coefficient, tl.tl[-1])
tl.plot()   # TL frente a distancia con la separación ensanchamiento/absorción
```

## Velocidad del sonido en agua de mar

`sea_water_sound_speed(T, S, depth, model=…)` usa la ecuación **UNESCO /
Chen–Millero** (por defecto, en la forma Wong & Zhu 1995 ITS-90), **Del Grosso**
(1974) o **Mackenzie** (1981). La profundidad se convierte a presión con
Leroy & Parthiot (1998). Las tres coinciden en ~1 m/s; el valor de verificación
canónico de Mackenzie es `1550,744 m/s` a 25 °C, 35 ‰, 1000 m.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Capa de mezcla cálida, termoclina hasta 4 °C y capa profunda isoterma.
depths = np.linspace(0.0, 3000.0, 121)
temps = 4.0 + 14.0 / (1.0 + (np.maximum(depths - 80.0, 0.0) / 250.0) ** 2)
profile = underwater.sound_speed_profile(depths, temps, 35.0, model="unesco")
profile.plot(language="es")   # velocidad del sonido frente a profundidad, mínimo en el eje del canal
plt.show()
```

</details>

```python

from phonometry import underwater

c = underwater.sea_water_sound_speed(25.0, 35.0, 1000.0, model="mackenzie")  # 1550,744
depths = np.linspace(0.0, 3000.0, 121)
temps = 4.0 + 14.0 / (1.0 + (np.maximum(depths - 80.0, 0.0) / 250.0) ** 2)
profile = underwater.sound_speed_profile(depths, temps, 35.0, model="unesco")
profile.plot()   # velocidad del sonido frente a profundidad
```

El mínimo de $c(z)$ actúa como una guía de ondas (el canal SOFAR): los frentes
de onda que se apartan del eje se refractan de vuelta hacia él, mientras que
el sonido generado fuera del canal se fuga hacia el fondo, como muestra la
simulación siguiente con un gradiente exagerado a propósito. Este atrapamiento
es la razón de que el sonido de baja frecuencia pueda cruzar océanos enteros.

## Ecuación del sonar

La ecuación del sonar da el **exceso de señal** $SE$ (detección cuando
$SE \ge 0$) y la **figura de mérito** (la máxima pérdida por transmisión
admisible en $SE = 0$):

$$
SE = SL - TL - (NL - DI) - DT \ \ \text{(pasiva)},
$$

$$
SE = SL - 2\,TL + TS - (NL - DI) - DT \ \ \text{(activa, monostática)},
$$

o limitada por reverberación con $RL$ en lugar de $NL - DI$.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

tl = np.linspace(40.0, 120.0, 400)
se = underwater.passive_sonar_equation(source_level=140.0, transmission_loss=tl,
                                       noise_level=60.0, directivity_index=15.0,
                                       detection_threshold=8.0)
print(f"figura de mérito = {se.figure_of_merit:.1f} dB")  # figura de mérito = 87.0 dB
se.plot(language="es")   # exceso de señal frente a pérdida por transmisión, cruce por cero en la FOM
plt.show()
```

</details>

```python

from phonometry import underwater

tl = np.linspace(40.0, 120.0, 400)
se = underwater.passive_sonar_equation(source_level=140.0, transmission_loss=tl,
                               noise_level=60.0, directivity_index=15.0,
                               detection_threshold=8.0)
print(se.figure_of_merit)
se.plot()   # exceso de señal frente a pérdida por transmisión
```

Los niveles de sonar, propagación y ambiental están en dB re una onda plana de
1 µPa rms (niveles espectrales). Los niveles de fuente (más abajo) usan la
convención de fuente, dB re 1 µPa²/Hz **a 1 m**.

## Pérdida por reflexión en el fondo

Una onda plana que incide en el fondo se refleja con el **coeficiente de
reflexión de Rayleigh** fluido–fluido (Medwin & Clay). Para un fondo más rápido ($c_2 > c_1$)
existe un **ángulo rasante crítico** $\varphi_c = \arccos(c_1/c_2)$, por
debajo del cual la onda se refleja totalmente ($|R| = 1$, pérdida nula). La
pérdida es $BL = -20 \lg |R|$.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Reflexión de Rayleigh fluido-fluido: agua sobre un fondo arenoso rápido.
phi = np.linspace(0.0, 90.0, 361)
bl = underwater.bottom_reflection_loss(phi, rho1=1000.0, c1=1500.0,
                                       rho2=1900.0, c2=1650.0)
print(f"ángulo crítico = {bl.critical_angle:.1f} deg")   # ángulo crítico = 24.6 deg
bl.plot(language="es")   # pérdida en el fondo frente al ángulo rasante
plt.show()
```

</details>

```python

from phonometry import underwater

phi = np.linspace(0.0, 90.0, 361)   # ángulo rasante desde la interfaz, grados
bl = underwater.bottom_reflection_loss(phi, rho1=1000.0, c1=1500.0,   # agua
                               rho2=1900.0, c2=1650.0)          # arena
print(bl.critical_angle)            # 24,6°
bl.plot()   # pérdida por reflexión frente al ángulo rasante
```

El complemento `seabed_reflection` agrupa el `reflection_coefficient` complejo,
su `magnitude` $|R|$, el `bottom_loss` (dB) y los parámetros de la interfaz en un
`SeabedReflection` cuyo `.plot()` dibuja directamente el módulo del coeficiente
de reflexión $|R|$ (unidad por debajo del ángulo crítico y decreciente hasta el
valor de incidencia normal a $90°$).

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Módulo del coeficiente de reflexión de Rayleigh: agua sobre un fondo arenoso rápido.
phi = np.linspace(0.0, 90.0, 361)
sr = underwater.seabed_reflection(phi, rho1=1000.0, c1=1500.0,
                                  rho2=1900.0, c2=1650.0)
print(f"|R| en incidencia normal = {sr.magnitude[-1]:.3f}")  # 0.353
sr.plot(language="es")   # módulo del coeficiente de reflexión frente al ángulo rasante
plt.show()
```

</details>

```python

from phonometry import underwater

phi = np.linspace(0.0, 90.0, 361)   # ángulo rasante desde la interfaz, grados
sr = underwater.seabed_reflection(phi, rho1=1000.0, c1=1500.0,   # agua
                          rho2=1900.0, c2=1650.0)          # arena
print(sr.magnitude[-1])             # 0,353 = |R| en incidencia normal
sr.plot()   # |R| frente al ángulo rasante (necesita matplotlib)
```

## Ruido ambiental oceánico

El nivel espectral de ruido ambiental es la suma energética de las componentes
físicas de Wenz: el ruido de **viento / superficie** por la "regla de los cincos"
(el ancla histórica de 25 dB a 1 kHz con 5 nudos es re 20 µPa, es decir ~51 dB
re 1 µPa; válida en ~500 Hz–5 kHz) y el ruido **térmico de
Mellen** (dominante por encima de ~50 kHz). El rango amplio del ejemplo mantiene
la curva de viento más allá de ~5 kHz solo como extrapolación para mostrar el
cruce con el térmico. El espectro de **tráfico** lo aporta quien llama.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Ruido ambiental de Wenz (regla de los cincos + térmico de Mellen) a dos vientos.
freqs = np.logspace(2, 5.5, 300)
fig, ax = plt.subplots()
for u in (5.0, 20.0):
    noise = underwater.ocean_ambient_noise(freqs, wind_speed_knots=u)
    ax.semilogx(noise.frequency, noise.spectrum_level, label=f"Total ({u:.0f} kn)")
ax.semilogx(freqs, underwater.thermal_noise_spectrum(freqs), ":", label="Térmico")
ax.set(xlabel="Frecuencia [Hz]", ylabel="Nivel espectral [dB re 1 µPa²/Hz]")
ax.legend()
ax.grid(True, which="both", alpha=0.3)
plt.show()
```

</details>

```python

from phonometry import underwater

freqs = np.logspace(2, 5.5, 300)
noise = underwater.ocean_ambient_noise(freqs, wind_speed_knots=15.0)
noise.plot()   # espectro compuesto con las componentes viento/térmico
```

## Nivel de fuente del tráfico marítimo

Cuando no hay espectro medido, el nivel de fuente de un buque puede
**estimarse** a partir de su clase, velocidad y eslora con **JOMOPANS-ECHO**
(MacGillivray & de Jong 2021, por defecto, validado contra 1862 medidas),
**RANDI 3.1** o **Wales & Heitmeyer** (2002).

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Espectros de fuente JOMOPANS-ECHO para tres clases de buque (velocidad, eslora).
fig, ax = plt.subplots()
for vessel_class, speed, length in (("containership", 18.0, 300.0),
                                    ("cruise", 17.1, 250.0),
                                    ("tug", 3.7, 30.0)):
    s = underwater.ship_source_spectrum(speed, length, vessel_class=vessel_class)
    ax.semilogx(s.frequency, s.source_psd,
                label=f"{vessel_class} ({speed:.0f} kn, {length:.0f} m)")
ax.set(xlabel="Frecuencia [Hz]",
       ylabel="Densidad espectral de fuente [dB re 1 µPa²/Hz a 1 m]")
ax.legend()
ax.grid(True, which="both", alpha=0.3)
plt.show()
```

</details>

```python
from phonometry import underwater

ship = underwater.ship_source_spectrum(18.0, 300.0, vessel_class="containership")
ship.plot()                     # densidad espectral de fuente frente a frecuencia
print(underwater.VESSEL_CLASSES)        # las 13 clases de buque de JOMOPANS-ECHO

# Alimenta la predicción al ruido ambiental como término de tráfico:
noise = underwater.ocean_ambient_noise(ship.frequency, wind_speed_knots=10.0,
                               shipping=ship.source_psd)
```

## Solvers numéricos

Para entornos independientes de la distancia el campo puede calcularse
numéricamente con tres solvers (Jensen et al., *Computational Ocean Acoustics*):

- **`normal_modes`**: el problema de autovalores de Sturm-Liouville separado en
  profundidad, resuelto por diferencias finitas y sumado en pérdida por
  transmisión (validado contra los modos exactos de la guía ideal).
- **`ray_trace`**: las ecuaciones de trayectoria de rayos integradas con
  Runge-Kutta, vectorizadas sobre todos los rayos a la vez (validado contra los
  arcos de círculo de un gradiente lineal).
- **`parabolic_equation`**: la PE estándar (Tappert) por el algoritmo split-step
  de Fourier (validado contra el esparcimiento esférico en campo libre).

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import underwater

# Un perfil de Munk de velocidad del sonido en aguas profundas.
z = np.linspace(0.0, 5000.0, 60)
eta = 2.0 * (z - 1300.0) / 1300.0
c = 1500.0 * (1.0 + 0.00737 * (eta - 1.0 + np.exp(-eta)))

# PE split-step de Fourier a 50 Hz; una malla gruesa mantiene el cálculo rápido.
field = underwater.parabolic_equation(50.0, z, c, source_depth=1000.0,
                                      max_range=50_000.0, range_step=50.0,
                                      n_depth_points=512)
field.plot(language="es")   # campo TL(z, r) mostrando las zonas de convergencia
plt.show()
```

</details>

```python

from phonometry import underwater

z = np.linspace(0.0, 5000.0, 60)
eta = 2.0 * (z - 1300.0) / 1300.0
c = 1500.0 * (1.0 + 0.00737 * (eta - 1.0 + np.exp(-eta)))   # perfil de Munk
underwater.ray_trace(z, c, source_depth=1000.0,
             launch_angles_deg=np.linspace(-12, 12, 21), max_range=100e3).plot()

modes = underwater.normal_modes(50.0, [0.0, 200.0], [1500.0, 1500.0],
                        source_depth=50.0, receiver_depth=100.0)
underwater.parabolic_equation(50.0, [0.0, 200.0], [1500.0, 1500.0],
                      source_depth=50.0, max_range=20e3).plot()
```

Los tres asumen una columna de agua independiente de la distancia con superficie
de presión-liberada.

## Elegir modelo

Todas las funciones anteriores responden a la misma pregunta, "cuánto nivel
sobrevive al camino", a distinto precio en física. La terminología sigue en
toda la página la ISO 18405:2017 (pérdida por propagación, nivel de fuente,
niveles re 1 µPa).

**Velocidad del sonido.** Las tres ecuaciones coinciden a menos de 1 m/s
dentro de su dominio común, así que la elección va de *rango de validez*, no
de exactitud. La forma **UNESCO / Chen-Millero** por defecto (en la
reformulación de Wong y Zhu de 1995) cubre de 0 a 40 °C, de 0 a 40 ppt y de 0
a 1000 bar, la envolvente más amplia, y es el estándar internacional.
**Del Grosso** (1974) queda restringida a 0-30 °C y 30-40 ppt, pero algunos
autores la prefieren para trabajo de océano profundo dentro de ese dominio
(buena parte de la literatura del canal SOFAR la usa). **Mackenzie** (1981)
cambia presión por profundidad directamente (2-30 °C, 25-40 ppt, 0-8000 m),
lo que la convierte en la opción cómoda cuando se dispone de una profundidad
de ecosonda y no de una presión de CTD; las otras dos convierten profundidad a
presión internamente mediante Leroy y Parthiot (1998).

**Absorción.** **Francois-Garrison** (1982) es la referencia y el valor por
defecto: incorpora las relajaciones del ácido bórico, el sulfato de magnesio y
el agua pura con sus dependencias completas de temperatura, salinidad y
profundidad, y es fiable desde unos 100 Hz hasta 1 MHz. **Ainslie-McColm**
(1998) es una simplificación deliberada de la misma física que se mantiene a
menos de un 10 % de ella en ese rango; úsese cuando una fórmula legible
importe más que el último punto porcentual. **Thorp** (1967) depende solo de
la frecuencia (lleva incorporada agua a 4 °C cerca de 1000 m) y es anterior a
ambas; resérvese para estimaciones rápidas de baja frecuencia por debajo de
unas decenas de kHz y para comparar con literatura antigua que la usó.

**Ley de ensanchamiento.** El ensanchamiento esférico ($20\lg R$) describe un
frente de onda que se expande libremente en tres dimensiones, antes de que
ningún contorno lo confine; el cilíndrico ($10\lg R$) describe energía
atrapada entre la superficie y el fondo (o en el canal SOFAR) que solo puede
expandirse en distancia. La ley `"practical"` empalma ambos en una distancia
de transición $R_0$, físicamente del orden de la profundidad del agua (o del
canal): esférico mientras el frente no ha llenado el conducto, cilíndrico
cuando ya lo ha hecho. En el ejemplo de 10 kHz de arriba la elección no es
cosmética: frente a la misma figura de mérito de 87 dB, el ensanchamiento
solo esférico predice detección hasta unos 8,7 km, mientras que la ley
práctica con $R_0 = 1000$ m la estira hasta unos 15,8 km. Cuando la ley de
ensanchamiento es la mayor incertidumbre del presupuesto, esa es la señal de
dejar la forma cerrada y calcular el campo.

**¿Forma cerrada o solver?** La pérdida por transmisión en forma cerrada no
sabe nada del perfil de velocidad del sonido, del fondo ni de la superficie;
es honesta para caminos cortos, directos y sin contornos, y para presupuestos
de sonar de primera pasada. Cuando la refracción y los contornos deciden la
respuesta, elíjase el solver por frecuencia y geometría (Jensen et al. 2011,
cap. 1):

| Solver | Régimen natural | Qué aporta |
|---|---|---|
| `ray_trace` | Alta frecuencia (profundidad ≫ λ), océano profundo | Geometría de eigenrayos, tiempos de propagación, zonas de convergencia; coste independiente de la frecuencia |
| `normal_modes` | Baja frecuencia, aguas someras, independiente de la distancia | Suma modal por diferencias finitas con pocos modos propagantes ($m < kD/\pi$); la solución de referencia en su régimen, validada frente a los modos exactos de la guía de ondas ideal |
| `parabolic_equation` | Baja frecuencia, caminos largos de un solo sentido | TL($z$,$r$) de campo completo con refracción, marchada en distancia sobre el $c(z)$ independiente de la distancia que asumen los tres solvers |

En la práctica las fronteras se difuminan: los rayos siguen siendo útiles a
frecuencias sorprendentemente bajas para trabajo de tiempos de propagación, y
la PE sigue siendo el caballo de batalla bastante por encima de su régimen
formal de ángulos pequeños. Cuando dos de los tres coinciden en un caso, como
hacen los modos y la PE en la figura de arriba, esa coincidencia es la prueba
práctica de convergencia.

**Un presupuesto de sonar resuelto.** Encadenando las piezas de punta a
punta: una fuente de 140 dB re 1 µPa²/Hz a 10 kHz, un nivel espectral de
ruido ambiental de 60 dB, una ganancia de array de 15 dB y un umbral de
detección de 8 dB dan la figura de mérito
$FOM = 140 - (60 - 15) - 8 = 87$ dB que calcula `passive_sonar_equation`
arriba. La curva de pérdida por transmisión de la primera sección (10 °C,
35 ppt, 100 m, $\alpha = 0,95$ dB/km) cruza los 87 dB hacia los 15,8 km con
la ley práctica: ese cruce *es* la distancia de detección predicha, y cada
término del presupuesto lo mueve. Recórtese el índice de directividad a
7,5 dB y la figura de mérito cae a 79,5 dB, así que la distancia baja a donde
la curva de TL cruce ese valor; dóblese la frecuencia a 20 kHz y $\alpha$ más que
se triplica hasta 3,3 dB/km, tirando del cruce bruscamente hacia dentro.
Este acoplamiento entre el modelo de absorción, la ley de ensanchamiento y la
ecuación del sonar es la razón de que los tres vivan en un mismo módulo.

## Qué cubre esta guía

**Cubierto.** La terminología de la ISO 18405:2017 (pérdida por propagación,
nivel de fuente, niveles re 1 µPa) sustenta cada magnitud de esta página.
`transmission_loss` y `seawater_absorption` implementan el ensanchamiento
geométrico más los modelos de absorción de Francois-Garrison (1982, por
defecto), Ainslie-McColm (1998) y Thorp (1967). `sea_water_sound_speed` y
`sound_speed_profile` implementan las ecuaciones de velocidad del sonido
UNESCO/Chen-Millero (forma ITS-90 de Wong y Zhu de 1995, por defecto), Del
Grosso (1974) y Mackenzie (1981), con la conversión de profundidad a presión
de Leroy y Parthiot (1998). `passive_sonar_equation` y
`active_sonar_equation` implementan las ecuaciones del sonar pasivo y activo
monostático (Urick, vía Etter 2003). `seabed_reflection` y
`bottom_reflection_loss` implementan el coeficiente de reflexión de Rayleigh
fluido-fluido y el ángulo crítico (Medwin & Clay). `ocean_ambient_noise` suma
el ruido de viento de Wenz por la "regla de los cincos" y el ruido térmico de
Mellen. `ship_source_spectrum` implementa los modelos de nivel de fuente
JOMOPANS-ECHO (por defecto), RANDI 3.1 y Wales & Heitmeyer (2002).
`normal_modes`, `ray_trace` y `parabolic_equation` implementan los solvers
numéricos de Jensen et al. (2011).

**No cubierto.** El modelo de fondo es solo reflexión de Rayleigh
fluido-fluido sin pérdidas, así que la atenuación del sedimento queda fuera
de alcance. `normal_modes`, `ray_trace` y `parabolic_equation` asumen una
columna de agua independiente de la distancia con un contorno de
presión-liberada o rígido únicamente, no un fondo absorbente o elástico, así
que la batimetría real no se modela. `active_sonar_equation` es solo
monostática: no hay geometría biestática. `ocean_ambient_noise` deja fuera la
banda de turbulencia de baja frecuencia y cualquier modelo integrado de
tráfico marítimo lejano; hay que aportar un espectro de tráfico propio, por
ejemplo con `ship_source_spectrum` de arriba.

## Véase también

- Referencia de la API: [`underwater.propagation`](/phonometry/es/reference/api/underwater/propagation/), [`underwater.numerical_propagation`](/phonometry/es/reference/api/underwater/numerical-propagation/) y [`underwater.sound_speed`](/phonometry/es/reference/api/underwater/sound-speed/).
