peclet-core 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- peclet/core/__init__.py +25 -0
- peclet/core/geom.py +9 -0
- peclet/core/mpi.py +9 -0
- peclet_core-1.1.0.dist-info/METADATA +138 -0
- peclet_core-1.1.0.dist-info/RECORD +7 -0
- peclet_core-1.1.0.dist-info/WHEEL +4 -0
- peclet_core-1.1.0.dist-info/licenses/LICENSE +21 -0
peclet/core/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""peclet.core — the pre-1.2 home of `peclet.geom` and `peclet.halo`.
|
|
2
|
+
|
|
3
|
+
This package is a thin compatibility shell. Its two submodules re-export, unchanged, the objects
|
|
4
|
+
that now live in the `peclet-geom` and `peclet-halo` distributions:
|
|
5
|
+
|
|
6
|
+
peclet.core.geom -> peclet.geom (package peclet-geom, wheels)
|
|
7
|
+
peclet.core.mpi -> peclet.halo (package peclet-halo, sdist, needs MPI)
|
|
8
|
+
|
|
9
|
+
They are the *same objects*, not wrappers: ``peclet.core.geom.SceneBuilder is
|
|
10
|
+
peclet.geom.SceneBuilder`` is True, so isinstance, pickling and docs all behave as before.
|
|
11
|
+
|
|
12
|
+
Why the split: `peclet.core.geom` is host-only SDF authoring with no MPI in it, but it shared a
|
|
13
|
+
distribution with the halo bindings whose build requires an MPI toolchain — so a pure-geometry API
|
|
14
|
+
could not be pip-installed without MPI. See suite/docs/CORE_BOUNDARY.md.
|
|
15
|
+
|
|
16
|
+
These spellings keep working unchanged in peclet 1.2.0, gain a DeprecationWarning in 1.3.0, and are
|
|
17
|
+
removed in 2.0.0. The canonical spellings are ``from peclet import geom`` and
|
|
18
|
+
``from peclet import halo``.
|
|
19
|
+
"""
|
|
20
|
+
from importlib.metadata import PackageNotFoundError, version as _version
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
__version__ = _version("peclet-core")
|
|
24
|
+
except PackageNotFoundError: # a source tree / build tree has no dist-info
|
|
25
|
+
__version__ = "0+unknown"
|
peclet/core/geom.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""peclet.core.geom — the pre-1.2 spelling of peclet.geom; `from peclet import geom` is canonical.
|
|
2
|
+
|
|
3
|
+
Re-exports peclet.geom unchanged: the objects here ARE the objects there. Works unchanged in
|
|
4
|
+
peclet 1.2.0, warns in 1.3.0, removed in 2.0.0 (suite/docs/CORE_BOUNDARY.md).
|
|
5
|
+
"""
|
|
6
|
+
from peclet.geom import * # noqa: F401,F403
|
|
7
|
+
from peclet import geom as _canonical
|
|
8
|
+
|
|
9
|
+
__all__ = [n for n in dir(_canonical) if not n.startswith("_")]
|
peclet/core/mpi.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""peclet.core.mpi — the pre-1.2 spelling of peclet.halo; `from peclet import halo` is canonical.
|
|
2
|
+
|
|
3
|
+
Re-exports peclet.halo unchanged: the objects here ARE the objects there. Works unchanged in
|
|
4
|
+
peclet 1.2.0, warns in 1.3.0, removed in 2.0.0 (suite/docs/CORE_BOUNDARY.md).
|
|
5
|
+
"""
|
|
6
|
+
from peclet.halo import * # noqa: F401,F403
|
|
7
|
+
from peclet import halo as _canonical
|
|
8
|
+
|
|
9
|
+
__all__ = [n for n in dir(_canonical) if not n.startswith("_")]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: peclet-core
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: peclet.core — compatibility shell: peclet.core.geom is now peclet.geom, peclet.core.mpi is now peclet.halo
|
|
5
|
+
Project-URL: Homepage, https://github.com/computational-chemical-engineering/peclet
|
|
6
|
+
Project-URL: Documentation, https://computational-chemical-engineering.github.io/peclet/
|
|
7
|
+
Project-URL: Source, https://github.com/computational-chemical-engineering/peclet-core
|
|
8
|
+
Author-email: "E.A.J.F. Peters" <e.a.j.f.peters@tue.nl>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: peclet-geom<2,>=1.0
|
|
17
|
+
Requires-Dist: peclet-halo<2,>=1.1
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# core
|
|
21
|
+
|
|
22
|
+
[](https://pypi.org/project/peclet-core/)
|
|
23
|
+
[](https://pypi.org/project/peclet-core/)
|
|
24
|
+
[](https://github.com/computational-chemical-engineering/peclet-core/blob/main/LICENSE)
|
|
25
|
+
[](https://github.com/computational-chemical-engineering/peclet-core/actions/workflows/ci.yml)
|
|
26
|
+
[](https://doi.org/10.5281/zenodo.21132435)
|
|
27
|
+
|
|
28
|
+
Shared infrastructure for the **peclet** suite (see `../docs/` for the suite-wide
|
|
29
|
+
[architecture](../docs/ARCHITECTURE.md), [conventions](../docs/CONVENTIONS.md),
|
|
30
|
+
[style](../docs/STYLE.md), [interfaces](../docs/INTERFACES.md) and [roadmap](../docs/ROADMAP.md)).
|
|
31
|
+
|
|
32
|
+
It provides the pieces every method code (`flow`, `dem`, `voro`, …) should
|
|
33
|
+
share: a common MPI **block domain decomposition**, an efficient **asynchronous ghost-layer
|
|
34
|
+
exchange** (CPU + portable Kokkos GPU), **particle migration**, **dynamic load balancing**, unified
|
|
35
|
+
**SDF geometry** (`peclet::core::geom`), the **face-CSR solver layer** (`peclet::core::solver`) and
|
|
36
|
+
**nanobind Python bindings**. Header-only C++20 (the device side, compiled through Kokkos, is also
|
|
37
|
+
C++20; only the `morton` dependency pins C++17 — see `../docs/STYLE.md`). The AMR octree and the
|
|
38
|
+
Navier–Stokes solver on it are the separate [peclet-amr](https://github.com/computational-chemical-engineering/peclet-amr)
|
|
39
|
+
package (`peclet::amr`, `peclet.amr`) since 2026-09-10 — relocated out of this tree with its history.
|
|
40
|
+
|
|
41
|
+
## What works today
|
|
42
|
+
|
|
43
|
+
- `peclet::core::decomp::BlockDecomposer<Dim>` — orthogonal recursive bisection of a global cell grid into
|
|
44
|
+
rank-owned blocks; `ownerOf()` tree-walk; x-fastest global/local linear indexing.
|
|
45
|
+
- `peclet::core::decomp::BlockIndexer<Dim>` — local↔global indexing for a block with a ghost layer.
|
|
46
|
+
- `peclet::core::halo::NbxEngine` — nonblocking-consensus sparse exchange (Issend + Ibarrier), for dynamic
|
|
47
|
+
patterns.
|
|
48
|
+
- `peclet::core::halo::GridHaloTopology<Dim>` (`grid_halo_topology.hpp`) — asynchronous ghost-layer exchange
|
|
49
|
+
with **topology separated from exchange** and a **field-agnostic** pack/unpack interface.
|
|
50
|
+
`buildTopology()` runs once; two interchangeable exchange engines give identical results:
|
|
51
|
+
- `exchangeNbx()` / `start()`+`wait()` — NBX, supports compute/comm overlap.
|
|
52
|
+
- `exchangePersistent()` — `MPI_Neighbor_alltoallv` on a cached distributed-graph communicator;
|
|
53
|
+
fastest for the static neighbour pattern of a fixed grid.
|
|
54
|
+
- `peclet::core::halo::GridFieldView<T>` — wraps a contiguous local array as an exchangeable field.
|
|
55
|
+
- `peclet::core::halo::GridHalo<T>` (`grid_halo.hpp`) — portable **GPU-resident** ghost-layer exchange (Kokkos:
|
|
56
|
+
CUDA / HIP / OpenMP). Built once from a host `GridHaloTopology<Dim>::flatten()`; pack / unpack /
|
|
57
|
+
periodic self-copy run as `Kokkos::parallel_for` over the device `peclet::core::View<T>` field, so the full
|
|
58
|
+
field never crosses the bus — only the compact halo buffers are host-staged for MPI by default, with
|
|
59
|
+
an opt-in GPU-aware path (env `PECLET_CORE_GPU_AWARE_MPI`). Bit-for-bit identical to the CPU exchange.
|
|
60
|
+
- `peclet::core::halo::ParticleMigrator<Dim>` — Lagrangian particle migration to owning ranks (NBX), the
|
|
61
|
+
dynamic counterpart to the Eulerian grid halo.
|
|
62
|
+
- `peclet::core::halo::ParticleHaloTopology<Dim>` (`particle_halo_topology.hpp`) — persistent Lagrangian ghost
|
|
63
|
+
halo: `forward` (owner→ghost), `reverse` (ghost→owner, accumulate) and `forwardPositions` (periodic
|
|
64
|
+
image shift). `peclet::core::halo::ParticleHalo<Dim>` (`particle_halo.hpp`) is its GPU-resident Kokkos driver
|
|
65
|
+
(on-device gather/scatter, host-staged or GPU-aware MPI), consumed by dem's distributed step.
|
|
66
|
+
- `peclet::core::halo::rebalanceByParticleCount(...)` (`particle_rebalance.hpp`) — **dynamic load balancing**
|
|
67
|
+
for the Lagrangian path: re-inits the decomposition in place with the **weighted ORB**
|
|
68
|
+
(`BlockDecomposer::init(numBlocks, globalSize, weights)`) and migrates. The Eulerian/AMR counterpart
|
|
69
|
+
is `peclet::amr::DistributedOctree::rebalance` (peclet-amr).
|
|
70
|
+
- `peclet::core::geom` (`sdf.hpp`, `grid_sdf.hpp`, `vti_io.hpp`) — shared SDF solids: analytic primitives +
|
|
71
|
+
trilinear `GridSdf` behind one `Sdf` concept, with VTI (.vti) read/write.
|
|
72
|
+
- `peclet::core::vof` (`include/peclet/core/vof/`) — layer L1 of the VoF stack: container-free
|
|
73
|
+
`KOKKOS_INLINE_FUNCTION` kernels (PLIC plane↔volume and normals, the height-function curvature
|
|
74
|
+
cascade, the cut-cell colour-transport rules, wetting). No `Kokkos::View` and no grid indexing in
|
|
75
|
+
any signature, so one copy serves every VoF container; the drivers live in `flow`.
|
|
76
|
+
- `peclet::core::solver` (`include/peclet/core/solver/`) — mesh-agnostic linear algebra: the
|
|
77
|
+
smoothed-aggregation graph AMG (`graph_amg.hpp`, host setup; `graph_amg_device.hpp`, device apply)
|
|
78
|
+
and the **assembled face-CSR operator layer** lifted out of the AMR tree on 2026-09-10 —
|
|
79
|
+
`face_csr.hpp` (host+device row kernels), `coloring.hpp` (greedy symmetrised graph colouring),
|
|
80
|
+
`csr_operator.hpp` (the device operator, Jacobi and multicolour Gauss–Seidel sweeps),
|
|
81
|
+
`csr_bicgstab.hpp` (preconditioned BiCGStab / defect correction) and `vector_ops.hpp`. Consumed by
|
|
82
|
+
voro's mesh optimiser and by peclet-amr.
|
|
83
|
+
- **Python bindings** (`python/mpi_bindings.cpp`, `python/geom_bindings.cpp`) —
|
|
84
|
+
**nanobind** modules over the shared zero-copy `View`↔ndarray bridge
|
|
85
|
+
(`include/peclet/core/python/ndarray_interop.hpp`). `peclet.core.mpi` exposes the host Lagrangian halo
|
|
86
|
+
(`ParticleMigrator`, `ParticleHalo`: migration / ghosts / rebalance); `peclet.core.geom` the analytic-SDF
|
|
87
|
+
scene authoring + rigid-body mass properties. Type stubs ship beside the modules
|
|
88
|
+
(`python/packaging/core_*.pyi`, generated with `python -m nanobind.stubgen`). `python/state_hash.py`
|
|
89
|
+
is the structural byte gate: fixed-seed runs of every entry path, SHA-256 of the final state.
|
|
90
|
+
|
|
91
|
+
Validated end-to-end by distributed explicit heat-diffusion solvers (plain, and **around an SDF solid
|
|
92
|
+
obstacle**) matching a serial reference cell-for-cell across ranks, and consumed by the validated
|
|
93
|
+
`flow` and `dem` distributed solvers. 53 ctests in the plain host+MPI build, 68 with Kokkos (`np` 1–8), plus 6
|
|
94
|
+
Python ctests in the `python/` build.
|
|
95
|
+
|
|
96
|
+
## Build / test / benchmark
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
|
100
|
+
cmake --build build -j
|
|
101
|
+
ctest --test-dir build --output-on-failure -LE bench # 52 ctests: serial + MPI (np=1,2,4,8); 67 with -DPECLET_CORE_ENABLE_KOKKOS=ON
|
|
102
|
+
ctest --test-dir build -L bench # the halo benchmark (label `bench`)
|
|
103
|
+
|
|
104
|
+
# halo microbenchmark: weak scaling, NBX vs persistent
|
|
105
|
+
mpirun -np 4 ./build/benchmarks/bench_halo 48 1 300 # cells/rank/axis, ghost, iters
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
ctest labels: `mpi` (every mpirun test), `np8` (the 8-rank instances — a local gate, excluded in CI whose
|
|
109
|
+
runners have 4 cores), `bench` (benchmarks/studies, excluded by default). A test that cannot run in a
|
|
110
|
+
configuration (no `morton` sibling: `morton_indexer`) exits 77 and ctest reports it **skipped**, never
|
|
111
|
+
passed. The Python modules and their tests (`test_mpi.py` np=1,2,4,8, `state_hash.py`, the
|
|
112
|
+
ndarray-interop pytest) are a second CMake project: `cmake -S python -B build_py
|
|
113
|
+
-DCMAKE_PREFIX_PATH=<kokkos prefix> && cmake --build build_py -j && ctest --test-dir build_py`.
|
|
114
|
+
|
|
115
|
+
Requires MPI (OpenMPI/MPICH) and a C++20 compiler (`-DPECLET_CORE_ENABLE_MPI=OFF` builds the
|
|
116
|
+
single-rank no-MPI stub). `morton` is picked up automatically if checked out as a sibling directory
|
|
117
|
+
(enables `PECLET_CORE_HAVE_MORTON`; `-DPECLET_CORE_MORTON_DIR=<dir>` points elsewhere). CI builds all
|
|
118
|
+
three configurations (host+MPI gcc/clang Debug/Release, Kokkos-OpenMP + Python, no-MPI) against the
|
|
119
|
+
pinned `morton` tag. The CMake project is
|
|
120
|
+
`peclet_core` (its version is read from `pyproject.toml`); it exports the header-only targets
|
|
121
|
+
`peclet::core` and `peclet::halo` (`cmake --install` + `find_package(peclet-core CONFIG)`).
|
|
122
|
+
|
|
123
|
+
## Documentation
|
|
124
|
+
|
|
125
|
+
The AMR reference notes and campaign records moved to peclet-amr with the code (`../amr/docs/`).
|
|
126
|
+
What stays here is [docs/archive/](docs/archive/README.md) (the GPU-aware-MPI recipe) and the Doxygen
|
|
127
|
+
API pages (`docs/Doxyfile`, README + `include/`), published to GitHub Pages by
|
|
128
|
+
`.github/workflows/docs.yml`.
|
|
129
|
+
|
|
130
|
+
## Status
|
|
131
|
+
|
|
132
|
+
Complete and in production. The block decomposition, the async ghost-layer exchange (CPU + portable
|
|
133
|
+
Kokkos GPU, host-staged and opt-in GPU-aware), particle migration, dynamic load balancing (weighted
|
|
134
|
+
ORB + Lagrangian rebalancing), SDF geometry, the face-CSR solver layer, and the nanobind Python bindings
|
|
135
|
+
are all shipped and tested (53 ctests plain, 68 with Kokkos; `np` 1–8). `flow` (distributed cut-cell
|
|
136
|
+
IBM Navier–Stokes), `dem`
|
|
137
|
+
(distributed XPBD with load rebalancing) are validated consumers. CUDA is retired; Kokkos
|
|
138
|
+
(CUDA / HIP / OpenMP) is the canonical device path. Remaining work is at-scale multi-GPU tuning.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
peclet/core/__init__.py,sha256=iN4H5U3RPhcqM5ddatketv1JALYaDLaXMNZwvDO126M,1273
|
|
2
|
+
peclet/core/geom.py,sha256=tiEGaEV14_B8jFLs1Wq6lQpB-kQQOSBPxR7own7Szgw,425
|
|
3
|
+
peclet/core/mpi.py,sha256=-bAiw1jhJMlrd8cyj7rBzZAudbKcrcPHSx5zP0u2HUQ,424
|
|
4
|
+
peclet_core-1.1.0.dist-info/METADATA,sha256=Fd1pH20_nflBhO-vbhOlrTPewWs8B7lyN0giRfAwvm8,10007
|
|
5
|
+
peclet_core-1.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
6
|
+
peclet_core-1.1.0.dist-info/licenses/LICENSE,sha256=y1lAzZEZuBZvgvSMwte2O-Of5uGi9PGpeNTCHMMxTvU,1069
|
|
7
|
+
peclet_core-1.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Frank Peters
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|