Operational modal analysis (OMA) of offshore wind turbine monopiles from sparse sensor response. An OpenSeesPy finite-element time-domain simulation feeds a Hankel Dynamic Mode Decomposition (pyDMD) pipeline that recovers natural frequencies and mode shapes with a Modal Assurance Criterion (MAC) > 0.99997 on the first three modes.
- Robust modal identification from only 4 virtual sensors / 12 acceleration channels, mimicking a sparse real-world instrumentation layout.
- Three methodological additions that make HankelDMD output usable for OMA:
- Damping-ratio filter — rejects forced 1P/3P harmonic content (ζ ≈ 0), retaining only physical structural modes.
- Delay-block spatial averaging — un-shifts the
dreplicas in the time-delay embedding and averages them to recover cleanm-dimensional mode shapes. - Phase rotation to real mode shapes — aligns the averaged complex mode with the real axis for visualisation and MAC comparison.
- A 1,000-realisation Latin Hypercube population study over material, geometry, wave and wind parameters, reporting per-mode frequency and MAC statistics.
- Full mathematical write-up in
docs/report.pdf(source).
OpenSeesPy monopile FE model (apparent fixity, Rayleigh damping,
Morison wave + turbulent wind + 1P/3P rotor loads)
│ 4 sensors × 3 DOF = 12 acceleration channels
▼
FIR anti-alias decimation (×5) → Hankel embedding (d = 200)
▼
SVD truncation (r = 12) → Koopman propagator → λ → f, ζ
▼
ζ-filter → delay-block averaged modes → phase-rotated real modes
▼
Frequency error + MAC metrics vs. reference eigenmodes
├── config.toml # environment / sea-state / wind / turbine parameters
├── population.toml # sampling distributions and sample count
├── docs/
│ ├── report.tex # full write-up (LaTeX)
│ └── report.pdf
├── examples/
│ ├── example_full.py # single realisation: simulate → DMD → metrics → figures
│ └── example_population.py# LHS population study over parameter variability
├── figures/ # generated plots (SVG)
└── src/
├── model/ # OpenSeesPy monopile FE model + load models
├── simulation/ # transient pipeline + HankelDMD wrapper
├── analysis/ # mode matching, MAC, frequency metrics
├── population/ # LHS sampling, distributions, parallel runner
├── viz/ # publication-style plotting
└── config.py # TOML config loading
Requires Python ≥ 3.10. OpenSeesPy is tested on Linux; other dependencies install from PyPI.
uv sync # or: pip install -r requirements.txt
python examples/example_full.py # single realisation → figures/ + metrics
python examples/example_population.py # 1,000-sample LHS study → data/raw/example_full.py runs the full transient simulation, extracts modes via
HankelDMD, prints the frequency/MAC comparison against the reference
eigenmodes, and writes publication-style SVGs to figures/.
example_population.py samples structural (E, D, t) and environmental
(H_wave, T_wave, U_mean_ref) parameters with Latin Hypercube Sampling and
reports per-mode frequency and MAC statistics across the population.
| File | Contents |
|---|---|
config.toml |
seawater/air properties, wave state, wind state, monopile/tower/rotor parameters |
population.toml |
n_samples and per-parameter sampling distributions |
Reference eigenmodes vs. HankelDMD extraction from 12-channel simulated accelerations (50 s at dt = 0.02 s):
| Mode | Eigen (Hz) | DMD (Hz) | Δf (Hz) | MAC |
|---|---|---|---|---|
| 1 | 0.0867 | 0.0866 | 0.0001 | 0.999999 |
| 2 | 0.5431 | 0.5428 | 0.0003 | 0.999998 |
| 3 | 1.5200 | 1.5124 | 0.0076 | 0.999808 |
Modes 4–6 lie beyond the effective Nyquist frequency (5 Hz after decimation) and are not resolvable from the subsampled data; this is documented in the report.