Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.2
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
41 changes: 21 additions & 20 deletions cfd_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

# Get version from package metadata (setuptools-scm) or fall back to C module
try:
from importlib.metadata import version, PackageNotFoundError
from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("cfd-python")
except PackageNotFoundError:
Expand Down Expand Up @@ -54,36 +55,35 @@
]

try:
# Import the C extension module to access dynamic solver constants
from . import cfd_python as _cfd_module
from .cfd_python import (
# Simulation functions
run_simulation,
OUTPUT_CSV_CENTERLINE,
OUTPUT_CSV_STATISTICS,
OUTPUT_CSV_TIMESERIES,
OUTPUT_FULL_FIELD,
# Output type constants
OUTPUT_PRESSURE,
OUTPUT_VELOCITY,
create_grid,
get_default_solver_params,
run_simulation_with_params,
get_solver_info,
has_solver,
# Solver functions
list_solvers,
has_solver,
get_solver_info,
# Simulation functions
run_simulation,
run_simulation_with_params,
# Output functions
set_output_dir,
write_csv_timeseries,
write_vtk_scalar,
write_vtk_vector,
write_csv_timeseries,
# Output type constants
OUTPUT_PRESSURE,
OUTPUT_VELOCITY,
OUTPUT_FULL_FIELD,
OUTPUT_CSV_TIMESERIES,
OUTPUT_CSV_CENTERLINE,
OUTPUT_CSV_STATISTICS,
)

# Import the C extension module to access dynamic solver constants
from . import cfd_python as _cfd_module

# Fall back to C module version if metadata lookup failed
if __version__ is None:
__version__ = getattr(_cfd_module, '__version__', '0.0.0')
__version__ = getattr(_cfd_module, "__version__", "0.0.0")

# Dynamically export all SOLVER_* constants from the C module
# This allows new solvers to be automatically available without
Expand All @@ -101,11 +101,12 @@
# Check if this is a development environment (source checkout without built extension)
# vs a broken installation (extension exists but fails to load)
import os as _os

_package_dir = _os.path.dirname(__file__)

# Look for compiled extension files
_extension_exists = any(
f.startswith('cfd_python') and (f.endswith('.pyd') or f.endswith('.so'))
f.startswith("cfd_python") and (f.endswith(".pyd") or f.endswith(".so"))
for f in _os.listdir(_package_dir)
)

Expand All @@ -120,4 +121,4 @@
# Development mode - module not yet built
__all__ = _CORE_EXPORTS
if __version__ is None:
__version__ = "0.0.0-dev"
__version__ = "0.0.0-dev"
14 changes: 10 additions & 4 deletions dev_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
python build.py clean # Clean build artifacts
python build.py all # Clean, build, install, and test
"""

import argparse
import shutil
import subprocess
import sys
import shutil
import argparse
from pathlib import Path

# Project paths
Expand Down Expand Up @@ -116,7 +117,12 @@ def clean():
def verify():
"""Verify the installation works"""
print("\n=== Verifying Installation ===")
result = run(f'{sys.executable} -c "import cfd_python; print(f\'Version: {{cfd_python.__version__}}\'); print(f\'Solvers: {{cfd_python.list_solvers()}}\')"', check=False)
verify_cmd = (
f'{sys.executable} -c "import cfd_python; '
f"print(f'Version: {{cfd_python.__version__}}'); "
f"print(f'Solvers: {{cfd_python.list_solvers()}}')\""
)
result = run(verify_cmd, check=False)
return result.returncode == 0


Expand All @@ -127,7 +133,7 @@ def main():
nargs="?",
default="develop",
choices=["build", "install", "develop", "test", "clean", "all", "verify", "cfd"],
help="Command to run (default: develop)"
help="Command to run (default: develop)",
)

args = parser.parse_args()
Expand Down
30 changes: 11 additions & 19 deletions examples/basic_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
for running fluid dynamics simulations.
"""

import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

try:
import cfd_python
import numpy as np

import cfd_python
except ImportError as e:
print(f"Import error: {e}")
print("Make sure to build the package first:")
Expand All @@ -36,7 +38,7 @@ def main():
ymin, ymax = 0.0, 1.0
steps = 50

print(f"\nSimulation Setup:")
print("\nSimulation Setup:")
print(f" Grid: {nx} x {ny}")
print(f" Domain: [{xmin}, {xmax}] x [{ymin}, {ymax}]")
print(f" Steps: {steps}")
Expand All @@ -47,10 +49,7 @@ def main():
print("-" * 50)

vel_mag = cfd_python.run_simulation(
nx=nx, ny=ny,
steps=steps,
xmin=xmin, xmax=xmax,
ymin=ymin, ymax=ymax
nx=nx, ny=ny, steps=steps, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax
)

