Skip to main content

Python finite-element library for wind turbine blade and tower modal analysis (OpenFAST/ElastoDyn)

Project description

pyBmodes

CI Validation Python 3.11+ License: Apache 2.0

pybmodes is a pure-Python finite-element library for wind-turbine blade and tower modal analysis. It reads OpenFAST (ElastoDyn / SubDyn / HydroDyn / MoorDyn), BModes .bmi, and WISDEM / WindIO ontology YAML inputs; solves the coupled flap–lag–torsion–axial vibration modes with a 15-DOF Bernoulli-Euler beam element; and emits ElastoDyn-compatible mode-shape polynomials, MAC-tracked Campbell diagrams, and bundled Markdown / HTML / CSV reports.

Validated against the BModes Fortran reference solver on six benchmark cases (NREL 5MW land + OC3 monopile + OC3 Hywind floating spar, IEA-3.4-130-RWT, BModes CertTest 03 / 04) to better than 0.01 % on every comparison. As of 1.8.0 the dedicated Validation workflow (weekly cron + workflow_dispatch) enforces the strict tolerance in CI for every case whose external data is clonable from a public GitHub upstream — the NREL 5MW r-test family (via OpenFAST/r-test) and the IEA-Task-37 reference turbines (via IEAWindTask37/IEA-*-RWT). The two BModes CertTest cases (Test03, Test04) depend on external/BModes, which is a NREL download (not a GitHub repo) and is not redistributable in CI; those tests skip cleanly when the data is absent and remain a maintainer-local enforcement until the BModes archive is mirrored somewhere CI can clone. The per-PR ci.yml continues to run the self-contained suite (synthetic + closed-form-referenced) and tolerates "no tests collected" on the integration step when the runner has no upstream data. See VALIDATION.md for the full per-case matrix with external-data flags and external/MANIFEST.toml for the pinned SHAs + file hashes you can verify against.

Documentation

📖 The rendered documentation lives at pybmodes.readthedocs.io. Sphinx-specific roles (:math:, :doc:, :func:, :class:) inside the .rst source files only render correctly through the deployed site; browsing the raw source on GitHub will show them as literal text. Always link readers to the RTD URL, not the source.

