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

La **movilidad** mecánica es el cociente complejo entre una respuesta en
velocidad y la fuerza que la produce, `Y = v/F`. Es un miembro de una familia de
**funciones de respuesta en frecuencia** (FRF) movimiento-por-fuerza: cuál se usa
depende solo de si el movimiento es un desplazamiento, una velocidad o una
aceleración, y cada una tiene una recíproca fuerza-por-movimiento. La
**ISO 7626-1:2011** define la familia completa (Tabla 1, con la definición de
movilidad del 3.1.2), y el clásico resonador de un grado de libertad (SDOF) en
forma cerrada sirve de referencia para esas definiciones. La **ISO 7626-2:2015**
añade el lado de medición: la estimación de FRF a partir de señales medidas y
sus criterios de aceptación. Esta base de FRF sustenta las normas de fuente y
transmisión de ruido estructural: ISO 9611, ISO 10846, EN 15657 y EN 12354-5.

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

```python

from phonometry import vibration

m, k, c = 2.0, 8000.0, 5.0
f = np.logspace(np.log10(0.5), np.log10(200.0), 500)
w = 2.0 * np.pi * f
h = vibration.sdof_receptance(f, m, k, c)
for label, frf in (("receptancia |H|", np.abs(h)),
                   ("movilidad |Y|", np.abs(1j * w * h)),
                   ("acelerancia |A|", np.abs(-(w**2) * h))):
    plt.loglog(f, frf / frf.max(), label=label)
plt.axvline(vibration.resonance_frequency(m, k), ls="--", color="0.6")
plt.xlabel("Frecuencia [Hz]"); plt.ylabel("Magnitud normalizada")
plt.legend(); plt.show()
```

</details>

## 1. La familia de funciones de respuesta en frecuencia (Tabla 1)

Para un movimiento armónico `x·e^{jωt}` la velocidad es `jω·x` y la aceleración
`−ω²·x`, de modo que las tres FRF movimiento-por-fuerza se derivan de la
receptancia `H` por una potencia de `jω`, y cada una tiene una recíproca
fuerza-por-movimiento:

| Movimiento | FRF (movimiento / fuerza) | Unidad | Recíproca (fuerza / movimiento) | Unidad |
|---|---|---|---|---|
| desplazamiento | receptancia `H = x/F` | m/N | rigidez dinámica `1/H` | N/m |
| velocidad | movilidad `Y = jω·H` | m/(N·s) | impedancia `1/Y` | N·s/m |
| aceleración | acelerancia `A = −ω²·H` | 1/kg | masa aparente `1/A` | kg |

`convert_frf` pasa entre cualquiera de las seis FRF, usando la receptancia como
pivote. Una FRF de **punto de excitación** tiene la respuesta y la fuerza en el
mismo punto (`i = j`); una FRF de **transferencia** las tiene en puntos
distintos. Los tipos fuerza-por-movimiento son recíprocas elemento a elemento,
es decir, las magnitudes *libres* de la ISO 7626-1, 3.1.4; las magnitudes
matriciales *bloqueadas* de la Tabla 1 no se invierten elemento a elemento en
sistemas de varias coordenadas (la Tabla 1 llama además "masa efectiva" a
`F/a`, la magnitud aquí denominada masa aparente).

```python
from phonometry import vibration

# Una movilidad de 2e-3 m/(N.s) a 80 Hz, expresada como las demás FRF:
Y = 2e-3
print(round(abs(vibration.convert_frf(Y, 80.0, "mobility", "impedance")), 1))     # 500.0  N.s/m
print(f"{abs(vibration.convert_frf(Y, 80.0, 'mobility', 'accelerance')):.3f}")    # 1.005  1/kg
```

