# PySPH: writing SPH solvers in Python and letting Cython compile them

> PySPH is a Python framework for Smoothed Particle Hydrodynamics in which the physics you write in pure Python is translated to Cython or OpenCL and then compiled, with parallel backends for OpenMP, GPU and MPI. It fits researchers who need to prototype a new SPH formulation quickly, and it fits badly if you need a maintained 1.0 release or a predictable dependency set.

**pypr/pysph** — A framework for Smoothed Particle Hydrodynamics in Python

- Repository: https://github.com/pypr/pysph
- Website: http://pysph.readthedocs.io
- Stars: 548 · Forks: 153
- Language: Python
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/pypr-pysph

## The core idea: Python source that becomes compiled code

PySPH is a framework for Smoothed Particle Hydrodynamics, a meshless method for simulating fluids and solids, and the project description is as plain as it gets: a framework for Smoothed Particle Hydrodynamics in Python.

The mechanism is the interesting part. The README states that PySPH allows users to write their high-level code in pure Python, and that this Python code is automatically converted to high-performance Cython or OpenCL which is compiled and executed. The performance critical parts are implemented in Cython and PyOpenCL, and the framework can be configured to work with OpenMP, OpenCL and MPI.

That is a different bargain from writing a solver in Fortran or C. The physics, the equations of state, the boundary conditions and the integrator all stay in Python, which means a researcher can change a constitutive model and re-run in seconds rather than recompiling. The price is that the Python is not executed by the Python interpreter. It is translated, and the translation is what makes it fast.

The target reader is a computational scientist or graduate student working on SPH formulations, usually in fluid dynamics, free-surface flow, solid mechanics or gas dynamics. The topic list on the repository names fluid simulation, gas dynamics, high performance computing, message passing interface and scientific computing, so this is a research code, not a product.

The project is hosted by the pypr organisation and the documentation lives at pysph.readthedocs.org, with the readthedocs badge pointing at the main branch build.

## The library of formulations already implemented

The strongest argument for using PySPH rather than writing your own is the breadth of what ships with it, and the README enumerates it with references for each entry.

For the fluid formulations there is Weakly Compressible SPH for free-surface flows, the Transport Velocity Formulation for incompressible fluids, Compressible SPH, the Generalized Transport Velocity Formulation, Entropically Damped Artificial Compressibility, delta-SPH, Dual Time SPH, Incompressible SPH, Simple Iterative SPH, Implicit Incompressible SPH, Gudnov SPH, Conservative Reproducible Kernel SPH, Approximate Gudnov SPH, Adaptive Density Kernel Estimate and Akinci.

There is also a separate list of boundary conditions taken from published work, including Generalized Wall BCs, a do-nothing type outlet BC, Outlet Mirror BC, the Method of Characteristics BC and a Hybrid BC.

A third group covers the corrections that separate a stable SPH run from a noisy one: Corrected SPH, hg-correction, the tensile instability correction, and the particle shift algorithms of Xu et al and Skillen et al. Surface tension models follow, with the Morris surface tension and the Adami surface tension formulation.

Each of these is a pointer to a specific paper and a specific implementation, which is the practical value: reproducing a published formulation in PySPH is a matter of selecting it, and comparing your own variant against it is a matter of changing one option.

One piece of housekeeping: several entries in the README carry typos in the original text, such as incompressilbe and Incompressibel, and one reference carries a stray apostrophe in a link title. Cosmetic, but it is what the source says.

## Running the examples: pysph run and pysph view

The README gives a verification path for a new installation, and it starts with the quickest example it has.

```bash
    $ pysph run elliptical_drop
```

The README describes this as taking about 20 seconds, and it requires that Mayavi be installed. The saved output data is viewed by running:

```bash
    $ pysph view elliptical_drop_output/
```

A more demanding example is the 2D dam-break, which the README says takes about 30 minutes in total to run:

```bash
    $ pysph run dam_break_2d
```

Its solution can be viewed live from another shell:

```bash
    $ pysph view
```

The generated output can also be viewed, and the newly generated output files can be refreshed on the viewer UI.