(If the URL 404s, the Read the Docs project hasn't been imported yet — see docs/deployment.rst for the one-time maintainer setup.)

Page What's there
Installation PyPI / source install, extras matrix, Windows + conda quickstart, troubleshooting
Quickstart Nine worked recipes — synthetic tower, OpenFAST deck, monopile + SubDyn, floating coupled, Campbell sweep, WindIO one-click, MAC, batch, persistence
Theory Eigenproblem maths, 15-DOF beam element, four boundary conditions, polynomial ansatz, solver dispatch, citable references
Data sources Every input format — BModes .bmi, ElastoDyn / SubDyn / HydroDyn / MoorDyn .dat, WAMIT .1 / .hst, WindIO .yaml — with snippet examples
Units SI conventions, conversion tables, mode-shape normalisation, OpenFAST DOF order, common pitfalls
Limitations Polynomial-representation limits, four specific validation-matrix edge cases, "when to reach for a different tool"
Validation matrix Per-case cross-checks against published references (cross-references VALIDATION.md)
API reference Autodoc-generated module reference
API contract Semver-frozen public surface + deprecation policy + stability tiers
Changelog Versioning policy + full release history (cross-references CHANGELOG.md)
Contributing Welcome scope, pre-commit, PR checklist, no-AI-attribution rule
Release checklist 11-step pre-tag sequence (maintainer)
Deployment One-time RTD setup + versioning policy (maintainer)

To build locally:

pip install -e ".[docs]"
make -C docs html
# then open docs/_build/html/index.html through a real web server
# (file:// blocks MathJax CDN in some browsers):
python -m http.server -d docs/_build/html

Install

PyPI status: pre-release. The pybmodes distribution is not yet published to PyPI — that's tracked as a 1.x release-gate item. Until the first PyPI release lands, install from source:

git clone https://github.com/SMI-Lab-Inha/pyBModes.git
cd pyBModes
pip install -e ".[dev,plots]"

Once published, the canonical install will be the standard one:

pip install pybmodes        # (post-PyPI-release; not available yet)

Take care that pybmodes is a different project from pyModeS (an ADS-B / Mode-S decoder). When the PyPI release lands the project name on PyPI will be pybmodes (lowercase, no S); double-check the package name + the GitHub SMI-Lab-Inha/pyBModes repo URL before installing.

See https://pybmodes.readthedocs.io/en/latest/installation.html for the full Windows + conda quickstart and the optional-extras matrix ([plots], [windio], [notebook], [docs]).

Quick example

from pybmodes.models import Tower
from pybmodes.elastodyn import compute_tower_params, patch_dat

# Reads ElastoDyn main + tower from one path; lumps the rotor mass.
tower = Tower.from_elastodyn("NRELOffshrBsline5MW_Onshore_ElastoDyn.dat")
modal = tower.run(n_modes=4)

# Constrained 6th-order fit, FA/SS family selection with torsion-contamination filter.
params = compute_tower_params(modal)

# Rewrite the polynomial blocks (use --dry-run / --diff via the CLI for safety).
patch_dat("NRELOffshrBsline5MW_Onshore_ElastoDyn.dat", params)

More — Campbell sweeps, WindIO one-click, mode-by-mode MAC comparison, bundled reports — in https://pybmodes.readthedocs.io/en/latest/quickstart.html.

CLI

Seven subcommands surfaced as the pybmodes console script:

Subcommand Purpose
pybmodes validate <main.dat> Coefficient-consistency report on one ElastoDyn deck.
pybmodes patch <main.dat> Regenerate polynomial blocks. --dry-run / --diff / --backup / --output-dir for safety.
pybmodes campbell <input> Rotor-speed sweep → Campbell diagram PNG + CSV.
pybmodes batch ROOT Walk a directory of decks; per-deck validate + patch + summary CSV.
pybmodes report <main.dat> Bundled Markdown / HTML / CSV analysis report.
pybmodes windio <yaml | dir> One-click WISDEM / WindIO → composite blade + tubular tower + coupled platform + Campbell.
pybmodes examples --copy DIR Vendor sample_inputs/ and / or reference_decks/ out of the installed wheel.

Development

pytest                                       # default — self-contained, no external data
pytest -m integration                        # integration — needs upstream decks under external/
ruff check src/ tests/ scripts/
mypy src/pybmodes
python scripts/audit_validation_claims.py    # gates "claim ahead of test" drift

The default pytest run is self-contained and works on a fresh clone with no external data. Tests that need locally-checked-out OpenFAST r-test, BModes CertTest, or IEA-RWT decks are gated behind the integration marker; CI tolerates exit code 5 ("no tests collected") on a runner without the data. Full developer guide in CONTRIBUTING.md.

Citation

If you use pyBmodes in academic work, please cite it via the CITATION.cff file. GitHub's Cite this repository widget reads it automatically; Zenodo and most reference managers pick it up too.

License

Released under the Apache License 2.0.

Copyright 2024-2026 Jae Hoon Seo, Marine Structural Mechanics and Integrity Lab (SMI Lab), Inha University.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pybmodes-1.8.0.tar.gz (675.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pybmodes-1.8.0-py3-none-any.whl (544.1 kB view details)

Uploaded Python 3

File details

Details for the file pybmodes-1.8.0.tar.gz.

File metadata

  • Download URL: pybmodes-1.8.0.tar.gz
  • Upload date:
  • Size: 675.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pybmodes-1.8.0.tar.gz
Algorithm Hash digest
SHA256 a0870b883ceb44b48ea1e4d082111a745e7a7f7a5a1e03f0d68dc0cfb1fb10d6
MD5 9fbaf03b308da44299b9663303ef7aa4
BLAKE2b-256 d6231389514f2a5b0de78e8e3d3df9b756e8a06d453c664b5513fdde75ceb174

See more details on using hashes here.

Provenance

The following attestation bundles were made for pybmodes-1.8.0.tar.gz:

Publisher: publish.yml on SMI-Lab-Inha/pyBModes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pybmodes-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: pybmodes-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 544.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pybmodes-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c60717c91f284811c156b7e189f889561f077134a1fb184eca56dcfc0b95f96
MD5 404cd14226ccfc586c14e4235fbf1aea
BLAKE2b-256 a7de4551bab19b54f5e165bda547196d0763dd612f6449b8eb34c1926c770c06

See more details on using hashes here.

Provenance

The following attestation bundles were made for pybmodes-1.8.0-py3-none-any.whl:

Publisher: publish.yml on SMI-Lab-Inha/pyBModes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page