La elección entre las tres FRF de movimiento es de conveniencia, no de
física: llevan la misma información y `convert_frf` pasa de una a otra de
forma exacta. La acelerancia es lo que entrega directamente una medición con
acelerómetros; la movilidad es la moneda natural de las normas de potencia
estructural (la potencia es fuerza por velocidad, de modo que
`P = ½·Re{Y}·|F|²` en un contacto); las recíprocas aparecen cuando una fuente
se describe por lo que impone y no por cómo responde. Leer una movilidad de
punto de excitación es en sí un diagnóstico estructural: por debajo de una
resonancia la magnitud sube proporcional a la frecuencia por una **línea de
rigidez** (`|Y| ≈ ω/k`), por encima cae por una **línea de masa**
(`|Y| ≈ 1/(ωm)`), y la altura del pico entre ambas refleja el
amortiguamiento: vale `1/c` para el resonador aislado con amortiguamiento
viscoso de la siguiente sección, mientras que en estructuras reales con
modos solapados el amortiguamiento se estima con ajuste modal o con el
ancho de banda de media potencia.

## 2. El resonador SDOF de referencia (forma cerrada)

La referencia canónica en forma cerrada, expresada en la taxonomía de FRF de la
Tabla 1 / 3.1.2, es una masa `m`, un amortiguamiento viscoso `c` y una rigidez
`k`, cuya receptancia es

$$
H(\omega) = \frac{1}{k - \omega^2 m + j\,\omega c}, \qquad
\omega_0 = \sqrt{k/m}.
$$

En la resonancia `ω0` la movilidad en el punto de excitación es **puramente
real** e igual a `1/c` (el máximo de movilidad mide el amortiguamiento) mientras
que la receptancia estática (`ω → 0`) es la flexibilidad `1/k`:

```python

from phonometry import vibration

m, k, c = 2.0, 8000.0, 5.0
f0 = vibration.resonance_frequency(m, k)             # 10.07 Hz

y0 = complex(vibration.sdof_mobility(f0, m, k, c))
print(round(y0.real, 4), round(y0.imag, 6))   # 0.2 0.0   -> |Y(f0)| = 1/c
print(round(complex(vibration.sdof_receptance(1e-6, m, k, c)).real, 7))  # 0.000125 = 1/k
```

## 3. FRF medidas y sus criterios de aceptación (ISO 7626-2)

En la disposición habitual de ISO 7626-2 la estructura cuelga de una
suspensión lo bastante blanda para que sus modos de sólido rígido queden muy
por debajo de la primera resonancia elástica (la norma admite estructuras
suspendidas libremente o ancladas; la cláusula 5 pide un apoyo
representativo de la aplicación prevista), un excitador ataca un punto a
través de una
**cabeza de impedancia** (una pila de transductores que mide fuerza y
aceleración en el mismo punto, lo que da al montaje con excitador acoplado su
FRF de punto de excitación) y acelerómetros recogen la respuesta en otros
puntos para las FRF
de transferencia. ISO 7626-5 cubre la alternativa de excitación por impacto
con un excitador no unido a la estructura, en la práctica casi siempre un
martillo instrumentado: cambia el espectro controlado del excitador acoplado
por rapidez, con un espectro de excitación fijado por la masa del impactador
y la rigidez de la punta.

El procesado de registros medidos con excitación aleatoria según la
ISO 7626-2, 8.1.3 (el estimador H1,
`Ĥ = G(respuesta, fuerza)/G(fuerza, fuerza)`) y la coherencia ordinaria
`γ² = |Gxy|²/(Gxx·Gyy)` de sus comprobaciones de calidad son los estimadores
espectrales ya existentes de la biblioteca, [`transfer_function` y
`coherence`](/phonometry/es/guides/electroacoustics/) (H1 es su valor por
defecto). Sobre ellos se ofrecen dos criterios de aceptación de la ISO 7626-2:

* **Calibración operacional con masa rígida (7.5.2).** La FRF medida de un
  bloque rígido de masa conocida, suspendido libremente, debe coincidir dentro
  de ±5 % con `|A| = 1/m` (acelerancia) o `|Y| = 1/(2πf·m)` (movilidad).
* **Error aleatorio (Anexo A + 8.1.3).** Deben promediarse suficientes
  espectros para que el error aleatorio normalizado `ε = √((1−γ²)/(2nγ²))` en
  cada resonancia de una movilidad de punto de excitación quede por debajo
  del 5 %.

