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

Esta página calcula en forma cerrada lo que el mar le hace a un nivel sonoro,
sin simular ningún campo. Al terminarla sabrás poner un número a la pérdida de
propagación de un trayecto, elegir los modelos de absorción y de velocidad del
sonido que le convienen a tu agua, seguir los cuatro regímenes de aguas someras
de Weston conforme el lecho marino le va quitando el mando a la geometría,
equilibrar una ecuación del sonar pasiva o activa e invertirla para obtener un
alcance de detección, evaluar la pérdida por reflexión en el fondo que fija esos
regímenes y construir un espectro de ruido ambiental con los términos de viento,
térmico y de tráfico marítimo. Los niveles de referencia en que se expresa cada
resultado están en la página de
[Acústica submarina](/phonometry/es/underwater/underwater-acoustics/); cuando la
refracción y los contornos deciden la respuesta, toman el relevo los
[métodos numéricos](/phonometry/es/underwater/underwater-solvers/).

<span id="perdida-de-propagacion"></span>

## Pérdida de propagación

**Son dos magnitudes, y la ISO 18405 las mantiene separadas.** La *pérdida de
propagación* $N_\mathrm{PL}$ es la diferencia entre el nivel de fuente en una
dirección especificada y el nivel de presión acústica cuadrático medio en una
posición especificada, $N_\mathrm{PL}(x) = L_\mathrm{S} - L_p(x)$, referida a 1 m²
(apartado 3.4.1.4). La *pérdida por transmisión* $\Delta L_\mathrm{TL}$ es la
reducción de un nivel especificado entre dos puntos especificados (apartado
3.4.1.3). La ecuación del sonar necesita la magnitud referida a la fuente, así
que lo que esta página calcula es una pérdida de propagación, y así se llama la
función. La norma desaconseja usar cualquiera de los dos nombres como sinónimo
del otro, en las dos direcciones, y por eso buena parte de la literatura llama a
esta magnitud pérdida por transmisión y esta biblioteca ha dejado de hacerlo.
Cualquiera de las dos magnitudes hay que declararla con el tiempo de promediado
y el margen de frecuencia a los que se aplica. Los regímenes de Weston de más
abajo son la misma magnitud en el mismo eje.

La pérdida de propagación es

$$
PL = \text{divergencia} + \alpha R .
$$

La divergencia geométrica es $20 \log_{10} R$ (esférico), $10 \log_{10} 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** (`model="francois-garrison"`, 1982, el valor
por defecto y la referencia), **Ainslie-McColm** (`"ainslie-mccolm"`, 1998) o
**Thorp** (`"thorp"`, 1967, solo frecuencia); los dos primeros coinciden
dentro de un ~10 % entre 100 Hz y 1 MHz.

*Los dos términos se intercambian los papeles con la distancia, y por eso se
dibujan aparte. Hasta la transición de 1 km la pérdida es divergencia y casi
nada más: 61,0 dB en total frente a 60,1 dB de divergencia. Pasada la
transición, la ley de divergencia se reduce a la mitad, $10\lg R$, y el término
$\alpha R$ toma el relevo del crecimiento: a 20 km, los 92,0 dB totales son
73,0 dB de divergencia más 19,0 dB de absorción a 0,95 dB/km. A 10 kHz la
absorción no llega a superar a la divergencia en todo este intervalo; a 100 kHz
lo habría hecho dentro del primer kilómetro.*

<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; divergencia "practical" con R0 = 1000 m.
ranges = np.linspace(10.0, 20_000.0, 400)
pl = underwater.propagation_loss(ranges, 10e3, law="practical",
                                  transition_range=1000.0, temperature=10.0,
                                  salinity=35.0, depth=100.0)
print(f"alpha = {pl.absorption_coefficient:.2f} dB/km")   # alpha = 0.95 dB/km
pl.plot(language="es")   # PL total con las contribuciones de divergencia y absorción
plt.show()
```

</details>

```python

from phonometry import underwater

ranges = np.linspace(10.0, 20_000.0, 400)
pl = underwater.propagation_loss(ranges, 10e3, law="practical", transition_range=1000.0,
                          temperature=10.0, salinity=35.0, depth=100.0)
print(round(pl.absorption_coefficient, 3), round(float(pl.pl[-1]), 1))
# 0.95 dB/km, 92.0 dB a 20 km

# El mismo caso con los otros dos modelos de absorción, para que la
# afirmación de concordancia de arriba sea comprobable y no un enunciado:
for model in ("ainslie-mccolm", "thorp"):
    other = underwater.propagation_loss(ranges, 10e3, law="practical",
                              transition_range=1000.0, temperature=10.0,
                              salinity=35.0, depth=100.0, model=model)
    print(model, round(other.absorption_coefficient, 3))   # 0.973 / 1.15

