Skip to main content

A small, readable numpy implementation of the SIMPLE/SIMPLER finite-volume pressure-velocity coupling — a forkable skeleton for writing your own CFD solver.

Project description

pysimpler

CI docs License: MIT Python deps: numpy

📖 Docs: https://alexlu997.github.io/pysimpler/

A small, readable numpy implementation of the SIMPLE / SIMPLER finite-volume pressure–velocity coupling (Patankar 1980) on a staggered grid — built as a study reference and a forkable skeleton for writing your own CFD solver.

  • numpy only. TDMA (tri-diagonal solver) is hand-rolled; no scipy/PETSc required.
  • SIMPLE and SIMPLER both implemented, side by side.
  • Verified: pure-conduction manufactured solution to machine precision; lid-driven cavity matches the Ghia et al. (1982) benchmark.
  • Textbook notation kept on purpose (aip/aim/ajp/ajm/ap/con, du/dv, diflow, solve/reset) so it maps cleanly onto any derivation and onto other languages.

Lid-driven cavity Re=100: streamlines and centreline velocity vs Ghia et al. 1982

Lid-driven cavity at Re=100 (SIMPLER): streamlines coloured by speed, and centreline velocity profiles overlaid on the Ghia et al. (1982) benchmark points. Reproduce with python docs/make_figure.py.

Install

pip install pysimpler-fvm       # from PyPI (import name stays: import pysimpler)
# or from a clone:
pip install -e .                # needs only numpy
pip install -e ".[test]"        # + pytest

The PyPI distribution is pysimpler-fvm (the bare name was taken), but the import name is unchanged — always import pysimpler.

Quickstart

import numpy as np
from pysimpler import Grid, SimpleField, simpler_iterate

g = Grid(L1=42, M1=42, XL=1.0, YL=1.0)     # 40x40 interior cells
s = SimpleField(g)
rho, mu = 1.0, 0.01                        # Re = rho*U*L/mu = 100

def lid(g, s):                             # BC hook (moving top lid)
    s.u[2, :] = 0; s.u[g.L1, :] = 0; s.v[:, 2] = 0; s.v[:, g.M1] = 0
    s.u[:, 1] = 0; s.u[:, g.M1] = 1.0; s.v[1, :] = 0; s.v[g.L1, :] = 0

for _ in range(400):
    smax, ssum = simpler_iterate(g, s, rho, mu, relax_u=0.8, relax_v=0.8, apply_bc=lid)
print("mass imbalance:", ssum)             # -> ~1e-15

Runnable demos in examples/: conduction.py (heat conduction, analytic check) and cavity.py (lid-driven cavity + a SIMPLE-vs-SIMPLER convergence comparison).

What's inside (pysimpler.py)

Piece Function/class Method
Staggered geometry Grid uniform Cartesian control volumes
Convection–diffusion scheme diflow Patankar power-law A(|P|)=max(0,(1−0.1|P|)^5)
Linear solver solve line TDMA (4-direction ADI) + additive/block correction
Scalar transport assemble_scalar aP·φ = Σ a_nb·φ_nb + b, source S_C + S_P·φ
SIMPLE coupling simple_iterate momentum → pressure-correction → correct u,v,p
SIMPLER coupling simpler_iterate pseudo-velocities → pressure equation → correct u,v

Verified results

Test Gate Result
Conduction (x+y+xy) max|T−(x+y+xy)| < 1e-6 5.6e-15 (discrete-exact)
Lid cavity Re=100, 22² mass imbalance → 0, bounded, no NaN SSUM → ~1e-15, |u|max=0.835
SIMPLER vs SIMPLE fewer outer iters to SSUM<1e-8 121 vs 405 (≈3.3× faster), same field
pytest            # runs all four gates above

Extending it (the one idea)

Every physics — buoyancy, swirl, turbulence sources, variable properties — enters through just two things: the effective diffusion Γ and the linearised source S = S_C + S_P·φ (keep S_P ≤ 0). Add your term there, not as a new code path, and the same engine solves it. Non-Cartesian geometries add curvature source terms only.

Contributing

See CONTRIBUTING.md. In short: keep it readable, keep the pytest gates green, numpy-only in the core.

Publishing to PyPI (maintainers)

Releases publish to PyPI automatically via Trusted Publishing (OIDC — no token in the repo). One-time setup on pypi.org: add a pending publisher with PyPI Project Name pysimpler-fvm, owner alexlu997, repo pysimpler, workflow publish.yml, environment pypi. Then each GitHub Release (e.g. tag v0.1.0) triggers .github/workflows/publish.yml, which builds and uploads the wheel

  • sdist. After the first successful publish: pip install pysimpler-fvm.

Provenance & license

Independent from-scratch re-implementation; structure follows the classic XJTU (Prof. 陶文铨 group) staggered-grid SIMPLER teaching code. The original teaching Fortran is not included (teaching-only). MIT licensed — see LICENSE and NOTICE. Please also credit Patankar (1980) in academic use.

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

pysimpler_fvm-0.1.0.tar.gz (16.6 kB view details)

Uploaded Source

Built Distribution

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

pysimpler_fvm-0.1.0-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file pysimpler_fvm-0.1.0.tar.gz.

File metadata

  • Download URL: pysimpler_fvm-0.1.0.tar.gz
  • Upload date:
  • Size: 16.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pysimpler_fvm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ff239709fdb5fb7db87a07c79652f87d3f79654043de959b7c3390ddb1ac9912
MD5 382a6f104e63027f7d9a0e43cccd24ac
BLAKE2b-256 837f0e342ac7dee64e829dbc3056e4a13926e9640faaf041b184fd01d1893d7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysimpler_fvm-0.1.0.tar.gz:

Publisher: publish.yml on alexlu997/pysimpler

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

File details

Details for the file pysimpler_fvm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pysimpler_fvm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pysimpler_fvm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 da9546e891c5c06f3fdb8d8641a871b657932251e169aa6812cdb299d24f5864
MD5 21f466fec6c110761241cd176cc6892d
BLAKE2b-256 6280178c1527132dbb94e850410a035ea2f81124df1a3be067378921fcd99e96

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysimpler_fvm-0.1.0-py3-none-any.whl:

Publisher: publish.yml on alexlu997/pysimpler

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