Those four commands are the entire learning curve for a new user, and the design choice they reveal is sensible: the example names are the identifiers, and the runner and the viewer are separate programs. The `pysph view` step depends on Mayavi, so visualisation is an optional extra that you can skip if you only want numbers, and the README is explicit that Mayavi is required for that part.

The README also links to a playlist of videos of example problems solved with PySPH, which is a faster way to judge whether the framework's output style suits your work than reading the documentation.

## Build configuration lives in ~/.compyle/config.py, not in setup.py

The build is where a scientific Python project usually gets unpleasant, and PySPH's answer is to push the decisions into a user-level configuration file that overrides everything else.

The setup script documents the environment variables first. Setting `CC/CXX` lets you choose a custom compiler, and these can also be set in the config file. You can export `ZOLTAN` or `ZOLTAN_INCLUDE/ZOLTAN_LIBRARY` for the Zoltan partitioner.

Then there is the file-based route, described as trumping everything. The setup script points at `~/.compyle/config.py` and says the file can contain arbitrary Python that is exec'd. The variables defined there specify the compile and link args, and the examples in the file are:

```python
OMP_CFLAGS = ['-fopenmp']
OMP_LINK = ['-fopenmp']
```

The same file has a section for MPI options described as handy on clusters like a Cray, and a Zoltan options section with `USE_TRILINOS`, `ZOLTAN`, `ZOLTAN_INCLUDE` and `ZOLTAN_LIBRARY`. The comment in the file notes that `ZOLTAN` looks inside that path for the include and lib directories.

The practical consequence for a cluster is that the same source tree can be built for a laptop with OpenMP, a GPU with OpenCL, and a multi-node run with MPI and Zoltan, without editing the build script at all. The cost is that the configuration is invisible unless you know to look, since a build can behave differently on two machines with the same source and no obvious reason why.

The `Makefile` exposes the same knobs as targets: `build` runs `python setup.py build_ext --inplace`, `test` runs pytest excluding the slow tests, `testall` runs the full suite, and there are `develop` and `install` targets alongside `doc`, `clean` and `cleanall`. The subpackage list in the Makefile names the package layout as `base`, `sph`, `sph/solid_mech`, `parallel` and `tools`.

## The dependency set and the packaging story

The build requirements and the runtime requirements are essentially the same list, which is a sign that PySPH compiles most of what it uses. The build system requires `Beaker`, `Cython>=0.20`, `compyle>=0.8`, `cyarray`, `mako`, `numpy>=2.0,<3`, `pytools`, `setuptools>=42.0.0` and `wheel>=0.29.0`, and `requirements.txt` lists the same set with `numpy` and `Cython>=0.20`.

`compyle` and `pytools` are the two names worth knowing. Compyle is the extension generation machinery that turns the Python into compiled code, and its configuration file is the `~/.compyle/config.py` described above, which is why that file is PySPH's build entry point rather than a PySPH file at all. `pytools` supplies the general Python utilities. `cyarray` provides the typed array support that the performance critical code needs, and `mako` handles templating, which is how the generated solver code is assembled.

The numpy constraint deserves a second look. The build pins `numpy>=2.0,<3`, which is a narrow window on the single most widely shared dependency in the scientific Python stack, and it means a project that also pins numpy elsewhere has to agree with PySPH's range.

Packaging is a hybrid. The tree has `pyproject.toml` with a setuptools build backend, plus a `setup.py` that does the real configuration work, a `setup.cfg`, and a `Makefile`. There is also a `docker/` directory for container builds, a `starcluster/` directory for cluster launch configurations, `docs/`, a `tox.ini` for test environments, and `requirements-test.txt`.

The `pysph/` package directory carries the subpackages the Makefile refers to, and the `base`, `sph`, `parallel` and `tools` names line up with a design in which the physics, the parallel backends and the general utilities are separated.

## Maintenance, the 1.0b1 tag and the licence

Two facts in the project metadata deserve a careful reading before anyone builds on this.