pl.plot()   # PL frente a distancia con la separación divergencia/absorción
```

Dos argumentos de esa llamada deciden más de lo que parece. `depth` es solo la
profundidad a la que se evalúa el coeficiente de absorción (una profundidad
representativa del trayecto, porque $\alpha$ cae con la presión) y **no** es la
profundidad del agua ni fija la ley de divergencia. $R_0$ es la distancia a la
que el frente de onda ha llenado el conducto, así que es del orden de la
profundidad del agua en una guía somera, o del espesor del canal en un conducto
SOFAR: un canal de 100 m pide un $R_0$ cercano a 100 m, no los 1 km usados
arriba, que corresponden a un trayecto de aguas profundas. La elección no es
cosmética. Frente a la figura de mérito de 87 dB que se trabaja más abajo, la
divergencia solo esférica sitúa la detección en 8,7 km y la ley práctica con
$R_0 = 1000$ m en 15,8 km: el mismo océano, siete kilómetros de diferencia.

El modelo de absorción importa menos, y vale la pena ver cuánto menos.

*Ainslie-McColm se queda dentro del ±10 % de la referencia de
Francois-Garrison en toda la banda, que es lo que lo hace un sustituto legítimo.
Thorp no: va un 20 % alto por debajo de unos pocos cientos de hercios y se
desploma por encima de ~60 kHz, porque es un ajuste solo en frecuencia con agua
a 4 °C cerca de 1000 m cocido dentro y sin temperatura, salinidad ni
profundidad que darle.*

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

```python

freqs = np.logspace(1.0, 6.0, 500)
env = {"temperature": 10.0, "salinity": 35.0, "depth": 100.0}
alpha = {m: np.asarray(underwater.seawater_absorption(freqs, model=m, **env))
         for m in ("francois-garrison", "ainslie-mccolm", "thorp")}

fig, (ax_a, ax_r) = plt.subplots(1, 2, figsize=(13.5, 5.4))
for name, style in (("francois-garrison", "-"), ("ainslie-mccolm", "--"),
                    ("thorp", ":")):
    ax_a.loglog(freqs, alpha[name], style, label=name)
    if name != "francois-garrison":
        ax_r.semilogx(freqs, 100.0 * (alpha[name] / alpha["francois-garrison"] - 1.0),
                      style, label=name)
ax_a.set(xlabel="Frecuencia [Hz]", ylabel="alpha [dB/km]")
ax_r.set(xlabel="Frecuencia [Hz]", ylabel="Desviación respecto a Francois-Garrison [%]",
         ylim=(-70, 90))
for ax in (ax_a, ax_r):
    ax.grid(True, which="both", alpha=0.3)
    ax.legend()
plt.show()
```

</details>

<span id="regimenes-de-aguas-someras-de-weston"></span>

### Regímenes de aguas someras de Weston

Fijar a mano la ley de divergencia funciona en mar abierto, pero en aguas
someras la ley *cambia con la distancia* a medida que el fondo toma el mando.
La teoría de flujo de energía de Weston, tal como la expone Ainslie §9.1.1.2,
deriva los cuatro regímenes sucesivos y las distancias en que se relevan, solo
a partir de la reflectividad del fondo:

| Régimen | Factor de propagación $F$ | Ley de pérdida | Termina en |
|---|---|---|---|
| Esférico | $1/r^2$ | $20 \log_{10} r$ | $r = H/(2\psi_\mathrm{c})$ |
| Cilíndrico | $2\psi_\mathrm{c}/(rH)$ | $10 \log_{10} r$ | $r_\mathrm{CS} = \pi H/(4\eta\psi_\mathrm{c}^2)$ |
| Descamado de modos | $\sqrt{\pi/(\eta H)}\, r^{-3/2}$ | $15 \log_{10} r$ | $r_\mathrm{MS} = k^2 H_\mathrm{e}^3/(9\pi\eta)$ |
| Modo único | Ec. (9.54), exponencial | más pronunciada que $15 \log_{10} r$ | — |

Aquí $r$ es la distancia, $H$ la profundidad del agua, $k = 2\pi f/c_1$ el
número de onda acústico en la columna de agua, $\psi_\mathrm{c} = \arccos(c_1/c_2)$ el
ángulo rasante crítico que fijan las velocidades del sonido del agua y del
sedimento, $\eta$ el **gradiente de pérdida por reflexión** en neperios por
radián ($|R(\theta)| \approx e^{-\eta\theta}$) y $H_\mathrm{e}$ la **profundidad efectiva
de Weston**: el nivel poco *por debajo* del fondo real en el que parece situarse
un contorno de presión nula, de modo que $H_\mathrm{e} > H$ y las dos letras no son
intercambiables (que es todo el contenido de la nota de errata de más abajo).

`weston_propagation_loss` compone la pérdida y devuelve además la ley propia de
cada régimen; el campo `boundaries` lleva las tres distancias de transición
junto con la frecuencia de corte de la guía de ondas y el número de modos
propagantes. Lo que devuelve es una **pérdida por propagación**
$PL = -10\log_{10} F$: el cociente incoherente, promediado en distancia, entre
las presiones cuadráticas medias recibida y de fuente, con el término de
absorción sumado aparte. Para las geometrías de esta página es directamente
comparable con la pérdida de propagación de arriba y con el resultado modal
promediado en profundidad (la diferencia entre las dos magnitudes de la
ISO 18405 es la convención de distancia de referencia, no la física), y por eso
ambas se dibujan en el mismo eje.

*Aquí no se ha elegido nada: las tres transiciones en 42,7 m, 411,8 m y 20,1 km
salen del lecho marino y de nada más, a través del ángulo crítico de 33,6° y del
gradiente de pérdida por reflexión de 0,278 Np/rad de la arena media con 50 m de
columna de agua. La compuesta es la envolvente inferior de las cuatro leyes a
trazos, así que la pérdida se empina por etapas: 32,6 dB en la primera frontera,
42,4 dB en la segunda y 67,7 dB en la tercera. La arena es la razón de que los
dos regímenes intermedios existan siquiera: un lecho más duro aleja las
transiciones y uno más blando descama los modos antes.*

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

```python

