Skip to main content

MODULO: a python toolbox for data-driven modal decomposition

MODULO logo

MODULO is a modal decomposition package developed at the von Karman Institute for Fluid Dynamics (VKI). It offers a wide range of decomposition techniques, allowing users to choose the most appropriate method for their specific problem. MODULO can efficiently handle large datasets natively, thanks to a memory-saving feature that partitions the data and processes the decomposition in chunks (Nini et al. (2022)). Moreover, it supports non-uniform meshes through a weighted inner product formulation. Currently, MODULO heavily relies on NumPy routines and does not offer additional parallel computing capabilities beyond those naturally provided by NumPy.

While the discontinued MATLAB version of MODULO is accessible in the “Old_Matlab_Implementation” branch, it is no longer maintained. The latest updates are exclusively available in the current Python version (Poletti et al. (2024)).

As part of the MODULO project, we provide a tutorial on data-driven modal decomposition and its applications, structured as a combination of video lectures and a basic theoretical guide. The video lectures are available on the MODULO YouTube channel, and the accompanying introductory theory is presented in the MODULO documentation.

Modal decompositions

Modal decompositions aim to describe the data as a linear combination of modes, obtained by projecting the data onto a suitable set of basis. Different decompositions employ different bases, such as prescribed Fourier basis for the Discrete Fourier Transform (DFT), or data-driven basis, i.e. tailored on the dataset at hand, for the Proper Orthogonal Decomposition (POD). We refer to Mendez (2022), Mendez (2023), and Mendez et al. (2023) for an introduction to the topic. MODULO currently features the following decompositions:

We remind the curious reader to the respective references for a detailed description of each decomposition, and to the documentation for a practical guide on how to use them in MODULO.

Release Notes

Version 3.0 of MODULO includes the following updates:

  1. fast mPOD formulation for large datasets is now available. This formulation does all processing efficiently in the frequency domain, reducing computational time by orders of magnitude. For very large datasets it includes optional Fortran support for correlation matrix assembly. See Tutorial_6_fast_mPOD.ipynb for an example.

  2. vtk support for both uniform and nonuniform grids. MODULO now supports reading and writing of vtk and vtu files. A utility to get cell volumes is also included.

  3. new tutorial: a tutorial for fast mPOD method illustrating the basic use of the method is included.

Documentation

The documentation of MODULO is available here. It contains a comprehensive guide on how to install and use the package, as well as a detailed description of the decompositions required inputs and outputs. A list of YouTube videos is also available to guide the introduce the user to modal decomposition and MODULO.

Installation

Installation via pip

You can access the latest update of the modulo python package on PyPI using the command line:

$ pip install modulo_vki

Installation from source

Alternatively, you can clone the repository and install the package locally:

$ git clone https://github.com/mendezVKI/MODULO.git

$ cd MODULO

$ python -m pip install .

Optional Fortran acceleration for fast mPOD

The standard installation is pure Python and does not compile or import Fortran. This is the supported path on Windows. Linux and macOS users can opt in to the build tools and compile the extension:

$ python -m pip install "modulo_vki[fortran]"
$ python -m modulo_vki.fortran.compile_fortran

The extension is loaded only when fastmPOD(..., useFortran=True) is used; the default remains useFortran=False. A compatible Fortran compiler and OpenBLAS must be installed separately.

Example

Example 1: POD decomposition

The following example illustrates how to decompose a data set (D) using the POD decomposition.

from modulo_vki import ModuloVKI
import numpy as np

# Create a random dataset
D = np.random.rand(100, 1000)

# Initialize the ModuloVKI object
m = ModuloVKI(D)

# Compute the POD decomposition
phi_POD, Sigma_POD, psi_POD = m.POD()

which returns the spatial basis ($phi$), the temporal basis ($psi$), and the modal amplitudes ($Sigma$) of the POD decomposition.

Example 2: Memory Saving option

For the Memory Saving option, MODULO decomposes $D$ in N_partitions, defined by the user (refer to examples/ex_04_Memory_Saving.py).

import os
import numpy as np
from modulo_vki import ModuloVKI
from modulo_vki.utils.read_db import ReadData

# --- 1. User-defined settings ---
# Define the path to your data and the file naming convention.
FOLDER = 'path/to/your/snapshot_data'
FILE_ROOT_NAME = 'Res'  # The base name, e.g., 'Res' for 'Res00001.dat'
n_t = 100               # The total number of snapshots (time steps) to process.

# --- 2. Data format parameters ---
# Specify how to read your text-based snapshot files.
H = 1  # H: Number of header lines to skip
F = 0  # F: Number of footer lines to skip
C = 0  # C: Number of initial columns to skip

