Skip to main content

High-performance CFD simulation library with Python bindings

Project description

CFD Python

Python bindings for high-performance CFD simulation library using CPython C-API with stable ABI (abi3).

Features

  • High Performance: Direct bindings to optimized C library with SIMD (AVX2/NEON) and OpenMP support
  • Stable ABI: Compatible across Python 3.9+ versions
  • Multiple Backends: Scalar, SIMD, OpenMP, and CUDA (GPU) backends with runtime detection
  • Boundary Conditions: Full BC support (Neumann, Dirichlet, no-slip, inlet, outlet)
  • Dynamic Solver Discovery: New solvers automatically available
  • Multiple Output Formats: VTK and CSV export support
  • Error Handling: Rich exception hierarchy with detailed error messages

Installation

Installing uv (optional but recommended)

uv is a fast Python package manager. Install it with:

# On macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Or with pip
pip install uv

From PyPI

Using uv (recommended):

uv pip install cfd-python

Or with pip:

pip install cfd-python

From Source

The Python package requires the C CFD library to be built first. By default, it expects the library at ../cfd relative to the cfd-python directory. You can override this by setting the CFD_ROOT environment variable.

  1. Build the C CFD library (static):

    cd ../cfd
    cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
    cmake --build build --config Release
    
  2. Install the Python package:

    cd ../cfd-python
    pip install .
    

    Or with uv for faster installs:

    uv pip install .
    

    With a custom library location:

    CFD_ROOT=/path/to/cfd pip install .
    

For Development

We use uv for fast dependency management:

# Create virtual environment
uv venv

# Activate it
source .venv/bin/activate      # Linux/macOS
source .venv/Scripts/activate  # Windows (Git Bash)
.venv\Scripts\activate         # Windows (cmd)

# Install with dev dependencies
uv pip install -e ".[test,dev]"

Alternatively, using pip:

pip install -e ".[test,dev]"

Quick Start

import cfd_python

# List available solvers
print(cfd_python.list_solvers())
# ['explicit_euler', 'explicit_euler_optimized', 'projection', ...]

# Run a simple simulation
velocity_magnitude = cfd_python.run_simulation(50, 50, steps=100)
print(f"Computed {len(velocity_magnitude)} velocity values")

# Create a grid
grid = cfd_python.create_grid(100, 100, 0.0, 1.0, 0.0, 1.0)
print(f"Grid: {grid['nx']}x{grid['ny']}")

# Get default solver parameters
params = cfd_python.get_default_solver_params()
print(f"Default dt: {params['dt']}")

API Reference

Simulation Functions

run_simulation(nx, ny, steps=100, xmin=0.0, xmax=1.0, ymin=0.0, ymax=1.0, solver_type=None, output_file=None)

Run a complete simulation with default parameters.

Parameters:

  • nx, ny: Grid dimensions
  • steps: Number of time steps (default: 100)
  • xmin, xmax, ymin, ymax: Domain bounds (optional)
  • solver_type: Solver name string (optional, uses library default)
  • output_file: VTK output file path (optional)

Returns: List of velocity magnitude values

run_simulation_with_params(nx, ny, xmin, xmax, ymin, ymax, steps=1, dt=0.001, cfl=0.2, solver_type=None, output_file=None)

Run simulation with custom parameters and solver selection.

Parameters:

  • nx, ny: Grid dimensions
  • xmin, xmax, ymin, ymax: Domain bounds
  • steps: Number of time steps (default: 1)
  • dt: Time step size (default: 0.001)
  • cfl: CFL number (default: 0.2)
  • solver_type: Solver name string (optional, uses library default)
  • output_file: VTK output file path (optional)

Returns: Dictionary with velocity_magnitude, nx, ny, steps, solver_name, solver_description, and stats

create_grid(nx, ny, xmin, xmax, ymin, ymax)

Create a computational grid.

Parameters:

  • nx, ny: Grid dimensions
  • xmin, xmax, ymin, ymax: Domain bounds

Returns: Dictionary with nx, ny, xmin, xmax, ymin, ymax, x_coords, y_coords

create_grid_stretched(nx, ny, xmin, xmax, ymin, ymax, beta)

Create a grid with non-uniform (stretched) spacing.

Parameters:

  • nx, ny: Grid dimensions
  • xmin, xmax, ymin, ymax: Domain bounds
  • beta: Stretching parameter (higher = more clustering)