from phonometry import underwater

# 50 m de agua sobre arena media (Ainslie Tabla 9.1) a 250 Hz.
ranges = np.logspace(1.0, 5.3, 500)
res = underwater.weston_propagation_loss(ranges, 250.0, 50.0, seabed="sand",
                                         source_depth=10.0, receiver_depth=25.0)
b = res.boundaries
print(f"psi_c = {np.degrees(b.critical_angle):.1f} grados, eta = {b.reflection_loss_gradient:.2f} Np/rad")
res.plot(language="es")   # pérdida compuesta con la ley de cada régimen y las fronteras
plt.show()
```

</details>

```python
from phonometry import underwater

b = underwater.weston_regime_boundaries(250.0, 50.0, seabed="sand")
print(b.cylindrical_to_mode_stripping)   # r_CS, en metros
print(b.cutoff_frequency, b.mode_count)  # la propagación guiada exige f > f_c
print(underwater.reflection_loss_gradient("sand"))   # 0.278 Np/rad
```

Al ser un resultado *incoherente*, el flujo describe el campo promediado en
distancia, y eso es justo lo que lo convierte en referencia para los
[métodos numéricos de propagación
submarina](/phonometry/es/underwater/underwater-solvers/).
Con el ángulo crítico a 90° y el gradiente de pérdida a cero, la rama cilíndrica
se reduce a $F = \pi/(rH)$, el límite exacto de muchos modos de una guía ideal;
la pérdida por modos normales promediada en profundidad y distancia cae sobre
ella dentro de un decibelio.

:::note
La Ecuación (9.57) impresa por Ainslie para $r_\mathrm{MS}$ dice $k^2H_\mathrm{e}^3/(9\eta)$.
Su propia regla de derivación, igualar las Ecuaciones (9.47) y (9.56) tal como
están impresas, da $k^2H_\mathrm{e}^2H/(9\pi\eta)$, menor en $\pi H_\mathrm{e}/H$. La biblioteca
implementa la forma coherente con la derivación; véase
[Erratas encontradas en fuentes publicadas](/phonometry/es/reference/errata/).
:::

## Velocidad del sonido en agua de mar

`sea_water_sound_speed(T, S, depth, model=…)` usa la ecuación **UNESCO /
Chen-Millero** (`model="unesco"`, el valor por defecto, en la forma Wong & Zhu
1995 ITS-90), **Del Grosso** (`"del_grosso"`, fíjate en el guion bajo, al
contrario que en los modelos de absorción de arriba, con guion), **Mackenzie**
(`"mackenzie"`) o **Medwin** (`"medwin"`), todas de 1974-1981. La profundidad se
convierte a
presión con Leroy & Parthiot (1998). **Dentro del dominio que comparten las
cuatro, coinciden dentro de 1 m/s**: 0,98 m/s a 25 °C, 35 ‰ y 1000 m, y
0,52 m/s en todo el kilómetro superior del perfil dibujado más abajo, así que la
elección va de rango de validez, no de exactitud. El valor de verificación
canónico de Mackenzie es 1550,744 m/s a 25 °C, 35 ‰, 1000 m. La forma de seis
términos de Medwin es la más basta de la familia y la que está detrás de las
reglas clásicas $\partial c/\partial T \approx 4.6 - 0.110\,T$ m/s por °C y
$\partial c/\partial z \approx 0.016$ m/s por metro; está ajustada hasta unos
1000 m en aguas someras y cálidas, y llevada a 5000 m se separa de las otras
casi 6 m/s, que es el único desacuerdo grande de la familia y es por entero
cuestión de usarla fuera de su dominio.

*Por encima del eje manda la temperatura y por debajo la presión, y el punto de
retorno es el canal sonoro. En este perfil la velocidad cae de 1515,79 m/s en la
superficie a un mínimo de 1486,05 m/s a 775 m, donde el agua ya ha alcanzado su
temperatura profunda, y vuelve a subir hasta 1517,85 m/s a 3000 m solo por
presión, en agua isoterma. Toda la excursión son 32 m/s, alrededor del 2 %, que
es la razón de que en el océano profundo sea la refracción, y no la absorción,
la que decide adónde va el sonido.*

<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
```