# --- 3. Determine data dimensions from a sample file ---
# To understand the structure, we load the first snapshot.
first_snapshot_file = os.path.join(FOLDER, f"{FILE_ROOT_NAME}00001.dat")
Dat = np.genfromtxt(first_snapshot_file, skip_header=H, skip_footer=F)

# N: Number of components per point (e.g., 2 for 2D velocity u,v)
N = Dat.shape[1]
# nxny: Number of spatial points in the mesh
nxny = Dat.shape[0]
# N_T: Total number of snapshots (aliased from n_t for clarity)
N_T = n_t

# --- 4. Process the dataset into partitions on disk ---
# The ReadData utility reads all snapshots and chunks the snapshot matrix.

D = ReadData._data_processing(
    D=None,                      # We start with no data in memory
    FOLDER_IN=FOLDER,
    filename=f'{FILE_ROOT_NAME}%05d', # File pattern for snapshot files
    N=N,                         # Number of components per point
    N_S=N * nxny,                # Total size of a single snapshot vector
    N_T=N_T,                     # Total number of snapshots
    h=H, f=F, c=C,               # Header, footer, and column skip parameters
    N_PARTITIONS=10,             # The dataset will be split into 10 chunks
    MR=False,                    # Mean-removal flag
    FOLDER_OUT=os.path.join('.', 'MODULO_tmp') # Where to save temp files
)

# --- 5. Initialize ModuloVKI and compute the POD ---
# Initialize the object, passing the number of partitions. D must be set to None
# MODULO will look for the partitions in FOLDER_OUT/MODULO_tmp
m = ModuloVKI(None, N_PARTITIONS=10, FOLDER_OUT=FOLDER_OUT)

# The POD method will now automatically read the data from the partitioned files.
phi_POD, Sigma_POD, psi_POD = m.POD()

print("POD computation complete.")

Example 3: non-uniform grid

If you are dealing with non-uniform grid (e.g. output of a Computational Fluid Dynamic (CFD) simulation), you can use the weighted inner product formulation (refer to examples/ex_05_nonUniform_POD.py).

from modulo_vki import ModuloVKI
import numpy as np

# Create a random dataset
D = np.random.rand(100, 1000)

# Get the area of the grid
a_dataSet = gridData.compute_cell_sizes()
area = a_dataSet['Area']

# Compute weights
areaTot = np.sum(area)
weights = area/areaTot # sum should be equal to 1

# Initialize the ModuloVKI object
m = ModuloVKI(D, weights=weights)

# Compute the POD decomposition
phi_POD, Sigma_POD, psi_POD = m.POD()

Community guidelines

Contributing to MODULO

We welcome contributions to MODULO.

It is recommended to perform a shallow clone of the repository to avoid downloading the entire history of the project:

$ git clone --depth 1 https://github.com/mendezVKI/MODULO.git

This will download only the latest version of the repository, which is sufficient for contributing to the project, and will save you time and disk space.

To create a new feature, please submit a pull request, specifying the proposed changes and providing an example of how to use the new feature (that will be included in the examples/ folder).

The pull request will be reviewed by the MODULO team before being merged into the main branch, and your contribution duly acknowledged.

Report bugs

If you find a bug, or you encounter unexpected behaviour, please open an issue on the MODULO GitHub repository.

Ask for help

If you have troubles using MODULO, or you need help with a specific decomposition, please open an issue on the MODULO GitHub repository.

Citation

If you use MODULO in your research, please cite it as follows:

Poletti, R., Schena, L., Ninni, D., Mendez, M. A. (2024). MODULO: A Python toolbox for data-driven modal decomposition. Journal of Open Source Software, 9(102), 6753. https://doi.org/10.21105/joss.06753