vel_array = np.array(vel_mag)
Expand All @@ -64,9 +63,7 @@ def main():
print("-" * 50)

vel_mag_vtk = cfd_python.run_simulation(
nx=nx, ny=ny,
steps=steps,
output_file="basic_output.vtk"
nx=nx, ny=ny, steps=steps, output_file="basic_output.vtk"
)
print(f" Output: basic_output.vtk ({len(vel_mag_vtk)} points)")

Expand All @@ -76,17 +73,12 @@ def main():
print("-" * 50)

result = cfd_python.run_simulation_with_params(
nx=nx, ny=ny,
xmin=xmin, xmax=xmax,
ymin=ymin, ymax=ymax,
steps=25,
dt=0.0005,
cfl=0.2
nx=nx, ny=ny, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, steps=25, dt=0.0005, cfl=0.2
)

print(f" Grid: {result['nx']} x {result['ny']}")
if 'stats' in result:
stats = result['stats']
if "stats" in result:
stats = result["stats"]
print(f" Max velocity: {stats.get('max_velocity', 'N/A')}")
print(f" Iterations: {stats.get('iterations', 'N/A')}")

Expand Down
53 changes: 27 additions & 26 deletions examples/lid_driven_cavity.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,36 @@
- Comparing solver performance
"""

import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

import cfd_python
import numpy as np
import tempfile
from pathlib import Path

import numpy as np

import cfd_python


def run_cavity_simulation(nx, ny, steps, solver_type=None, output_dir=None):
"""Run a lid-driven cavity simulation."""
kwargs = {
'nx': nx,
'ny': ny,
'steps': steps,
'xmin': 0.0,
'xmax': 1.0,
'ymin': 0.0,
'ymax': 1.0,
"nx": nx,
"ny": ny,
"steps": steps,
"xmin": 0.0,
"xmax": 1.0,
"ymin": 0.0,
"ymax": 1.0,
}

if solver_type:
kwargs['solver_type'] = solver_type
kwargs["solver_type"] = solver_type

if output_dir:
kwargs['output_file'] = str(output_dir / f"cavity_{nx}x{ny}_{steps}steps.vtk")
kwargs["output_file"] = str(output_dir / f"cavity_{nx}x{ny}_{steps}steps.vtk")

result = cfd_python.run_simulation(**kwargs)
return np.array(result).reshape((ny, nx))
Expand All @@ -46,22 +49,22 @@ def run_cavity_simulation(nx, ny, steps, solver_type=None, output_dir=None):
def analyze_results(vel_mag, nx, ny):
"""Analyze the velocity field."""
# Find vortex center (location of minimum velocity in central region)
center_region = vel_mag[ny//4:3*ny//4, nx//4:3*nx//4]
center_region = vel_mag[ny // 4 : 3 * ny // 4, nx // 4 : 3 * nx // 4]
min_idx = np.unravel_index(np.argmin(center_region), center_region.shape)

# Adjust indices for full grid
vortex_y = min_idx[0] + ny//4
vortex_x = min_idx[1] + nx//4
vortex_y = min_idx[0] + ny // 4
vortex_x = min_idx[1] + nx // 4

# Normalize to [0,1] domain
vortex_x_norm = vortex_x / (nx - 1)
vortex_y_norm = vortex_y / (ny - 1)

return {
'max_velocity': np.max(vel_mag),
'min_velocity': np.min(vel_mag),
'mean_velocity': np.mean(vel_mag),
'vortex_center': (vortex_x_norm, vortex_y_norm),
"max_velocity": np.max(vel_mag),
"min_velocity": np.min(vel_mag),
"mean_velocity": np.mean(vel_mag),
"vortex_center": (vortex_x_norm, vortex_y_norm),
}


Expand All @@ -88,13 +91,11 @@ def main():
vel_mag = run_cavity_simulation(n, n, steps, output_dir=output_dir)
analysis = analyze_results(vel_mag, n, n)

results.append({
'grid': n,
**analysis
})
results.append({"grid": n, **analysis})

print(f" Max velocity: {analysis['max_velocity']:.6f}")
print(f" Vortex center: ({analysis['vortex_center'][0]:.3f}, {analysis['vortex_center'][1]:.3f})")
vx, vy = analysis["vortex_center"]
print(f" Vortex center: ({vx:.3f}, {vy:.3f})")

# Reference values (Ghia et al., 1982 for Re=100)
print("\n2. Comparison with Reference Data")
Expand All @@ -104,7 +105,7 @@ def main():
print()

for r in results:
vx, vy = r['vortex_center']
vx, vy = r["vortex_center"]
print(f" Grid {r['grid']:3d}x{r['grid']:<3d}: vortex at ({vx:.3f}, {vy:.3f})")

# Solver comparison
Expand Down
Loading
Loading