*A la escala del perfil las cuatro ecuaciones son una sola curva. El panel de
diferencias es el útil: Del Grosso y Mackenzie se quedan dentro de 0,85 m/s de
UNESCO en toda la columna, y las cuatro dentro de 0,52 m/s hasta 1000 m. La
única desviación grande es la de Medwin por debajo de su propio límite de
validez, que es un error de dominio y no un desacuerdo entre modelos.*

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

```python

depths = np.linspace(0.0, 5000.0, 251)
temps = 4.0 + 14.0 / (1.0 + (np.maximum(depths - 80.0, 0.0) / 250.0) ** 2)
models = ("unesco", "del_grosso", "mackenzie", "medwin")
profiles = {m: np.asarray(underwater.sound_speed_profile(
    depths, temps, 35.0, model=m).sound_speed) for m in models}

fig, (ax_c, ax_d) = plt.subplots(1, 2, figsize=(13.0, 6.2))
for m in models:
    ax_c.plot(profiles[m], depths, label=m)
    if m != "unesco":
        ax_d.plot(profiles[m] - profiles["unesco"], depths, label=m)
ax_d.axhspan(1000.0, 5000.0, color="0.9", zorder=0)   # Medwin fuera de dominio
for ax in (ax_c, ax_d):
    ax.invert_yaxis()
    ax.grid(True, alpha=0.3)
    ax.legend()
ax_c.set(xlabel="Velocidad del sonido c [m/s]", ylabel="Profundidad [m]")
ax_d.set(xlabel="Diferencia respecto a UNESCO [m/s]", ylabel="Profundidad [m]",
         xlim=(-7, 7))
plt.show()
```

</details>

### De dónde salen los números

Cada fragmento de código de esta página lleva su océano escrito a mano, y una
campaña no. La temperatura, la salinidad y la profundidad que consumen
`sea_water_sound_speed` y `sound_speed_profile` salen de un **lance de CTD**
tomado cerca de la campaña tanto en el tiempo como en el espacio; el sustituto
habitual es un XBT con una salinidad supuesta, y el apartado 8.1.3 de la
ISO 18406 incluye el perfil de velocidad del sonido entre los datos auxiliares
que registra una campaña precisamente por esto. Qué modelo le conviene a qué
sensor se deduce de ahí: Mackenzie toma la profundidad directamente, así que le
va bien una profundidad de ecosonda, mientras que UNESCO y Del Grosso convierten
por dentro la profundidad a presión mediante Leroy & Parthiot.

Los parámetros del fondo tampoco son constantes libres. La clase de `seabed` de
los regímenes de Weston y la $\rho_2$, $c_2$ de la reflexión de Rayleigh salen
de una muestra por draga o de una campaña de sísmica somera, y el esquema de
clasificación empleado hay que declararlo con el resultado (Folk o similar, como
exige la norma de hincado). El término de viento de Wenz espera una velocidad de
viento **con su altura de medida y su periodo de promediado registrados**, no una
lectura suelta del puente; y un espectro ambiental medido solo sustituye a la
curva de Wenz donde queda claramente por encima del ruido propio del sistema de
registro, que en un sistema corriente se acerca a los niveles de estado de la
mar cero cerca de 63 Hz y 125 Hz. Por último, $NL$, $DI$ y $DT$ son propiedades
del array receptor y del detector, no del mar: vienen de la especificación del
array y de la estadística de detección, y ninguna medida oceanográfica los va a
producir.

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.

A escala oceánica real el eje del canal queda hacia los 1200 m, y las
llegadas atrapadas son rayos que ciclan en torno al mínimo de velocidad a lo
largo de decenas de kilómetros.

