/foamlib

A modern Python interface for interacting with OpenFOAM

Primary LanguagePythonGNU General Public License v3.0GPL-3.0

foamlib

Documentation CI Codecov Checked with mypy Ruff PyPI PyPI - Python Version OpenFOAM Docker image

foamlib provides a simple, modern and ergonomic Python interface for interacting with OpenFOAM.

It offers the following classes:

  • FoamFile (and FoamFieldFile): read-write access to OpenFOAM configuration and field files as if they were Python dicts, using foamlib's own parser. Supports both ASCII and binary field formats.
  • FoamCase: a class for manipulating, executing and accessing the results of OpenFOAM cases.
  • AsyncFoamCase: variant of FoamCase with asynchronous methods for running multiple cases at once.

Get started

Install

Install with pip:

pip install foamlib

Clone a case

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 case

my_pitz.run()

Access the results

latest_time = my_pitz[-1]

p = latest_time["p"]
U = latest_time["U"]

print(p.internal_field)
print(U.internal_field)

Clean the case

my_pitz.clean()

Edit the controlDict file

my_pitz.control_dict["writeInterval"] = 10

Make multiple file reads and writes in a single go

with my_pitz.fv_schemes as f:
    f["gradSchemes"]["default"] = f["divSchemes"]["default"]
    f["snGradSchemes"]["default"] = "uncorrected"

Run a case asynchronously

import asyncio
from foamlib import AsyncFoamCase

async def run_case():
    my_pitz_async = AsyncFoamCase(my_pitz)
    await my_pitz_async.run()

asyncio.run(run_case())

Parse a field using the FoamFieldFile class directly

from foamlib import FoamFieldFile

U = FoamFieldFile(Path(my_pitz) / "0/U")

print(U.internal_field)

Run an optimization loop in parallel

import os
from pathlib import Path
from foamlib import AsyncFoamCase
from scipy.optimize import differential_evolution

base = AsyncFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")

async def cost(x):
    async with base.clone() as clone:
        clone[0]["U"].boundary_field["inlet"].value = [x[0], 0, 0]
        await clone.run()
        return abs(clone[-1]["U"].internal_field[0][0])

result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncFoamCase.map, polish=False)

Documentation

For more information, check out the documentation.