The first is the release history. The repository has exactly one tagged release, 1.0b1, dated 2022-03-01, and the working tree has moved on considerably since. The last push was on 2026-08-23, so the code is being changed, but the tagged versions are scarce, and a team that pins a version is pinned to a beta from 2022 or to a moving commit. The README also does not document a release cadence, so treat the branch as the source of truth and keep your own note of the commit you build from.

The second is the licence. The repository is recorded under a custom licence that GitHub cannot classify, and the instruction is to see the LICENSE file. The tree carries `LICENSE.txt`, and the `MANIFEST.in` and `CHANGES.rst` files sit alongside it. The README itself does not state the terms, so anyone planning to publish code that depends on PySPH, or to redistribute it inside a commercial or closed project, needs to read `LICENSE.txt` directly. This is a note about where to look, not legal advice.

The comparison point that makes PySPH's position clear is a hand-written solver. The README claims the performance is comparable to hand-written solvers implemented in FORTRAN, and PySPH can also run the same code across OpenMP, OpenCL and MPI. A FORTRAN solver gives you raw speed and total control of the loop structure. PySPH gives you the ability to change the physics in Python, a library of published formulations, and the ability to move between CPU, GPU and cluster without rewriting the solver. The trade is between that flexibility and the control you get from owning every line of the discretisation.

## Conclusion

PySPH belongs in a research group that changes its SPH formulation every few months and needs to run the same code on a laptop, a GPU and a cluster, because the pure Python to Cython or OpenCL compilation path is the whole point and the library already ships a dozen published formulations to start from. It does not belong in a production pipeline that needs a stable release, since the only tagged release is 1.0b1 from 2022-03-01 and the last push was on 2026-08-23, and it does not belong if you cannot compile Cython extensions or install a compiler toolchain. Before adopting it, read the `LICENSE.txt` file, since the licence is a custom one that GitHub could not classify, and check the `~/.compyle/config.py` mechanism, because the build options there override everything the rest of the setup script decides.

## FAQ

### What is PySPH and who is it for?

PySPH is a Python framework for Smoothed Particle Hydrodynamics, a meshless method for fluid and solid simulation. It is aimed at researchers who write their SPH equations and integrators in pure Python and need the code compiled to Cython or OpenCL, with parallel backends for OpenMP, GPUs and MPI.

### How do I install PySPH?

The README points to the installation page at pysph.readthedocs.org for up to date instructions on Linux, OS X and Windows. The build needs Cython, compyle, cyarray, mako, numpy, pytools, Beaker and setuptools, and the `Makefile` provides a `build` target that runs `python setup.py build_ext --inplace`.

### How do I verify that PySPH is installed correctly?

The README suggests running the examples, starting with `pysph run elliptical_drop`, which it says takes about 20 seconds, then viewing the output with `pysph view elliptical_drop_output/`. The viewer requires Mayavi to be installed.

### How do I enable OpenMP, OpenCL or MPI in PySPH?

The setup script reads compiler and linker arguments from `~/.compyle/config.py`, a file that can contain arbitrary Python and overrides everything else. It defines `OMP_CFLAGS` and `OMP_LINK` for OpenMP, MPI options for clusters, and Zoltan options including `USE_TRILINOS`, `ZOLTAN`, `ZOLTAN_INCLUDE` and `ZOLTAN_LIBRARY`.

### Which SPH formulations and boundary conditions does PySPH implement?

The README lists among them Weakly Compressible SPH, Transport Velocity Formulation, Compressible SPH, delta-SPH, Incompressible SPH, Implicit Incompressible SPH, Akinci and several others, plus boundary conditions including Generalized Wall BCs, Outlet Mirror BC and the Method of Characteristics BC. It also lists corrections such as Corrected SPH, hg-correction, the tensile instability correction and particle shift algorithms.

## Sources

- [Issues](https://github.com/pypr/pysph/issues)
- [Project website](http://pysph.readthedocs.io)
- [pypr/pysph on GitHub](https://github.com/pypr/pysph)
- [README](https://github.com/pypr/pysph/blob/main/README.md)
- [Releases](https://github.com/pypr/pysph/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pypr-pysph