<span id="ecuacion-del-sonar"></span>

## 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 de propagación
admisible en $SE = 0$):

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

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

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

Esas dos formas son dos geometrías. En el caso pasivo el blanco radia y el
sonido viaja en un solo sentido; en el activo radia el sonar, el blanco
retrodispersa hacia él una fracción de lo que le llega, y la pérdida se paga dos
veces, que es la razón de que $PL$ aparezca duplicada y de que exista siquiera
el término $TS$. La reverberación no es ruido ambiental: es la propia emisión
del sonar dispersada de vuelta por la superficie, el volumen y el fondo, así
que escala con el nivel emitido y sustituye a $NL - DI$ en vez de sumarse a él.

*Una recta de pendiente −1, y su ordenada en el origen es todo el diseño. El
exceso de señal cae decibelio a decibelio con la pérdida de propagación y cruza
el cero en $FOM = SL - (NL - DI) - DT$ = 140 − (60 − 15) − 8 = 87,0 dB, así que
el sonar detecta allí donde el canal pierde menos de 87 dB y en ningún otro
sitio. Todos los términos desplazan la recta verticalmente y ninguno cambia su
pendiente: 6 dB más de ganancia de array compran exactamente 6 dB más de pérdida
admisible, que la curva de propagación convierte después en una distancia.*

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

```python

from phonometry import underwater

pl = np.linspace(40.0, 120.0, 400)
se = underwater.passive_sonar_equation(source_level=140.0, propagation_loss=pl,
                                       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 de propagación, cruce por cero en la FOM
plt.show()
```

</details>

```python

from phonometry import underwater

pl = np.linspace(40.0, 120.0, 400)
se = underwater.passive_sonar_equation(source_level=140.0, propagation_loss=pl,
                               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 de propagación
```

Los términos, una vez: $SL$ el nivel de fuente del blanco, $PL$ la pérdida de
propagación de ida, $NL$ el nivel de ruido en el receptor, $DI$ el índice de
directividad (ganancia de array), $DT$ el umbral de detección y, para la forma
activa, $TS$ la fuerza del blanco.

**Hay dos referencias en juego, y la ISO 18405 las mantiene separadas.** Los
niveles de banda y de banda ancha (el nivel ambiental en una banda, $NL$, y $SL$
tal como se usa en la ecuación del sonar) son re 1 µPa. Las *densidades
espectrales*, que es lo que devuelven `ocean_ambient_noise` y
`ship_source_spectrum`, son re 1 µPa²/Hz. Un nivel de fuente lleva además un
metro cuadrado que viene de su distancia de referencia, lo que la ISO 18405
escribe re 1 µPa²m² (equivalentemente, «dB re 1 µPa a 1 m»).

**Todos los términos tienen que referirse al mismo ancho de banda.** La ecuación
del sonar es un balance de niveles, así que mezclar un nivel de fuente de banda
ancha con un nivel *espectral* de ruido ambiental introduce un error de
$10\log_{10} B$, decenas de decibelios con cualquier ancho de banda útil, y la
función no puede detectarlo porque recibe decibelios pelados. Como los modelos
de ambiental y de tráfico marítimo de aquí son por hercio, la disciplina más
simple es trabajar por hercio en todo y dejar que el ancho de banda de proceso
entre por $DT$; la alternativa suma $10\log_{10} B$ a una señal de banda ancha
*y* al ruido (para un tono, solo al ruido, que es toda la ganancia de proceso).
El resultado del buque lleva los niveles de banda de decidécada junto a su
densidad justo para esta conversión.

La figura de mérito se expresa más abajo como «dB re m²»: Ainslie la escribe como
un *factor de propagación* máximo y no como una pérdida, y el factor de
propagación tiene unidades de m², así que el mismo número que se lee como
pérdida de propagación máxima admisible en decibelios se lee como figura de
mérito re 1 m².

### Alcance de detección

Como la figura de mérito *es* la pérdida de propagación máxima admisible,
invertir una ley de pérdida en $PL = FOM$ da el **alcance de detección**, la
distancia a la que la probabilidad de detección es del 50 %. `detection_range`
invierte la pérdida en forma cerrada de más arriba, que crece monótonamente
con la distancia y por tanto tiene un único cruce; `detection_range_from_curve`
lee el cruce sobre cualquier curva calculada, incluida la pérdida oscilante de
una guía real, donde puede haber varios.

```python
from phonometry import underwater

# Ejemplo de sonar activo CW de Ainslie: FOM = 82,7 dB re m2 a 50 kHz -> r50 ~ 1,3 km.
res = underwater.detection_range(82.7, 50e3)
print(res.detection_range)          # metros
res.plot(language="es")             # PL frente a FOM con el cruce marcado
```