@article{Poletti2024,
  doi = {10.21105/joss.06753},
  url = {https://doi.org/10.21105/joss.06753},
  year = {2024},
  publisher = {The Open Journal},
  volume = {9},
  number = {102},
  pages = {6753},
  author = {R. Poletti and L. Schena and D. Ninni and M. A. Mendez},
  title = {MODULO: A Python toolbox for data-driven modal decomposition},
  journal = {Journal of Open Source Software}
}

and

Ninni, D., & Mendez, M. A. (2020). MODULO: A software for Multiscale Proper Orthogonal Decomposition of data. SoftwareX, 12, 100622. https://doi.org/10.1016/j.softx.2020.100622

@article{ninni2020modulo,
    title={MODULO: A software for Multiscale Proper Orthogonal Decomposition of data},
    author={Ninni, Davide and Mendez, Miguel A},
    journal={SoftwareX},
    volume={12},
    pages={100622},
    year={2020},
    publisher={Elsevier}
}

References

  • Mendez, Miguel Alfonso. “Statistical Treatment, Fourier and Modal Decomposition.” arXiv preprint arXiv:2201.03847 (2022).

  • Mendez, M. A. (2023) “Generalized and Multiscale Modal Analysis”. In : Mendez M.A., Ianiro, A., Noack, B.R., Brunton, S. L. (Eds), “Data-Driven Fluid Mechanics: Combining First Principles and Machine Learning”. Cambridge University Press, 2023:153-181. https://doi.org/10.1017/9781108896214.013. The pre-print is available at https://arxiv.org/abs/2208.12630.

  • Ninni, Davide, and Miguel A. Mendez. “MODULO: A software for Multiscale Proper Orthogonal Decomposition of data.” SoftwareX 12 (2020): 100622.

  • Poletti, Romain, Schena, Lorenzo, Ninni, David, and Mendez, Miguel A. “Modulo: A python toolbox for data-driven modal decomposition”. Journal of Open Source Software (2024), 9(102), 6753.

  • Mendez, Miguel A. “Linear and nonlinear dimensionality reduction from fluid mechanics to machine learning.” Measurement Science and Technology 34.4 (2023): 042001.

  • Briggs, William L., and Van Emden Henson. The DFT: an owner’s manual for the discrete Fourier transform. Society for Industrial and Applied Mathematics, 1995.

  • Berkooz, Gal, Philip Holmes, and John L. Lumley. “The proper orthogonal decomposition in the analysis of turbulent flows.” Annual review of fluid mechanics 25.1 (1993): 539-575.

  • Sirovich, Lawrence. “Turbulence and the dynamics of coherent structures. III. Dynamics and scaling.” Quarterly of Applied mathematics 45.3 (1987): 583-590.

  • Mendez, M. A., M. Balabane, and J-M. Buchlin. “Multi-scale proper orthogonal decomposition of complex fluid flows.” Journal of Fluid Mechanics 870 (2019): 988-1036.

  • Belda, M., L. Schena, R. Poletti, M. Isoz, T. Hyhlík, and M. A. Mendez. A Fast Spectral Formulation of the Multiscale Proper Orthogonal Decomposition. arXiv:2604.12077 (2026).

  • Schmid, Peter J. “Dynamic mode decomposition of numerical and experimental data.” Journal of fluid mechanics 656 (2010): 5-28.

  • Sieber, Moritz, C. Oliver Paschereit, and Kilian Oberleithner. “Spectral proper orthogonal decomposition.” Journal of Fluid Mechanics 792 (2016): 798-828.

  • Towne, Aaron, Oliver T. Schmidt, and Tim Colonius. “Spectral proper orthogonal decomposition and its relationship to dynamic mode decomposition and resolvent analysis.” Journal of Fluid Mechanics 847 (2018): 821-867.

  • Mika, Sebastian, et al. “Kernel PCA and de-noising in feature spaces.” Advances in neural information processing systems 11 (1998).

Metadata

Release files for modulo-vki 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for modulo-vki 3.0.0
File Size Uploaded
modulo_vki-3.0.0.tar.gz 82.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for modulo-vki 3.0.0
File Interpreter ABI Platform
modulo_vki-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 166.8 kB

Release files / modulo_vki-3.0.0.tar.gz

Download URL modulo_vki-3.0.0.tar.gz
Size 82.6 kB
Tags Source
SHA-256 checksum
How to use checksums
05c9aaaf14dd073b3e9c6ded04ae603d04c60ef5be5e5ac1610eab2cd1c44aa7
BLAKE2b-256 checksum
How to use checksums
e8dd953f755929b0abc8f0ded7db463973b73209b30021d275656607cd96542e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release files / modulo_vki-3.0.0-py3-none-any.whl

Download URL modulo_vki-3.0.0-py3-none-any.whl
Size 84.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
16338f4778abe9f5336a72ddaedb301f5b531d216d384efdf6c14092561d6fcd
BLAKE2b-256 checksum
How to use checksums
8b88871b5e0526da9981c099c83cc8345d771a82435b7f71067bf68c89fe4c61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.4

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.1.5

1 release file

2.1.4

2 release files

2.1.2

1 release file

2.1.1

1 release file

2.1.0

1 release file

2.0.7

2 release files

2.0.6

2 release files

2.0.5

2 release files

2.0.4

1 release file

2.0.3

1 release file

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