Returns: Dictionary with grid info including x_coords, y_coords

Note: The stretched grid implementation has a known bug - see ROADMAP.md for details.

get_default_solver_params()

Get default solver parameters.

Returns: Dictionary with keys: dt, cfl, gamma, mu, k, max_iter, tolerance

Solver Discovery

list_solvers()

Get list of all available solver names.

Returns: List of solver name strings

has_solver(name)

Check if a solver is available.

Returns: Boolean

get_solver_info(name)

Get information about a solver.

Returns: Dictionary with name, description, version, capabilities

Dynamic Solver Constants

Solver constants are automatically generated from the registry:

cfd_python.SOLVER_EXPLICIT_EULER           # 'explicit_euler'
cfd_python.SOLVER_EXPLICIT_EULER_OPTIMIZED # 'explicit_euler_optimized'
cfd_python.SOLVER_PROJECTION               # 'projection'
# ... more solvers as registered in C library

Backend Availability (v0.1.6+)

Query and select compute backends at runtime:

import cfd_python

# Check available backends
print(cfd_python.get_available_backends())
# ['Scalar', 'SIMD', 'OpenMP']  # CUDA if GPU available

# Check specific backend
if cfd_python.backend_is_available(cfd_python.BACKEND_SIMD):
    print("SIMD backend available!")

# Get backend name
print(cfd_python.backend_get_name(cfd_python.BACKEND_OMP))  # 'OpenMP'

# List solvers for a backend
omp_solvers = cfd_python.list_solvers_by_backend(cfd_python.BACKEND_OMP)
print(f"OpenMP solvers: {omp_solvers}")

Backend Constants:

  • BACKEND_SCALAR: Basic scalar CPU implementation
  • BACKEND_SIMD: SIMD-optimized (AVX2/NEON)
  • BACKEND_OMP: OpenMP parallelized
  • BACKEND_CUDA: CUDA GPU acceleration

Boundary Conditions

Apply various boundary conditions to flow fields:

import cfd_python

# Create velocity field (as flat lists)
nx, ny = 50, 50
u = [0.0] * (nx * ny)
v = [0.0] * (nx * ny)

# Apply uniform inlet on left edge
cfd_python.bc_apply_inlet_uniform(
    u, v, nx, ny,
    u_inlet=1.0, v_inlet=0.0,
    edge=cfd_python.BC_EDGE_LEFT
)

# Apply zero-gradient outlet on right edge
cfd_python.bc_apply_outlet_velocity(u, v, nx, ny, cfd_python.BC_EDGE_RIGHT)

# Apply no-slip walls on top and bottom
cfd_python.bc_apply_noslip(u, v, nx, ny)

# Check/set BC backend
print(f"BC Backend: {cfd_python.bc_get_backend_name()}")
if cfd_python.bc_backend_available(cfd_python.BC_BACKEND_OMP):
    cfd_python.bc_set_backend(cfd_python.BC_BACKEND_OMP)

BC Type Constants:

  • BC_TYPE_PERIODIC: Periodic boundaries
  • BC_TYPE_NEUMANN: Zero-gradient boundaries
  • BC_TYPE_DIRICHLET: Fixed value boundaries
  • BC_TYPE_NOSLIP: No-slip wall (zero velocity)
  • BC_TYPE_INLET: Inlet velocity specification
  • BC_TYPE_OUTLET: Outlet conditions

BC Edge Constants:

  • BC_EDGE_LEFT, BC_EDGE_RIGHT, BC_EDGE_BOTTOM, BC_EDGE_TOP

BC Backend Constants:

  • BC_BACKEND_AUTO: Auto-select best available
  • BC_BACKEND_SCALAR: Single-threaded scalar
  • BC_BACKEND_OMP: OpenMP parallel
  • BC_BACKEND_SIMD: SIMD + OpenMP (AVX2/NEON)
  • BC_BACKEND_CUDA: GPU acceleration

BC Functions:

  • bc_apply_scalar(field, nx, ny, bc_type): Apply BC to scalar field
  • bc_apply_velocity(u, v, nx, ny, bc_type): Apply BC to velocity fields
  • bc_apply_dirichlet(field, nx, ny, left, right, bottom, top): Fixed values
  • bc_apply_noslip(u, v, nx, ny): Zero velocity at walls
  • bc_apply_inlet_uniform(u, v, nx, ny, u_inlet, v_inlet, edge): Uniform inlet
  • bc_apply_inlet_parabolic(u, v, nx, ny, max_velocity, edge): Parabolic inlet
  • bc_apply_outlet_scalar(field, nx, ny, edge): Zero-gradient outlet
  • bc_apply_outlet_velocity(u, v, nx, ny, edge): Zero-gradient outlet