Esa llamada arrastra cuatro valores por defecto implícitos: `law="spherical"`,
10 °C, 35 ‰ y profundidad de superficie, con absorción de Francois-Garrison.
Solo el supuesto de divergencia mueve la respuesta casi un factor dos, así que
es una elección que hay que tomar a propósito y no una que se hereda; y a
50 kHz, donde manda la absorción, la temperatura y la profundidad que se le
pasan tampoco son decorativas. Echa mano de `detection_range_from_curve` siempre
que la pérdida venga de un método numérico en vez de una ley.

*La pérdida en forma cerrada crece monótonamente, así que el cruce es único y
`detection_range` puede devolverlo. La pérdida de una guía real oscila: aquí la
misma figura de mérito se cruza ocho veces entre 4 y 6 km, y
`detection_range_from_curve` devuelve por defecto el **primero** de ellos,
4,4 km. La pérdida vuelve a caer por debajo de la figura de mérito hasta tan
lejos como 5,9 km, así que citar 4,4 km como «el» alcance de detección es una
convención y no un hecho, y hay que decirlo en el informe.*

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

```python

fig, (ax_c, ax_m) = plt.subplots(1, 2, figsize=(13.5, 5.4))
underwater.detection_range(82.7, 50e3).plot(ax=ax_c, language="es")

ranges = np.linspace(200.0, 6000.0, 1200)
modes = underwater.normal_modes(30.0, [0.0, 100.0], [1500.0, 1500.0],
                                source_depth=25.0, receiver_depth=60.0,
                                ranges_m=ranges, n_depth_points=800)
pl = np.asarray(modes.propagation_loss)
ax_m.plot(ranges / 1000.0, pl, label="PL de modos normales (30 Hz, 100 m)")
ax_m.axhline(60.0, linestyle="--", label="Figura de mérito = 60 dB")
print(underwater.detection_range_from_curve(60.0, ranges, pl))   # primer cruce
ax_m.invert_yaxis()
ax_m.set(xlabel="Distancia [km]", ylabel="Pérdida de propagación [dB]")
ax_m.legend()
plt.show()
```

</details>

## 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**
$\psi_\mathrm{c} = \arccos(c_1/c_2)$, el mismo $\psi_\mathrm{c}$ que fija las fronteras de los
regímenes de Weston de arriba, por debajo del cual la onda se refleja totalmente
($|R| = 1$, pérdida nula). La pérdida es $BL = -20 \log_{10} |R|$.

La reflexión total por debajo de $\psi_\mathrm{c}$ es una propiedad de la idealización
fluido-fluido **sin pérdidas**, no de ningún fondo marino real. Un sedimento
real absorbe, así que $|R|$ queda un poco por debajo de la unidad a cualquier
ángulo, y en aguas someras esa pequeña diferencia es toda la respuesta: un rayo
solo llega a larga distancia después de muchos rebotes, así que unas centésimas
de decibelio por reflexión se acumulan hasta ser la dependencia dominante con la
distancia. Esa cantidad acumulada es exactamente lo que parametriza el gradiente
de pérdida por reflexión $\eta$ de Weston. Lee las dos cosas juntas: la curva de
Rayleigh para localizar el ángulo crítico y la forma de la pérdida por encima de
él, y el gradiente de Weston cuando la pregunta es hasta dónde llega el sonido.

*Un rayo que se mantiene rasante no paga nada, y uno empinado lo paga casi todo.
Para este par de agua sobre arena el ángulo crítico es de 24,62°: por debajo la
pérdida es idénticamente nula, y un grado por encima la curva ya está subiendo,
pasando por 5,21 dB a 30°, 7,89 dB a 45° y 9,05 dB en incidencia normal. Ese
escalón es lo que convierte la propagación en aguas someras en un problema de
filtrado angular: tras unos pocos rebotes solo sobreviven los rayos
subcríticos, que es el descamado de modos que describen los regímenes de Weston.*

