foamlib is a modern Python package that provides an elegant, streamlined interface for interacting with OpenFOAM. It's designed to make OpenFOAM-based workflows more accessible, reproducible, and precise for researchers and engineers.

Loading a volVectorField with one million cells1
foamlib is a Python package designed to simplify and streamline OpenFOAM workflows. It provides:
- 🗄️ Intuitive file handling: Read and write OpenFOAM configuration and field files as if they were Python objects
- ⚡ High performance: Standalone parser supporting both ASCII and binary formats with or without compression
- 🔄 Async operations: Run multiple cases in parallel with full
asyncio
support - 🎯 Type safety: A fully typed API for a better development experience
- ⚙️ Workflow automation: Reduce boilerplate code for pre/post-processing and simulation management
- 🧩 Fully compatible: Works with OpenFOAM from both openfoam.com and openfoam.org
- And more!
Compared to PyFoam and other similar tools like fluidfoam, fluidsimfoam, and Ofpp, foamlib offers significant advantages in performance, usability, and modern Python compatibility.
foamlib provides these key classes for different aspects of OpenFOAM workflow automation:
FoamFile
- Read and write OpenFOAM configuration files as if they were Pythondict
sFoamFieldFile
- Handle field files with support for ASCII and binary formats (with or without compression)
FoamCase
- Configure, run, and access results of OpenFOAM casesAsyncFoamCase
- Asynchronous version for running multiple cases concurrentlyAsyncSlurmFoamCase
- Specialized for Slurm-based HPC clusters
Choose your preferred installation method:
✨ pip | pip install foamlib |
🐍 conda | conda install -c conda-forge foamlib |
🍺 Homebrew | brew install gerlero/openfoam/foamlib |
🐳 Docker | docker pull microfluidica/foamlib |
Here's a simple example to get you started:
import os
from pathlib import Path
from foamlib import FoamCase
# Clone and run a case
my_case = FoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily").clone("myCase")
my_case.run()
# Access results
latest_time = my_case[-1]
pressure = latest_time["p"].internal_field
velocity = latest_time["U"].internal_field
print(f"Max pressure: {max(pressure)}")
print(f"Velocity at first cell: {velocity[0]}")
# Clean up
my_case.clean()
import os
from pathlib import Path
from foamlib import FoamCase
pitz_tutorial = FoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
my_pitz = pitz_tutorial.clone("myPitz")
# Run the simulation
my_pitz.run()
# Access the latest time step
latest_time = my_pitz[-1]
p = latest_time["p"]
U = latest_time["U"]
print(f"Pressure field: {p.internal_field}")
print(f"Velocity field: {U.internal_field}")
# Clean the case
my_pitz.clean()
# Modify control settings
my_pitz.control_dict["writeInterval"] = 10
my_pitz.control_dict["endTime"] = 2000
# Make multiple file changes efficiently
with my_pitz.fv_schemes as f:
f["gradSchemes"]["default"] = f["divSchemes"]["default"]
f["snGradSchemes"]["default"] = "uncorrected"
import asyncio
from foamlib import AsyncFoamCase
async def run_multiple_cases():
"""Run multiple cases concurrently."""
base_case = AsyncFoamCase(my_pitz)
# Create and run multiple cases with different parameters
tasks = []
for i, velocity in enumerate([1, 2, 3]):
case = base_case.clone(f"case_{i}")
case[0]["U"].boundary_field["inlet"].value = [velocity, 0, 0]
tasks.append(case.run())
# Wait for all cases to complete
await asyncio.gather(*tasks)
# Run the async function
asyncio.run(run_multiple_cases())
import numpy as np
from foamlib import FoamFieldFile
# Read field data directly
U = FoamFieldFile("0/U")
print(f"Velocity field shape: {np.shape(U.internal_field)}")
print(f"Boundaries: {list(U.boundary_field)}")
import os
from pathlib import Path
from foamlib import AsyncSlurmFoamCase
from scipy.optimize import differential_evolution
# Set up base case for optimization
base = AsyncSlurmFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
async def objective_function(x):
"""Objective function for optimization."""
async with base.clone() as case:
# Set inlet velocity based on optimization parameters
case[0]["U"].boundary_field["inlet"].value = [x[0], 0, 0]
# Run with fallback to local execution if Slurm unavailable
await case.run(fallback=True)
# Return objective (minimize velocity magnitude at outlet)
return abs(case[-1]["U"].internal_field[0][0])
# Run optimization with parallel jobs
result = differential_evolution(
objective_function,
bounds=[(-1, 1)],
workers=AsyncSlurmFoamCase.map,
polish=False
)
print(f"Optimal inlet velocity: {result.x[0]}")
#!/usr/bin/env python3
"""Run the OpenFOAM case in this directory."""
from pathlib import Path
from foamlib import FoamCase
# Initialize case from this directory
case = FoamCase(Path(__file__).parent)
# Adjust simulation parameters
case.control_dict["endTime"] = 1000
case.control_dict["writeInterval"] = 100
# Run the simulation
print("Starting OpenFOAM simulation...")
case.run()
print("Simulation completed successfully!")
For more details on how to use foamlib, check out the documentation.
If you have any questions or need help, feel free to open a discussion.
If you believe you have found a bug in foamlib, please open an issue.
You're welcome to contribute to foamlib! Check out the contributing guidelines for more information.
foamlib has been published in the Journal of Open Source Software!
If you use foamlib in your research, please cite our paper:
Gerlero, G. S., & Kler, P. A. (2025). foamlib: A modern Python package for working with OpenFOAM. Journal of Open Source Software, 10(109), 7633. https://doi.org/10.21105/joss.07633
📋 BibTeX
@article{foamlib,
author = {Gerlero, Gabriel S. and Kler, Pablo A.},
doi = {10.21105/joss.07633},
journal = {Journal of Open Source Software},
month = may,
number = {109},
pages = {7633},
title = {{foamlib: A modern Python package for working with OpenFOAM}},
url = {https://joss.theoj.org/papers/10.21105/joss.07633},
volume = {10},
year = {2025}
}
[1] foamlib 1.3.11 vs. PyFoam 2023.7 (Python 3.11.13) on an M3 MacBook Air. Benchmark script.