```python

from phonometry import vibration

# Un bloque de calibración de 10 kg: |A| debe ser 1/m = 0,100 1/kg en toda frecuencia.
f = np.array([20.0, 100.0, 500.0])
res = vibration.rigid_mass_calibration_check([0.100, 0.102, 0.097], f, mass=10.0)
print(res.passed, res.within_tolerance.tolist())   # True [True, True, True]

# El ejemplo del Anexo A: coherencia 0,8 necesita unos 75 promedios para < 5 %.
print(round(float(vibration.random_error_percent(0.8, 75)), 2))   # 4.08  %
```

La verificación de calibración devuelve un `RigidMassCalibrationResult` con la
desviación por frecuencia y los indicadores de aprobación, y un `.plot()`: la
magnitud de la FRF medida frente a la recta de masa rígida con su banda de
tolerancia de ±5 % (panel superior) y la desviación relativa frente a la misma
banda (panel inferior, donde una tolerancia de pocos por ciento es realmente
legible). Una calibración que se sale de la banda hacia unos pocos kHz señala
un error del transductor o de la conformidad del acoplamiento, justo lo que la
verificación pretende detectar:

```python

from phonometry import vibration

m = 10.0                                                  # masa del bloque de calibración
f = np.logspace(np.log10(20.0), np.log10(5000.0), 400)
drift = 0.05 * (f / 2500.0) ** 2                          # deriva en alta frecuencia
measured = (1.0 / m) * (1.0 + 0.015 * np.sin(2 * np.pi * np.log10(f)) + drift)
res = vibration.rigid_mass_calibration_check(measured, f, mass=m)
print(res.passed)                                         # False (la deriva supera el 5 %)
res.plot()
```

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

```python

from phonometry import vibration

m = 10.0
f = np.logspace(np.log10(20.0), np.log10(5000.0), 400)
drift = 0.05 * (f / 2500.0) ** 2
measured = (1.0 / m) * (1.0 + 0.015 * np.sin(2 * np.pi * np.log10(f)) + drift)
res = vibration.rigid_mass_calibration_check(measured, f, mass=m)
bad = ~res.within_tolerance

fig, (top, bot) = plt.subplots(2, 1, sharex=True, figsize=(10, 7),
                               gridspec_kw={"height_ratios": [1.5, 1.0]})
top.fill_between(f, res.expected * 0.95, res.expected * 1.05, color="C1",
                 alpha=0.15, label="banda de tolerancia ±5 %")
top.semilogx(f, res.expected, "--", color="C1", label="esperado |A| = 1/m")
top.semilogx(f, res.measured, color="C0", label="dentro de tolerancia")
top.semilogx(f[bad], res.measured[bad], "o", color="C1", label="fuera de tolerancia")
top.set_ylabel("Acelerancia |A| [1/kg]"); top.legend()

bot.axhspan(-5.0, 5.0, color="C1", alpha=0.15)
bot.semilogx(f, 100.0 * res.deviation, color="C0")
bot.semilogx(f[bad], 100.0 * res.deviation[bad], "o", color="C1")
bot.set_xlabel("Frecuencia [Hz]"); bot.set_ylabel("Desviación [%]")
plt.show()
```

</details>

## 4. El objeto `MobilityResult`

`sdof_mobility_result` agrupa la FRF en frecuencia en un `MobilityResult`, que
expone `.magnitude`, `.phase`, `.to(target)` (cualquier tipo de la Tabla 1) y un
`.plot()` de `|Y(f)|` con la resonancia marcada:

```python

from phonometry import vibration

f = np.logspace(np.log10(0.5), np.log10(200.0), 400)
res = vibration.sdof_mobility_result(f, mass=2.0, stiffness=8000.0, damping=5.0)
z = res.to("impedance")                        # impedancia = 1/Y por frecuencia
print(res.frequencies[int(np.argmax(res.magnitude))].round(1))   # ~10.1 Hz

res.plot()   # |Y(f)| con la resonancia marcada (requiere matplotlib)
```

*Leer una movilidad en el punto de excitación es un diagnóstico estructural:
por debajo de la resonancia la magnitud sube por la **línea de rigidez**
$\omega/k$, por encima baja por la **línea de masa** $1/(\omega m)$, y la
altura del pico entre ambas es $1/c$, una lectura directa del
amortiguamiento (Sección 1).*

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