Derived Fields & Statistics

Compute derived quantities from flow fields:

import cfd_python

# Compute velocity magnitude
u = [1.0] * 100
v = [0.5] * 100
vel_mag = cfd_python.compute_velocity_magnitude(u, v, 10, 10)

# Calculate field statistics
stats = cfd_python.calculate_field_stats(vel_mag)
print(f"Min: {stats['min']}, Max: {stats['max']}, Avg: {stats['avg']}")

# Comprehensive flow statistics
p = [0.0] * 100  # pressure field
flow_stats = cfd_python.compute_flow_statistics(u, v, p, 10, 10)
print(f"Max velocity: {flow_stats['velocity_magnitude']['max']}")

CPU Features Detection

Detect SIMD capabilities at runtime:

import cfd_python

# Check SIMD architecture
arch = cfd_python.get_simd_arch()
name = cfd_python.get_simd_name()  # 'avx2', 'neon', or 'none'

# Check specific capabilities
if cfd_python.has_avx2():
    print("AVX2 available!")
elif cfd_python.has_neon():
    print("ARM NEON available!")

# General SIMD check
if cfd_python.has_simd():
    print(f"SIMD enabled: {name}")

SIMD Constants:

  • SIMD_NONE: No SIMD support
  • SIMD_AVX2: x86-64 AVX2
  • SIMD_NEON: ARM NEON

Error Handling

Handle errors with Python exceptions:

import cfd_python
from cfd_python import (
    CFDError,
    CFDMemoryError,
    CFDInvalidError,
    CFDDivergedError,
    raise_for_status,
)

# Check status codes
status = cfd_python.get_last_status()
if status != cfd_python.CFD_SUCCESS:
    error_msg = cfd_python.get_last_error()
    print(f"Error: {error_msg}")

# Use raise_for_status helper
try:
    raise_for_status(status, context="simulation step")
except CFDDivergedError as e:
    print(f"Solver diverged: {e}")
except CFDInvalidError as e:
    print(f"Invalid parameter: {e}")
except CFDError as e:
    print(f"CFD error: {e}")

# Clear error state
cfd_python.clear_error()

Error Constants:

  • CFD_SUCCESS: Operation successful (0)
  • CFD_ERROR: Generic error (-1)
  • CFD_ERROR_NOMEM: Out of memory (-2)
  • CFD_ERROR_INVALID: Invalid argument (-3)
  • CFD_ERROR_IO: File I/O error (-4)
  • CFD_ERROR_UNSUPPORTED: Operation not supported (-5)
  • CFD_ERROR_DIVERGED: Solver diverged (-6)
  • CFD_ERROR_MAX_ITER: Max iterations reached (-7)

Exception Classes:

  • CFDError: Base exception class
  • CFDMemoryError(CFDError, MemoryError): Memory allocation failed
  • CFDInvalidError(CFDError, ValueError): Invalid argument
  • CFDIOError(CFDError, IOError): File I/O error
  • CFDUnsupportedError(CFDError, NotImplementedError): Unsupported operation
  • CFDDivergedError(CFDError): Solver diverged
  • CFDMaxIterError(CFDError): Max iterations reached

Output Functions

set_output_dir(directory)

Set the output directory for VTK/CSV files.

write_vtk_scalar(filename, field_name, data, nx, ny, xmin, xmax, ymin, ymax)

Write scalar field to VTK file.

write_vtk_vector(filename, field_name, u_data, v_data, nx, ny, xmin, xmax, ymin, ymax)

Write vector field to VTK file.

write_csv_timeseries(filename, step, time, u_data, v_data, p_data, nx, ny, dt, iterations, create_new=False)

Write simulation timeseries data to CSV file.

Parameters:

  • filename: Output file path
  • step: Time step number
  • time: Simulation time
  • u_data, v_data, p_data: Flow field data as lists (size nx*ny)
  • nx, ny: Grid dimensions
  • dt: Time step size
  • iterations: Number of solver iterations
  • create_new: If True, create new file; if False, append

