diff --git a/.github/workflows/performance-benchmarking.yml b/.github/workflows/performance-benchmarking.yml index b8c7eb9b..ff1ab5e7 100644 --- a/.github/workflows/performance-benchmarking.yml +++ b/.github/workflows/performance-benchmarking.yml @@ -69,16 +69,16 @@ jobs: run: | if [ "$RUNNER_OS" == "Linux" ]; then sudo apt-get update - sudo apt-get install -y valgrind linux-tools-common + sudo apt-get install -y valgrind linux-tools-common libfontconfig1-dev fi - name: Build benchmarks - run: cargo build --release --bench comprehensive_cfd_benchmarks + run: cargo build --release --bench performance_benchmarks - name: Run comprehensive benchmarks if: github.event.inputs.benchmark_type == 'comprehensive' || github.event_name != 'workflow_dispatch' run: | - cargo bench --bench comprehensive_cfd_benchmarks | tee benchmark_results.txt + cargo bench --bench performance_benchmarks | tee benchmark_results.txt - name: Run regression detection benchmarks if: github.event.inputs.benchmark_type == 'regression' || github.event_name == 'schedule' diff --git a/.gitignore b/.gitignore index 066d60e1..f4a91c5a 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,5 @@ report/ *.dll *.so *.dylib +venv/ +__pycache__/ diff --git a/validation/compare_cavity_external.py b/validation/compare_cavity_external.py index 2d0b092e..d3d7cdcf 100644 --- a/validation/compare_cavity_external.py +++ b/validation/compare_cavity_external.py @@ -15,6 +15,7 @@ import numpy as np import matplotlib.pyplot as plt from pathlib import Path +from scipy.interpolate import RectBivariateSpline # Add validation directory to path sys.path.insert(0, str(Path(__file__).parent)) @@ -49,24 +50,26 @@ def run_cfd_python_cavity(Re: float = 100, nx: int = 65, ny: int = 65): if hasattr(cfd_python, 'CavitySolver2D'): solver = cfd_python.CavitySolver2D( nx=nx, ny=ny, - Re=Re, - tolerance=1e-6, - max_iterations=20000 + reynolds=Re ) result = solver.solve() - return { - "u": np.array(result.u_field), - "v": np.array(result.v_field), - "p": np.array(result.p_field), - "u_centerline": np.array(result.u_centerline), - "v_centerline": np.array(result.v_centerline), - "x": np.array(result.x_coords), - "y": np.array(result.y_coords), - "converged": result.converged, - "iterations": result.iterations, - "residual": result.residual - } + if hasattr(result, "u_field"): + return { + "u": np.array(result.u_field), + "v": np.array(result.v_field), + "p": np.array(result.p_field), + "u_centerline": np.array(result.u_centerline), + "v_centerline": np.array(result.v_centerline), + "x": np.array(result.x_coords), + "y": np.array(result.y_coords), + "converged": result.converged, + "iterations": getattr(result, "iterations", 0), + "residual": getattr(result, "residual", 0.0) + } + else: + print("WARN: cfd_python cavity solver does not export full fields, skipping 2D comparison.") + return None else: print("WARN: CavitySolver2D not found in cfd_python - using placeholder") # Return dummy data matching external reference dimensions @@ -103,9 +106,32 @@ def compare_solutions(cfd_python_result, external_result, Re: float): # Ensure same grid size if cfd_python_result["u"].shape != ext_sol["u"].shape: - print(f"WARN: Grid size mismatch: cfd_python {cfd_python_result['u'].shape} vs external {ext_sol['u'].shape}") - # TODO: Interpolate if needed - return None + print(f"INFO: Interpolating cfd_python results from {cfd_python_result['u'].shape} to external {ext_sol['u'].shape} grid") + + # Original grid (assuming regular grid) + # Note: RectBivariateSpline expects strictly increasing x and y + x_orig = cfd_python_result["x"] + y_orig = cfd_python_result["y"] + + # Target grid + x_new = ext_sol["x"] + y_new = ext_sol["y"] + + # Interpolate fields (transpose as RectBivariateSpline expects [x, y] ordering) + spline_u = RectBivariateSpline(x_orig, y_orig, cfd_python_result["u"].T) + spline_v = RectBivariateSpline(x_orig, y_orig, cfd_python_result["v"].T) + spline_p = RectBivariateSpline(x_orig, y_orig, cfd_python_result["p"].T) + + # Evaluate on new grid (and transpose back to [y, x] ordering) + cfd_python_result["u"] = spline_u(x_new, y_new).T + cfd_python_result["v"] = spline_v(x_new, y_new).T + cfd_python_result["p"] = spline_p(x_new, y_new).T + + # Update centerlines and coordinates + cfd_python_result["u_centerline"] = cfd_python_result["u"][:, len(x_new) // 2] + cfd_python_result["v_centerline"] = cfd_python_result["v"][len(y_new) // 2, :] + cfd_python_result["x"] = x_new + cfd_python_result["y"] = y_new # Compute L2 errors u_diff = cfd_python_result["u"] - ext_sol["u"]