```python

from phonometry import vibration

m, k, c = 2.0, 8000.0, 5.0
f = np.logspace(np.log10(0.5), np.log10(200.0), 400)
res = vibration.sdof_mobility_result(f, mass=m, stiffness=k, damping=c)

# Una línea: |Y(f)| con la resonancia marcada:
res.plot(language="es")
plt.show()

# A mano, añadiendo las asíntotas de rigidez y de masa que describe la prosa:
w = 2.0 * np.pi * f
fig, ax = plt.subplots()
ax.loglog(f, res.magnitude, label="|Y(f)| en el punto de excitación")
ax.loglog(f, w / k, ":", label="línea de rigidez ω/k")
ax.loglog(f, 1.0 / (w * m), ":", label="línea de masa 1/(ωm)")
ax.axhline(1.0 / c, ls="--", color="0.6", label="pico |Y| = 1/c")
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Movilidad |Y| [m/(N·s)]")
ax.set_title("Lectura de una movilidad en el punto de excitación (ISO 7626-1)")
ax.legend()
plt.show()
```

</details>

### Ficha de informe

`MobilityResult.report(path)` genera un informe de medición de movilidad mecánica
de una página (definiciones de FRF de la ISO 7626-1:2011, medición según la
ISO 7626-2:2015). La movilidad es una función de respuesta en frecuencia
continua, no una magnitud por bandas de octava, de modo que la ficha la presenta
con honestidad como el espectro de magnitud $|Y(f)|$ más una tabla compacta de
puntos característicos (el tipo de FRF, en punto de excitación o de
transferencia, el rango de frecuencias, la frecuencia del máximo, la movilidad
máxima y la fase allí), y una movilidad máxima $|Y|$ enmarcada a la frecuencia en
que ocurre (para una FRF en punto de excitación, una resonancia donde
$|Y| = 1/c$ mide el amortiguamiento). Es una caracterización, así que no hay
veredicto de aprobado/no aprobado; `language="es"` genera la ficha en español. La
ficha siempre incrusta el espectro $|Y(f)|$, por lo que necesita los extras de
informe y de gráficos (`pip install "phonometry[report,plot]"`).

```python
from phonometry import ReportMetadata, vibration

res = vibration.sdof_mobility_result(f, mass=2.0, stiffness=8000.0, damping=5.0)
res.report(
    "movilidad.pdf",
    metadata=ReportMetadata(
        specimen="Soporte de máquina (punto de excitación)",
        measurement_standard="ISO 7626-2",
    ),
    language="es",
)   # ficha de una página (necesita phonometry[report,plot])
```

## Qué cubre esta guía

**Cubierto.** La familia de FRF de la ISO 7626-1:2011 (Tabla 1): receptancia,
movilidad y acelerancia, con sus recíprocas fuerza-por-movimiento, que se
convierten entre sí con `convert_frf`. También se cubren la distinción entre
punto de excitación y transferencia, y el resonador SDOF en forma cerrada
usado como referencia (`sdof_receptance`, `sdof_mobility`,
`sdof_accelerance`, `resonance_frequency`, `sdof_mobility_result`). En el
lado de medición también se cubre el procesado H1 de excitación aleatoria de
la ISO 7626-2:2015 (`transfer_function`, `coherence`, compartidos con la
guía de electroacústica), junto con dos criterios de aceptación: la
calibración operacional con masa rígida del 7.5.2
(`rigid_mass_calibration_check`) y el criterio de error aleatorio del
Anexo A (`random_error_percent`).

**No cubierto.** La ISO 7626-5 cubre la excitación por martillo de impacto
como alternativa al excitador acoplado. Se nombra aquí solo como contexto:
ninguna función sintetiza ni procesa un espectro de excitación por impacto.
Las magnitudes matriciales *bloqueadas* de la Tabla 1, necesarias para
sistemas de varias coordenadas, tampoco están implementadas. `convert_frf`
devuelve solo las recíprocas *libres* elemento a elemento de la ISO 7626-1,
3.1.4, correctas para el punto de excitación o para una sola vía, pero no
para una matriz de FRF completa.

## Véase también

- Referencia de la API: [`vibration.mechanical_mobility`](/phonometry/es/reference/api/vibration/mechanical-mobility/).