Output Type Constants

cfd_python.OUTPUT_VELOCITY_MAGNITUDE  # Velocity magnitude scalar (VTK)
cfd_python.OUTPUT_VELOCITY            # Velocity vector field (VTK)
cfd_python.OUTPUT_FULL_FIELD          # Complete flow field (VTK)
cfd_python.OUTPUT_CSV_TIMESERIES      # Time series (CSV)
cfd_python.OUTPUT_CSV_CENTERLINE      # Centerline profile (CSV)
cfd_python.OUTPUT_CSV_STATISTICS      # Global statistics (CSV)

Migration from v0.1.0

If you're upgrading from an older version, note these changes:

API Changes

  1. Type names changed (internal, transparent to Python users)
  2. Error handling improved: Use get_last_error(), get_last_status(), clear_error()
  3. New solver backends: SIMD, OpenMP, CUDA available via backend_is_available()

New Features in v0.1.6

  • Boundary conditions: Full BC API with inlet/outlet support
  • Backend selection: Query and select compute backends at runtime
  • Derived fields: compute_velocity_magnitude(), compute_flow_statistics()
  • Error handling: Python exception classes with raise_for_status()
  • CPU detection: has_avx2(), has_neon(), has_simd()

See MIGRATION_PLAN.md for detailed migration information.

Requirements

  • Python 3.9+
  • uv (recommended) or pip

For building from source:

  • C compiler (MSVC on Windows, GCC/Clang on Unix)
  • CMake 3.15+

License

MIT License

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

cfd_python-0.1.6.tar.gz (289.7 kB view details)

Uploaded Source

Built Distributions

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

cfd_python-0.1.6-cp39-abi3-win_amd64.whl (85.4 kB view details)

Uploaded CPython 3.9+Windows x86-64

cfd_python-0.1.6-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (419.9 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

cfd_python-0.1.6-cp39-abi3-macosx_15_0_arm64.whl (72.3 kB view details)

Uploaded CPython 3.9+macOS 15.0+ ARM64

File details

Details for the file cfd_python-0.1.6.tar.gz.

File metadata

  • Download URL: cfd_python-0.1.6.tar.gz
  • Upload date:
  • Size: 289.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for cfd_python-0.1.6.tar.gz
Algorithm Hash digest
SHA256 f1b04a41d845d10d2a6a42deb8bde976cf9d46b85f166bdc3a81da7119e0274c
MD5 76fe378f2eef80700521f8bdae7a0200
BLAKE2b-256 e7abac73c5058b230b51d0e95ab24cb355c4290bd38e105f3d9fc2fe7d17b42c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cfd_python-0.1.6.tar.gz:

Publisher: publish.yml on shaia/cfd-python

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

File details

Details for the file cfd_python-0.1.6-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: cfd_python-0.1.6-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 85.4 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for cfd_python-0.1.6-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4579861004ee186580ef3a177d53d64cbee59524fae49316182c96077faddc72
MD5 34da1af224136e5c6dc752ee32055466
BLAKE2b-256 266b98919b867bd83bf18d73654234f4dc027907579f2c64d8eedbac0889528c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cfd_python-0.1.6-cp39-abi3-win_amd64.whl:

Publisher: publish.yml on shaia/cfd-python

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

File details

Details for the file cfd_python-0.1.6-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cfd_python-0.1.6-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 18a9520e9a62791c07a032eb6559fd18a4192b735bd0d31ad0c532dee5c6064c
MD5 5140f3581e55ff2a4e518a15a8c2b177
BLAKE2b-256 09ef6c9cc2968a0903c43511e74783e9840e4d4e411b3bd3d69e327ec46b1025

See more details on using hashes here.

Provenance

The following attestation bundles were made for cfd_python-0.1.6-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on shaia/cfd-python

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

File details

Details for the file cfd_python-0.1.6-cp39-abi3-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for cfd_python-0.1.6-cp39-abi3-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 13656b96d0aecd0cc8aefab2d34c9bc34493cfb90533cfbac4a4a2dcad323533
MD5 6dcedbac5534c632d4aa42520515e103
BLAKE2b-256 dfd88be2187d98febef956797800bd305447046e7c72532dda931a25913bf5ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for cfd_python-0.1.6-cp39-abi3-macosx_15_0_arm64.whl:

Publisher: publish.yml on shaia/cfd-python

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