Python bindings for Voro++ with 2D/3D Voronoi and power/Laguerre tessellations, periodic topology utilities, and inverse power fitting.
Project description
pyvoro2
Documentation: https://delonecommons.github.io/pyvoro2/
pyvoro2 is a Python interface to the C++ library Voro++ for computing 2D and 3D Voronoi-type tessellations around a set of points:
- Voronoi tessellations (standard, unweighted)
- power / Laguerre tessellations (weighted Voronoi, via per-site radii)
- a dedicated planar namespace,
pyvoro2.planar, for 2D rectangular domains
The focus is not only on computing cells, but on making the results usable in scientific and geometric settings that need periodic boundary conditions, explicit neighbor-image shifts, reproducible topology/normalization utilities, and a reusable mathematical interface to Voronoi and power tessellations.
pyvoro2 is designed to be honest and predictable:
- it vendors and wraps an upstream Voro++ snapshot (with a small numeric robustness patch for power/Laguerre diagrams);
- the 3D top-level API stays separate from the 2D
pyvoro2.planarnamespace; - the core tessellation modes are standard Voronoi and power/Laguerre.
License note: starting with 0.6.0, the pyvoro2-authored code is released under LGPLv3+. Versions before 0.6.0 were released under MIT. Vendored third-party code remains under its own licenses.
Quickstart
1) Standard Voronoi in a 3D bounding box
For 3D visualization, install the optional dependency: pip install "pyvoro2[viz]".
import numpy as np
import pyvoro2 as pv
from pyvoro2.viz3d import view_tessellation
points = np.random.default_rng(0).uniform(-1.5, 1.5, size=(10, 3))
box = pv.Box(((-2, 2), (-2, 2), (-2, 2)))
cells = pv.compute(points, domain=box, mode='standard')
view_tessellation(
cells,
domain=box,
show_vertices=False,
)
2) Planar periodic workflow
import numpy as np
import pyvoro2.planar as pv2
pts2 = np.array([
[0.2, 0.2],
[0.8, 0.25],
[0.4, 0.8],
], dtype=float)
cell2 = pv2.RectangularCell(((0.0, 1.0), (0.0, 1.0)), periodic=(True, True))
result2 = pv2.compute(
pts2,
domain=cell2,
return_diagnostics=True,
normalize='topology',
)
diag2 = result2.require_tessellation_diagnostics()
topo2 = result2.require_normalized_topology()
3) Power/Laguerre tessellation (weighted Voronoi)
radii = np.full(len(points), 1.2)
cells = pv.compute(
points,
domain=box,
mode='power',
radii=radii,
include_empty=True, # power diagrams can have zero-volume cells
)
4) Periodic crystal cell with neighbor image shifts
cell = pv.PeriodicCell(
vectors=(
(10.0, 0.0, 0.0),
(2.0, 9.0, 0.0),
(1.0, 0.5, 8.0),
)
)
cells = pv.compute(points, domain=cell, return_face_shifts=True)
# Each face can include:
# adjacent_cell (neighbor id)
# adjacent_shift (which periodic image produced the face)
Numerical safety notes
Voro++ uses a few fixed absolute tolerances internally (most importantly a hard
near-duplicate check around ~1e-5 in container distance units). For very small
or very large coordinate systems, this can lead to hard process termination or
loss of accuracy.
pyvoro2 does not silently rescale your coordinates. If you work in unusual units, rescale explicitly before calling into the C++ layer.
As an additional safety net, you can ask pyvoro2 to run a fast Python-side near-duplicate pre-check before entering the C++ layer:
cells = pv.compute(points, domain=cell, duplicate_check='raise')
For stricter post-hoc checks, see:
pyvoro2.validate_tessellation(..., level='strict')pyvoro2.validate_normalized_topology(..., level='strict')pyvoro2.planar.validate_tessellation(..., level='strict')pyvoro2.planar.validate_normalized_topology(..., level='strict')
Note: pyvoro2 vendors a Voro++ snapshot that includes the upstream numeric robustness fix for power/Laguerre mode (radical pruning). This avoids rare cross-platform edge cases where fully periodic power tessellations could yield a non-reciprocal face/neighbor graph under aggressive floating-point codegen.
Why use pyvoro2
Voro++ is fast and feature-rich, but it is a C++ library with a low-level API. pyvoro2 aims to be a scientific interface that stays close to Voro++ while adding practical pieces that are easy to get wrong:
- triclinic periodic cells (
PeriodicCell) with robust coordinate mapping in 3D - partially periodic orthorhombic cells (
OrthorhombicCell) for slabs and wires - dedicated planar 2D support in
pyvoro2.planarfor boxes and rectangular periodic cells - optional periodic image shifts (
adjacent_shift) on faces/edges for building periodic graphs - diagnostics and normalization utilities for reproducible topology work
- convenience operations beyond full tessellation:
locate(...)/pyvoro2.planar.locate(...)(owner lookup for arbitrary query points)ghost_cells(...)/pyvoro2.planar.ghost_cells(...)(probe cell at a query point without inserting it)- power-fitting utilities for fitting power weights from desired pairwise separator locations in both 2D and 3D
Documentation overview
The documentation is written as a short scientific tutorial: it starts with the geometric ideas, then explains domains and operations, and only then dives into implementation-oriented details.
| Section | What it contains |
|---|---|
| Concepts | What Voronoi and power/Laguerre tessellations are, and what you can expect from them. |
| Domains (3D) | Which spatial containers exist (Box, OrthorhombicCell, PeriodicCell) and how to choose between them. |
| Planar (2D) | The planar namespace, current 2D domain scope, wrapper-level diagnostics/normalization convenience, and plotting. |
| Operations | How to compute tessellations, assign query points, and compute probe (ghost) cells in the 3D and planar namespaces. |
| Topology and graphs | How to build periodic neighbor graphs and how normalization helps in both 2D and 3D. |
| Power fitting | Fit power weights from pairwise bisector constraints, realized-boundary matching, and self-consistent active sets in 2D or 3D. |
| Visualization | Optional py3Dmol / matplotlib helpers for debugging and exploratory analysis. |
| Examples (notebooks) | End-to-end examples, including focused power-fitting notebooks for reports, infeasibility witnesses, and active-set path diagnostics. |
| API reference | The full reference (docstrings) for both the spatial and planar APIs. |
Installation
Most users should install a prebuilt wheel:
pip install pyvoro2
Optional extras:
pyvoro2[viz]for the 3Dpy3Dmolviewer (and 2D plotting too)pyvoro2[viz2d]for 2D matplotlib plotting onlypyvoro2[all]to install the full optional stack used for local notebook, docs, lint, and publishability checks
To build from source (requires a C++ compiler and Python development headers):
pip install -e .
For contributor-style local validation, install the full optional stack:
pip install -e ".[all]"
Testing
pyvoro2 uses pytest. The default test suite is intended to be fast and deterministic:
pip install -e ".[test]"
pytest
Additional test groups are opt-in:
-
Fuzz/property tests (randomized):
pytest -m fuzz --fuzz-n 100
-
Cross-check tests vs
pyvoro(requires installingpyvorofirst):pip install pyvoro pytest -m pyvoro --fuzz-n 100
-
Slow tests (if any are added in the future):
pytest -m slow
Tip: you can combine markers, e.g. pytest -m "fuzz and pyvoro" --fuzz-n 100.
Release and publishability checks
For a one-shot local publishability pass (lint, notebook execution, exported notebook sync, README sync, tests, docs, build, metadata checks, and wheel smoke test):
python tools/release_check.py
Project status
pyvoro2 is currently in beta.
The core tessellation modes (standard and power/Laguerre) are stable, and the
0.6.0 release now includes a first-class planar namespace.
A future 1.0 release is planned once the inverse-fitting workflow is more mature,
its disconnected-graph / coverage diagnostics are stabilized, and the project has
reassessed whether planar PeriodicCell support is actually needed.
AI-assisted development
Some parts of the implementation, tests, and documentation were developed with AI assistance (OpenAI ChatGPT). The maintainer reviews and integrates changes, and remains responsible for the resulting code and scientific claims.
Details are documented in the AI usage page.
License
- Starting with 0.6.0, the pyvoro2-authored code is released under the GNU Lesser General Public License v3.0 or later (LGPLv3+).
- Versions before 0.6.0 were released under the MIT License.
- Voro++ is vendored and redistributed under its original upstream license.
This README is auto-generated from the MkDocs sources in docs/.
To update it, edit the docs pages and re-run: python tools/gen_readme.py.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvoro2-0.6.3.tar.gz.
File metadata
- Download URL: pyvoro2-0.6.3.tar.gz
- Upload date:
- Size: 771.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65e35ac8292cd3e70f684a6707e3da2ec13a1056c394b985f119f60e8b4477d6
|
|
| MD5 |
6dc9b5ed3579c3f3df76b84abf69069b
|
|
| BLAKE2b-256 |
ca61f6b9ce6a205e1faaf5c19a2293ebd66c31638081959b3be740747c4b4704
|
File details
Details for the file pyvoro2-0.6.3-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 386.1 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14df72244bb0594385e6eff4e92ab53e4ce6c24505c7c98bd5483fdcbf66f980
|
|
| MD5 |
928ecdf08f6b0fd1f55af8629e9e4a4f
|
|
| BLAKE2b-256 |
39e01baa834c14da45a7493fe9b15aaf1d47c9bd998ed3172c8c1c3cf60ec834
|
File details
Details for the file pyvoro2-0.6.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 457.8 kB
- Tags: CPython 3.13, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
049f08de86f6ff41bf4d9b51b0bba167e6240db7167a9fe6e9b3c7940f584a44
|
|
| MD5 |
e2413e7522103fc1708a246222bc0a2d
|
|
| BLAKE2b-256 |
063ef2582f7d18f448520472e88d715b05128ce8cb4822a99bb53a2ea0818020
|
File details
Details for the file pyvoro2-0.6.3-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 367.5 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ed59c643444ce0b38d35b4e2a77d4179b91a17680679ccf7ebcf9a4fce300d4
|
|
| MD5 |
4e08cb0324ae29e27309bd9be6f174d7
|
|
| BLAKE2b-256 |
56fb97ae2c2b4120109be37ed2fbe6b3a218ec464dc947c5c3effa30266ff2a0
|
File details
Details for the file pyvoro2-0.6.3-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 386.1 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a2a310ece93bc5968a1eb5305fec56c313918c0c797c78a47b4fd85ac2ee17c
|
|
| MD5 |
cb22b9daf6c0b987608c3c209d4c8231
|
|
| BLAKE2b-256 |
a5444ccaedd2b1a74b95030192a3677db771703c865c08264b49dc9196796e25
|
File details
Details for the file pyvoro2-0.6.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 458.0 kB
- Tags: CPython 3.12, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52372180404da9df453289008c3ad32cd389bdf1c48563b4cd72edaf09b43490
|
|
| MD5 |
a10224f2d8924605d807e149fcd34146
|
|
| BLAKE2b-256 |
596d268fa9531614215f0b65de2b855c7f3060872ba72852da27ae8b2130f315
|
File details
Details for the file pyvoro2-0.6.3-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 367.4 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1b262a537886ca0f044f8a27f256786902fc09bf7b31a75400fc23bd0e9f231
|
|
| MD5 |
6d5874d30ee44f2edd439d4ce1c62d48
|
|
| BLAKE2b-256 |
85fe6323b7b7b64c1297ab228acb756094360e3abfba4d9d1f7d987df832d5d9
|
File details
Details for the file pyvoro2-0.6.3-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 384.4 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e5cd740ed396796bc50a8d0159ee820d84830614b2228ccba37d1b0ae11bd80
|
|
| MD5 |
44a61e2931db557c65159445f6814691
|
|
| BLAKE2b-256 |
3c682c1e5d279f4fc9e1da7a1ff51ca23403ec9fc669fc6a1f43d65e97c3ce49
|
File details
Details for the file pyvoro2-0.6.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 458.0 kB
- Tags: CPython 3.11, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
087f0235eec1c84b09c5a13631de6e5179d82f6cbfc96eb383778fb21c44dbc1
|
|
| MD5 |
e13ad6c384e5e37a7496b51f5bbf47b0
|
|
| BLAKE2b-256 |
b1601853f925d7a1e187ac3185d809ac24ce139f0ecd33c3b864a1d8d039e502
|
File details
Details for the file pyvoro2-0.6.3-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 368.6 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f23aed96e311bfd8eb1c7f713114898f57afcd3f084b4e0f04903f3324974e5
|
|
| MD5 |
3e27ac5d5f9a15f4d15c0208131616ab
|
|
| BLAKE2b-256 |
5f313aa117e3ebf02f9e7b991a2393fb680df158118e5749a7d87195cfd60bd1
|
File details
Details for the file pyvoro2-0.6.3-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 383.1 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f08d7b96641ac4cf18138c0ed1c202f71e7e50a0935fc6ccff83ca640b7fda7d
|
|
| MD5 |
971f8ec29a0eb298601093afdc30cff3
|
|
| BLAKE2b-256 |
d725005796b474a2c22dbf729a2d73eba1680f8c4672348adda04d192829b51c
|
File details
Details for the file pyvoro2-0.6.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 455.2 kB
- Tags: CPython 3.10, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c85347fd11b189dd7f12d143d709e8f7729b307c52b03191c4df8ba1c3764649
|
|
| MD5 |
220b7814de66aa9a646031da76ac4806
|
|
| BLAKE2b-256 |
e9886527f8397eb6c158b2ee956bb408636992f2568fdd510c9fc9849b1adb32
|
File details
Details for the file pyvoro2-0.6.3-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyvoro2-0.6.3-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 366.1 kB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
080bce59bbbbaa2914771bb015b6257be96546b286d16072272fbf566990c921
|
|
| MD5 |
92096cd3d47d995d19f216b298ddac94
|
|
| BLAKE2b-256 |
1e3b890568b5553c614480e923053fb46e5cff3b8e81d61f0b83492d3c6e5d22
|