<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.
psi = np.linspace(0.0, 90.0, 361)
bl = underwater.bottom_reflection_loss(psi, 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

psi = np.linspace(0.0, 90.0, 361)   # ángulo rasante desde la interfase, grados
bl = underwater.bottom_reflection_loss(psi, 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 interfase 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°$).

*La misma interfase que la pérdida de arriba, leída como amplitud. $|R|$ vale
exactamente 1 hasta 24,62° y a partir de ahí cae deprisa: 0,403 a 45° y 0,353
en incidencia normal, la razón de impedancias de onda plana de los dos medios.
La idealización sin pérdidas es lo que deja plana la parte subcrítica; un
sedimento real, que absorbe, la baja unas centésimas por debajo de la unidad,
cosa invisible en este eje y término dominante al cabo de cincuenta rebotes.*

<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.
psi = np.linspace(0.0, 90.0, 361)
sr = underwater.seabed_reflection(psi, 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

psi = np.linspace(0.0, 90.0, 361)   # ángulo rasante desde la interfase, grados
sr = underwater.seabed_reflection(psi, 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)
```

### La misma interfase, como campo

Las dos curvas de arriba se leen a *un* ángulo cada vez, y al lecho marino no
se le llega nunca con un solo ángulo: una fuente radia todos los ángulos a la
vez, y cuál de ellos incide dónde es cuestión de geometría. El clip de abajo
construye esa geometría a partir de una sola ráfaga de 100 Hz a 36 m por
encima del fondo. Su frente en expansión toca el lecho justo debajo de la
fuente con $\psi = 90°$ y el punto de contacto corre después hacia fuera,
barriendo el ángulo rasante hacia abajo, a través de los 24,62° y hasta unos
pocos grados en el borde del encuadre: así se recorre entera la curva
$|R|(\psi)$, una vez, en orden y de una sola tirada. La escena se ejecuta
luego dos veces, sin cambiar nada más que los dos números que describen el
sedimento.

*Sobre la arena la transmisión termina en el rayo crítico y lo que queda en el
sedimento es una piel evanescente: brilla y no se lleva nada. Medido sobre la
propia interfase (el neto de $\int p\,v_z\,\mathrm{d}t$ por metro de lecho
marino, al que un campo evanescente no aporta nada), el neto de la arena más
allá del rayo crítico es el **−4,9 %** de lo que entró dentro de él, frente al
0 % de la forma cerrada, y el signo no es un error de redondeo: pasado el
alcance crítico el flujo neto **se invierte**, porque la onda lateral que nace
en el punto crítico corre a lo largo de la interfase por dentro del sedimento
y vuelve a radiar hacia arriba, al agua. El fango se lleva el **+28,3 %** más
allá de ese mismo alcance frente al **+29,7 %** previsto, y su curva
sencillamente sigue cayendo por la derecha del panel. Esa diferencia, pagada
otra vez en cada rebote, es lo que acumula el gradiente de pérdida por
reflexión $\eta$ de Weston.*

Dos cosas que el clip a propósito *no* enseña. En él no hay superficie del
mar: con una sola interfase la imagen tiene una familia de rayos y un solo
alcance crítico, mientras que una guía de ondas real añade una familia
reflejada en la superficie cuya imagen queda más alta y cuyo alcance crítico
propio cae más lejos. Y es un único rebote, así que el *filtrado* angular se
ve, pero la acumulación a lo largo de muchos rebotes, el descamado de modos de
la tabla de Weston, no; esa es la magnitud que $\eta$ viene a sustituir.

## 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; estrictamente 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** puede aportarlo quien llama.

La «regla de los cincos» es una regla mnemotécnica que conviene desmenuzar,
porque de ella sale toda la rama de viento: una caída de unos 5 dB por octava,
anclada en un viento de 5 nudos y 1 kHz, donde la cifra histórica es 25 dB re
20 µPa, de ahí que `ocean_ambient_noise` devuelva ahí **51 dB re 1 µPa²/Hz**.
Lee el espectro en tres bandas. Por debajo de un par de cientos de hercios, un
emplazamiento real lo domina normalmente el tráfico marítimo, que este modelo
deja a quien llama, así que ahí la curva de viento es un suelo y no una
predicción. Entre unos cientos de hercios y unos pocos kilohercios el ruido de
viento manda de verdad y el modelo se gana el sueldo: a 1 kHz da 51 dB con
5 nudos frente a 64 dB en un temporal de 30 nudos, así que la velocidad del
viento es el único mando y mueve la banda media más de una década de estado de
la mar. Por encima de decenas de kilohercios no hay quien le gane al ruido
térmico de Mellen, que fija el suelo absoluto de cualquier medida con hidrófono:
25 dB re 1 µPa²/Hz a 100 kHz, haya viento o no. Un total compuesto fuera de
aproximadamente 30-100 dB re 1 µPa²/Hz entre 100 Hz y 100 kHz es un error de
entrada y no un océano insólito.

*La regla de los cincos, medida: entre 500 Hz y 5 kHz la rama de viento cae
5,02 dB por octava, y pasar de 5 a 20 nudos la levanta 10,03 dB a 1 kHz, de
51,1 dB a 61,1 dB. Los dos mecanismos van luego en sentidos opuestos, así que el
total tiene un mínimo: el ruido térmico llega a 25,3 dB a 100 kHz y con 5 nudos
está ya a menos de 0,7 dB del total ahí, mientras que con 20 nudos sigue ganando
el viento. Nada de lo que hay en esta figura es un suelo por debajo del cual
pudiera bajar un hidrófono más silencioso: la rama térmica es el agua misma.*

<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).

*La clase, la velocidad y la eslora son las únicas entradas, y abarcan 45 dB. El
portacontenedores alcanza su máximo de 174,3 dB re 1 µPa²/Hz a 31,6 Hz, el
crucero 158,7 dB a 25,1 Hz, y el remolcador, lento y corto, 129,5 dB y más
arriba, a 125,9 Hz. De ahí salen dos cosas: la energía de la flota está por
debajo de 100 Hz, que es justo donde el modelo de viento del apartado anterior
es más flojo, y un número único de «ruido de tráfico marítimo» no significa nada
sin la clase. Estos son niveles de **fuente** a 1 m; el fragmento de más abajo
muestra lo que cuesta olvidarlo.*

<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

# `source_psd` es un nivel de FUENTE a 1 m; el término `shipping` de la suma
# ambiental es un nivel espectral RECIBIDO en la posición de escucha. La
# propagación es el paso entre ambos: aquí, ese buque a 2 km.
pl = np.array([float(underwater.propagation_loss(
    2000.0, float(f), law="practical", transition_range=1000.0).pl[0])
    for f in ship.frequency])
received = ship.source_psd - pl
noise = underwater.ocean_ambient_noise(ship.frequency, wind_speed_knots=10.0,
                               shipping=received)
print(round(float(np.interp(100.0, ship.frequency, noise.spectrum_level)), 1))
# 97.6 dB re 1 uPa^2/Hz a 100 Hz, frente a 72.7 solo con el viento. Pasar
# ship.source_psd directamente imprimiría 160.6: un nivel de fuente no es uno
# recibido, y el error es la pérdida de propagación entera.
```

Ni siquiera eso es más que una estimación de un solo buque. El ruido de
tráfico marítimo medido en un emplazamiento es la suma sobre todo el campo de
tráfico, así que un término realista integra muchos buques sobre sus
distancias y clases, que es la razón por la que `ocean_ambient_noise` deja el
espectro de tráfico a quien llama en vez de construir uno por dentro. Una sola
comprobación de plausibilidad se lleva casi todo el valor: un espectro
ambiental compuesto por encima de unos 120 dB re 1 µPa²/Hz es un error de
unidades o de geometría, no un mar ruidoso.

Todas las formas cerradas anteriores dejan de bastar cuando la refracción y
los contornos deciden la respuesta: un mínimo de velocidad del sonido que
atrapa energía, reflexiones en la superficie y el fondo en aguas someras, o
una distancia de detección que oscila con la elección de la ley de
divergencia. En ese punto el campo hay que calcularlo, y los métodos numéricos
del módulo (modos normales, trazado de rayos y ecuación parabólica), junto
con la guía para elegir entre ellos y estas formas cerradas, tienen su
propia guía:
[Métodos numéricos de propagación
submarina](/phonometry/es/underwater/underwater-solvers/).

## Qué cubre esta guía

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.
`propagation_loss` y `seawater_absorption` implementan la divergencia
geométrica 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), Mackenzie (1981) y Medwin (1975), con la conversión de
profundidad a presión de Leroy y Parthiot (1998). `weston_propagation_loss` y
`weston_regime_boundaries` implementan los cuatro regímenes de flujo de
energía de Weston y sus distancias de transición (Ainslie sección 9.1.1.2,
Tabla 9.1). `passive_sonar_equation` y `active_sonar_equation` implementan las
ecuaciones del sonar pasivo y activo monoestático (Urick, vía Etter 2003), y
`detection_range` / `detection_range_from_curve` invierten una pérdida de
propagación en la figura de mérito. `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).

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.
`active_sonar_equation` es solo monoestá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.
Los métodos numéricos del campo (`normal_modes`, `ray_trace`,
`parabolic_equation`) se cubren en [Métodos numéricos de propagación
submarina](/phonometry/es/underwater/underwater-solvers/).

## Véase también

- [Métodos numéricos de propagación submarina](/phonometry/es/underwater/underwater-solvers/):
  los métodos de modos normales, trazado de rayos y ecuación parabólica para
  los casos en que estas formas cerradas no bastan, y la guía de selección
  de modelo.
- Referencia de la API: [`underwater.propagation.closed_form`](/phonometry/es/reference/api/underwater/closed-form/) y [`underwater.propagation.sound_speed`](/phonometry/es/reference/api/underwater/sound-speed/).
