Skip to main content

openmodalpy banner

CI PyPI Python License

openmodalpy puts nine modal decomposition methods for spatiotemporal data behind one API. Extract coherent structures from simulation or experimental data — energy-ranked POD modes, frequency-resolved SPOD modes, DMD eigenvalues, nonlinear BSMD triads — without switching libraries or rewriting your loading code for each method.

Why this package

Most Python tools here specialise: PyDMD covers DMD variants in depth, PySPOD covers SPOD. That depth is real, and if you only need one method they are excellent choices.

OpenModalPy trades some of that depth for breadth. Nine methods share one analyzer interface, one data contract and one config file, so running POD, SPOD, DMD and BSMD over the same dataset — and comparing them directly — is a single command rather than four integrations. Bispectral mode decomposition (BSMD) in particular has little open-source coverage elsewhere.

It runs on the NumPy/SciPy stack. No compiled solver toolchain (PETSc, SLEPc) to install.

Installation

uv add openmodalpy                 # library
uv tool install openmodalpy        # standalone CLI

Optional extras:

Extra Adds
openmodalpy[viz3d] 3D slice and isosurface plotting (PyVista)
openmodalpy[mkl] Intel MKL FFT backend
openmodalpy[gpu] CuPy / PyTorch FFT backends

Quick Start

from openmodalpy import PODAnalyzer, SPODAnalyzer, DMDAnalyzer

pod = PODAnalyzer(file_path="data.mat", n_modes_save=10)
pod.run_analysis()

spod = SPODAnalyzer(file_path="data.mat", nfft=256, overlap=0.5)
spod.run_analysis()

# DMD is driven in two steps, so the fit method can be chosen after loading.
dmd = DMDAnalyzer(file_path="data.mat", n_modes_save=10)
dmd.load_and_preprocess()
dmd.perform_dmd(method="ls")

Configuration-Driven Workflow

One JSONC file runs several methods over the same dataset — the main reason to reach for this package over a single-method library:

{
  "case": {
    "name": "my_case",
    "data": { "kind": "file", "path": "data.mat" },
    "n_modes_save": 10, "nfft": 128, "overlap": 0.5
  },
  "runs": [
    { "id": "pod",   "method": "pod" },
    { "id": "spod",  "method": "spod" },
    { "id": "dmd",   "method": "dmd",   "params": { "method": "ls" } },
    { "id": "hodmd", "method": "hodmd", "params": { "delays": 4 } },
    { "id": "bsmd",  "method": "bsmd" }
  ]
}
openmodalpy run --config analysis.jsonc

CLI

openmodalpy analyze pod --config case.jsonc     # one method
openmodalpy run --config suite.jsonc            # full suite
openmodalpy run --config suite.jsonc --dry-run  # preview without computing
openmodalpy methods list                        # supported methods
openmodalpy examples list                       # bundled examples
openmodalpy results inspect output.hdf5         # inspect a result file

Three example cases ship with the package and need no external data — double_gyre, cylinder_wake and taylor_green generate their fields analytically. A fourth config, run_benchmarks, runs all three as a suite. So openmodalpy examples list gives you something runnable immediately, with nothing to download.

Methods

These are the names openmodalpy methods list reports and the values the method field takes in a config file.

method Class What it extracts Reference
pod variance-optimal energy-ranked spatial modes Lumley (1967); Sirovich (1987)
mpod variance-optimal scale-separated modes across non-overlapping bands Mendez et al. (2019)
psd-pod variance-optimal POD of blockwise Fourier realizations
spod variance-optimal frequency-local modes (Welch blocks) Towne, Schmidt & Colonius (2018)
stpod variance-optimal space-time structures via delay embedding
dmd evolution-fit modes with frequency and growth rate Schmid (2010); Tu et al. (2014)
hodmd evolution-fit delay-embedded (Hankel) DMD Le Clainche & Vega (2017)
tls-hodmd evolution-fit delay-embedded DMD, total-least-squares fit Hemati et al. (2017)
bsmd triadic interaction nonlinear triad structures Schmidt (2020)

dmd accepts method: "ls" (least squares) or method: "tls" (total least squares, de-biased for noisy data).

The BSMD implementation follows Schmidt (2020) and was inspired by the reference MATLAB implementation.

Data Format

.mat and .npz files are auto-detected and must provide:

{
    "q": np.ndarray,   # (Ns, Nspace) — snapshots × spatial points
    "dt": float,       # time step
    "Nx": int,         # grid points in x
    "Ny": int,         # grid points in y
    "x": np.ndarray,   # x-coordinates
    "y": np.ndarray,   # y-coordinates
}

Anything else can be read with a custom loader returning the same dictionary:

def my_loader(path):
    return {"q": data, "dt": 0.01, "Nx": 100, "Ny": 50, "x": x, "y": y}

pod = PODAnalyzer(file_path="ignored", data_loader=my_loader)

FFT Backend

FFT dispatch comes from fftkit, installed automatically. It probes the available backends, picks the fastest, and falls back to SciPy when nothing else is present — so this section is optional reading.

To pin a backend:

export FFTKIT_BACKEND=mkl      # or scipy, numpy, cupy, accelerate
from openmodalpy.core import FFT_BACKEND
print(FFT_BACKEND)   # the backend actually in use

The legacy PYMODAL_FFT_BACKEND variable still works as a fallback, but FFTKIT_BACKEND is the supported name.

Contributing

Contributions are welcome, and questions and bug reports count. See CONTRIBUTING.md for setup and the checks CI runs, and the openfluids Code of Conduct for how we work together.

License

Apache-2.0. Originally developed by Ricardo A S Frantz — see LICENSE and NOTICE for terms and attribution.

Download files

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

Source Distribution

openmodalpy-0.4.0.tar.gz (311.3 kB view details)

Uploaded Source

Built Distribution

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

openmodalpy-0.4.0-py3-none-any.whl (158.4 kB view details)

Uploaded Python 3

File details

Details for the file openmodalpy-0.4.0.tar.gz.

File metadata

  • Download URL: openmodalpy-0.4.0.tar.gz
  • Upload date:
  • Size: 311.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for openmodalpy-0.4.0.tar.gz
Algorithm Hash digest
SHA256 9c18f2ef62a516c0fe554b75d24fdc61399c9df0f91ac4863f0d6736515f66ec
MD5 74b1c8d9477c1262f1bb1654b8901a3e
BLAKE2b-256 fb86b5ba47ee2a3d5896dad669355a9fdcde5f3d2b15409cf7e1c27365ba5826

See more details on using hashes here.

Provenance

The following attestation bundles were made for openmodalpy-0.4.0.tar.gz:

Publisher: release.yml on openfluids/openmodalpy

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

File details

Details for the file openmodalpy-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: openmodalpy-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 158.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for openmodalpy-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d13a6bd7e1ede580f318847d43574ce630ecb11cefc56e8a8ae462fdab6ad14c
MD5 a400cafa9627ceaec85ea8df4412c1c4
BLAKE2b-256 787d62734a4d2635c0c9649dca8954e4a9ceb037073871b8572a8a5dce708988

See more details on using hashes here.

Provenance

The following attestation bundles were made for openmodalpy-0.4.0-py3-none-any.whl:

Publisher: release.yml on openfluids/openmodalpy

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

Release history Release notifications | RSS feed

0.5.0

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page