peclet-core 1.3.0__tar.gz → 1.3.2__tar.gz

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.
Files changed (143) hide show
  1. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/workflows/ci.yml +3 -1
  2. {peclet_core-1.3.0 → peclet_core-1.3.2}/CITATION.cff +2 -2
  3. {peclet_core-1.3.0 → peclet_core-1.3.2}/CLAUDE.md +1 -1
  4. {peclet_core-1.3.0 → peclet_core-1.3.2}/PKG-INFO +4 -4
  5. {peclet_core-1.3.0 → peclet_core-1.3.2}/README.md +2 -2
  6. {peclet_core-1.3.0 → peclet_core-1.3.2}/docs/Doxyfile +1 -1
  7. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/vof/curvature.hpp +46 -6
  8. {peclet_core-1.3.0 → peclet_core-1.3.2}/packaging/pyproject-core.toml +3 -3
  9. peclet_core-1.3.2/packaging/shell/core_geom.py +16 -0
  10. {peclet_core-1.3.0 → peclet_core-1.3.2}/packaging/shell/core_init.py +2 -1
  11. peclet_core-1.3.2/packaging/shell/core_mpi.py +16 -0
  12. {peclet_core-1.3.0 → peclet_core-1.3.2}/pyproject.toml +3 -3
  13. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/CMakeLists.txt +10 -0
  14. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/packaging/halo_init.py +1 -1
  15. peclet_core-1.3.2/python/test_shell_deprecation.py +78 -0
  16. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/CMakeLists.txt +8 -0
  17. peclet_core-1.3.2/tests/test_vof_pvfit.cpp +305 -0
  18. peclet_core-1.3.0/packaging/shell/core_geom.py +0 -9
  19. peclet_core-1.3.0/packaging/shell/core_mpi.py +0 -9
  20. {peclet_core-1.3.0 → peclet_core-1.3.2}/.clang-format +0 -0
  21. {peclet_core-1.3.0 → peclet_core-1.3.2}/.clang-tidy +0 -0
  22. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  23. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  24. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  25. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/dependabot.yml +0 -0
  26. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/workflows/docs.yml +0 -0
  27. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/workflows/quality.yml +0 -0
  28. {peclet_core-1.3.0 → peclet_core-1.3.2}/.github/workflows/release.yml +0 -0
  29. {peclet_core-1.3.0 → peclet_core-1.3.2}/.gitignore +0 -0
  30. {peclet_core-1.3.0 → peclet_core-1.3.2}/CMakeLists.txt +0 -0
  31. {peclet_core-1.3.0 → peclet_core-1.3.2}/LICENSE +0 -0
  32. {peclet_core-1.3.0 → peclet_core-1.3.2}/benchmarks/CMakeLists.txt +0 -0
  33. {peclet_core-1.3.0 → peclet_core-1.3.2}/benchmarks/bench_halo.cpp +0 -0
  34. {peclet_core-1.3.0 → peclet_core-1.3.2}/cmake/PecletCorePinMpiexec.cmake +0 -0
  35. {peclet_core-1.3.0 → peclet_core-1.3.2}/cmake/PecletCoreTest.cmake +0 -0
  36. {peclet_core-1.3.0 → peclet_core-1.3.2}/cmake/SuiteNanobind.cmake +0 -0
  37. {peclet_core-1.3.0 → peclet_core-1.3.2}/cmake/peclet-coreConfig.cmake.in +0 -0
  38. {peclet_core-1.3.0 → peclet_core-1.3.2}/docs/archive/README.md +0 -0
  39. {peclet_core-1.3.0 → peclet_core-1.3.2}/docs/archive/cuda-aware-mpi.md +0 -0
  40. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/cpu_budget.hpp +0 -0
  41. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/host_parallel.hpp +0 -0
  42. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/mpi.hpp +0 -0
  43. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/mpi_stub.hpp +0 -0
  44. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/portable.hpp +0 -0
  45. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/types.hpp +0 -0
  46. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/common/view.hpp +0 -0
  47. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/block_decomposer.hpp +0 -0
  48. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/block_indexer.hpp +0 -0
  49. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/gather_by_global_id.hpp +0 -0
  50. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/grid_redistribute.hpp +0 -0
  51. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/morton_indexer.hpp +0 -0
  52. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/redistribute_topology.hpp +0 -0
  53. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/stage_comm.hpp +0 -0
  54. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/decomp/stage_target.hpp +0 -0
  55. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/domain.hpp +0 -0
  56. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/field/field_set.hpp +0 -0
  57. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/body_properties.hpp +0 -0
  58. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/device_scene.hpp +0 -0
  59. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/grid_sdf.hpp +0 -0
  60. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/primitives.hpp +0 -0
  61. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/quadrature.hpp +0 -0
  62. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/scene.hpp +0 -0
  63. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/scene_builder.hpp +0 -0
  64. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/scene_query.hpp +0 -0
  65. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/sdf.hpp +0 -0
  66. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/geom/vti_io.hpp +0 -0
  67. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/grid_halo.hpp +0 -0
  68. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/grid_halo_topology.hpp +0 -0
  69. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/nbx.hpp +0 -0
  70. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/particle_halo.hpp +0 -0
  71. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/particle_halo_topology.hpp +0 -0
  72. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/particle_migrator.hpp +0 -0
  73. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/particle_migrator_view.hpp +0 -0
  74. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/halo/particle_rebalance.hpp +0 -0
  75. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/interp/particle_grid.hpp +0 -0
  76. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/python/kokkos_teardown.hpp +0 -0
  77. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/python/ndarray_interop.hpp +0 -0
  78. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/scheme/cut_cell_closure.hpp +0 -0
  79. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/scheme/ghost_closure.hpp +0 -0
  80. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/coloring.hpp +0 -0
  81. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/csr_bicgstab.hpp +0 -0
  82. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/csr_operator.hpp +0 -0
  83. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/face_csr.hpp +0 -0
  84. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/graph_amg.hpp +0 -0
  85. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/graph_amg_device.hpp +0 -0
  86. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/solver/vector_ops.hpp +0 -0
  87. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/vof/cutcell.hpp +0 -0
  88. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/vof/plic.hpp +0 -0
  89. {peclet_core-1.3.0 → peclet_core-1.3.2}/include/peclet/core/vof/wetting.hpp +0 -0
  90. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/halo_bindings.cpp +0 -0
  91. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/packaging/_halo.pyi +0 -0
  92. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/state_hash.py +0 -0
  93. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/state_hash_reference.json +0 -0
  94. {peclet_core-1.3.0 → peclet_core-1.3.2}/python/test_mpi.py +0 -0
  95. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/data/rcp_pack_seed3_unit.txt +0 -0
  96. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/python/CMakeLists.txt +0 -0
  97. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/python/interop_test_module.cpp +0 -0
  98. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/python/test_ndarray_interop.py +0 -0
  99. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_aligned_weighted.cpp +0 -0
  100. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_aligned_weighted_mpi.cpp +0 -0
  101. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_cpu_budget.cpp +0 -0
  102. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_csr_solver.cpp +0 -0
  103. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_cut_cell_closure.cpp +0 -0
  104. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_decomposition.cpp +0 -0
  105. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_diffusion.cpp +0 -0
  106. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_diffusion_sdf.cpp +0 -0
  107. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_domain.cpp +0 -0
  108. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_field_set.cpp +0 -0
  109. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_batch_device.cpp +0 -0
  110. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_body.cpp +0 -0
  111. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_owner.cpp +0 -0
  112. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_primitives.cpp +0 -0
  113. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_properties.cpp +0 -0
  114. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_quadrature.cpp +0 -0
  115. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_scene.cpp +0 -0
  116. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_scene_builder.cpp +0 -0
  117. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_scene_query.cpp +0 -0
  118. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_geom_tree_grad.cpp +0 -0
  119. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_ghost_particles_mpi.cpp +0 -0
  120. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_graph_amg.cpp +0 -0
  121. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_graph_amg_device.cpp +0 -0
  122. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_grid_halo.cpp +0 -0
  123. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_grid_halo_exchange.cpp +0 -0
  124. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_grid_redistribute_mpi.cpp +0 -0
  125. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_host_parallel.cpp +0 -0
  126. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_morton_indexer.cpp +0 -0
  127. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_nbx_rounds.cpp +0 -0
  128. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_grid.cpp +0 -0
  129. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_halo_exchange.cpp +0 -0
  130. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_halo_images_mpi.cpp +0 -0
  131. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_halo_mpi.cpp +0 -0
  132. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_migration.cpp +0 -0
  133. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_migrator_view_mpi.cpp +0 -0
  134. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_particle_rebalance.cpp +0 -0
  135. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_sdf.cpp +0 -0
  136. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_skip_mpi.hpp +0 -0
  137. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_stage_redistribute_mpi.cpp +0 -0
  138. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_stage_repartition_mpi.cpp +0 -0
  139. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_stage_target.cpp +0 -0
  140. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_util.hpp +0 -0
  141. {peclet_core-1.3.0 → peclet_core-1.3.2}/tests/test_vti.cpp +0 -0
  142. {peclet_core-1.3.0 → peclet_core-1.3.2}/tools/cuda_aware_mpi_check.cpp +0 -0
  143. {peclet_core-1.3.0 → peclet_core-1.3.2}/tools/cudampi-env.sh +0 -0
@@ -110,7 +110,9 @@ jobs:
110
110
  python3-dev python3-pip
111
111
  # nanobind is located through the interpreter (cmake/SuiteNanobind.cmake); mpi4py builds
112
112
  # against the apt OpenMPI just installed (same MPI the modules link).
113
- python3 -m pip install "nanobind==${NANOBIND_VERSION}" numpy pytest mpi4py
113
+ # peclet-geom (a wheel) lets python_shell_deprecation_geom run instead of SKIPping: the
114
+ # compatibility shell re-exports it, so the warning gate needs it importable.
115
+ python3 -m pip install "nanobind==${NANOBIND_VERSION}" numpy pytest mpi4py "peclet-geom>=1.0,<2"
114
116
 
115
117
  - name: Cache Kokkos install
116
118
  id: kokkos-cache
@@ -16,8 +16,8 @@ authors:
16
16
  orcid: "https://orcid.org/0000-0001-6099-3583"
17
17
  email: e.a.j.f.peters@tue.nl
18
18
  affiliation: "Eindhoven University of Technology"
19
- version: 1.3.0
20
- date-released: 2026-09-26
19
+ version: 1.3.2
20
+ date-released: 2026-10-03
21
21
  license: MIT
22
22
  doi: 10.5281/zenodo.21132435
23
23
  identifiers:
@@ -37,7 +37,7 @@ ctest --test-dir build --output-on-failure -LE bench # 76 ctests (77 with `ben
37
37
  export PATH=/usr/local/cuda-13.2/bin:$PATH # if the Kokkos install targets the CUDA backend
38
38
  cmake -S . -B build_kokkos -DPECLET_CORE_ENABLE_KOKKOS=ON \
39
39
  -DCMAKE_PREFIX_PATH=../extern/install/nvidia-cuda
40
- cmake --build build_kokkos -j && ctest --test-dir build_kokkos --output-on-failure -LE bench # 91 ctests (92 with `bench`): + device halo / geometry / solver, np=1,2,4,8
40
+ cmake --build build_kokkos -j && ctest --test-dir build_kokkos --output-on-failure -LE bench # 92 ctests (93 with `bench`): + device halo / geometry / solver / VoF PV fit, np=1,2,4,8
41
41
  mpirun -np 4 ./build/benchmarks/bench_halo 48 1 300
42
42
 
43
43
  # Python modules + their ctests (test_mpi.py np=1,2,4,8; state_hash; ndarray interop). Release is
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: peclet-core
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: peclet.core — compatibility shell: peclet.core.geom is now peclet.geom, peclet.core.mpi is now peclet.halo
5
5
  Project-URL: Homepage, https://github.com/computational-chemical-engineering/peclet
6
6
  Project-URL: Documentation, https://computational-chemical-engineering.github.io/peclet/
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Topic :: Scientific/Engineering
16
16
  Requires-Python: >=3.10
17
17
  Requires-Dist: peclet-geom<2,>=1.0
18
- Requires-Dist: peclet-halo<2,>=1.1
18
+ Requires-Dist: peclet-halo<2,>=1.2
19
19
  Description-Content-Type: text/markdown
20
20
 
21
21
  # core — `peclet-halo` (+ the `peclet-core` compatibility shell)
@@ -127,8 +127,8 @@ after `cmake --install`, or as a sibling checkout in the suite.
127
127
  `find_package(MPI REQUIRED)` — so a pure-geometry API could not be installed without an MPI
128
128
  toolchain. The C++ headers `include/peclet/core/geom/` **stay here**; peclet-geom vendors them at
129
129
  `PECLET_CORE_TAG`. The old spellings keep working through the `peclet-core` compatibility shell
130
- until 2.0.0 — `peclet.core.geom` is now `peclet.geom`, `peclet.core.mpi` is now `peclet.halo`,
131
- and each pair is the same object. See
130
+ until 2.0.0, with a `DeprecationWarning` since 1.3.1 — `peclet.core.geom` is now `peclet.geom`,
131
+ `peclet.core.mpi` is now `peclet.halo`, and each pair is the same object. See
132
132
  [docs/CORE_BOUNDARY.md](https://github.com/computational-chemical-engineering/peclet/blob/main/docs/CORE_BOUNDARY.md).
133
133
 
134
134
  Validated end-to-end by distributed explicit heat-diffusion solvers (plain, and **around an SDF solid
@@ -107,8 +107,8 @@ after `cmake --install`, or as a sibling checkout in the suite.
107
107
  `find_package(MPI REQUIRED)` — so a pure-geometry API could not be installed without an MPI
108
108
  toolchain. The C++ headers `include/peclet/core/geom/` **stay here**; peclet-geom vendors them at
109
109
  `PECLET_CORE_TAG`. The old spellings keep working through the `peclet-core` compatibility shell
110
- until 2.0.0 — `peclet.core.geom` is now `peclet.geom`, `peclet.core.mpi` is now `peclet.halo`,
111
- and each pair is the same object. See
110
+ until 2.0.0, with a `DeprecationWarning` since 1.3.1 — `peclet.core.geom` is now `peclet.geom`,
111
+ `peclet.core.mpi` is now `peclet.halo`, and each pair is the same object. See
112
112
  [docs/CORE_BOUNDARY.md](https://github.com/computational-chemical-engineering/peclet/blob/main/docs/CORE_BOUNDARY.md).
113
113
 
114
114
  Validated end-to-end by distributed explicit heat-diffusion solvers (plain, and **around an SDF solid
@@ -5,7 +5,7 @@
5
5
 
6
6
  DOXYFILE_ENCODING = UTF-8
7
7
  PROJECT_NAME = "core"
8
- PROJECT_NUMBER = 1.3.0
8
+ PROJECT_NUMBER = 1.3.2
9
9
  PROJECT_BRIEF = "Shared MPI block decomposition, asynchronous ghost-layer exchange, SDF geometry, load balancing (header-only C++20)"
10
10
  OUTPUT_DIRECTORY = docs
11
11
  HTML_OUTPUT = html
@@ -729,7 +729,7 @@ KOKKOS_INLINE_FUNCTION void pvFitInit(PvFit& f) {
729
729
  f.npoly = 0;
730
730
  }
731
731
 
732
- /// Fold one stencil cell's PLIC polygon into the fit.
732
+ /// One stencil cell's PLIC polygon in the PV fit: the parameters of `pvFitTerm` and `pvFitAdd`.
733
733
  ///
734
734
  /// @param mx,my,mz,alpha the cell's PLIC plane in ITS OWN unit-cell coordinates (`plic.hpp`).
735
735
  /// @param off the cell's integer index offset from the target cell.
@@ -744,11 +744,25 @@ KOKKOS_INLINE_FUNCTION void pvFitInit(PvFit& f) {
744
744
  /// integrated with the wrong sign of `z'`. Jibben's area projection
745
745
  /// `A (n.n_p)` decays to zero over the same range; this is the explicit
746
746
  /// version of the same guard.
747
- /// @return true if the polygon contributed.
748
- KOKKOS_INLINE_FUNCTION bool pvFitAdd(PvFit& f, double mx, double my, double mz, double alpha,
749
- const double off[3], const double org[3], const double t1[3],
750
- const double t2[3], const double nn[3], double dW,
751
- double cosMin, const VofMetric& g) {
747
+ ///
748
+ /// `pvFitAdd` is the composition of `pvFitTerm` (the per-polygon map) and `pvFitAccum` (the `+=`
749
+ /// into the normal equations), bitwise (`tests/test_vof_pvfit.cpp`). The split lets a device
750
+ /// fallback evaluate the stencil's terms in parallel and still accumulate them in the canonical
751
+ /// order (flow `doc/vof_step_performance_design.md` §4.7, §5.11).
752
+ struct PvTerm {
753
+ double w, B, s[6];
754
+ bool ok;
755
+ };
756
+
757
+ /// One stencil polygon's contribution to the PV fit: everything `pvFitAdd` computes before the
758
+ /// accumulation — the polygon, the frame transform, the moments `s`, the Wendland weight `w` and
759
+ /// `B`. Same parameters as `pvFitAdd`. Sets `t.ok` and returns it: false exactly where `pvFitAdd`
760
+ /// returns false (a rejected polygon), and then `w`, `B`, `s` are unspecified.
761
+ KOKKOS_INLINE_FUNCTION bool pvFitTerm(PvTerm& t, double mx, double my, double mz, double alpha,
762
+ const double off[3], const double org[3], const double t1[3],
763
+ const double t2[3], const double nn[3], double dW,
764
+ double cosMin, const VofMetric& g) {
765
+ t.ok = false;
752
766
  const double n2 = mx * mx + my * my + mz * mz;
753
767
  if (!(n2 > 0.0))
754
768
  return false;
@@ -804,12 +818,38 @@ KOKKOS_INLINE_FUNCTION bool pvFitAdd(PvFit& f, double mx, double my, double mz,
804
818
  return false;
805
819
 
806
820
  const double B = b0 * s[0] + b1 * s[1] + b2 * s[2];
821
+ t.w = w;
822
+ t.B = B;
823
+ for (int i = 0; i < 6; ++i)
824
+ t.s[i] = s[i];
825
+ t.ok = true;
826
+ return true;
827
+ }
828
+
829
+ /// Fold one accepted term (`t.ok`) into the fit — the accumulation half of `pvFitAdd`, with its
830
+ /// expressions verbatim. Calling it in the stencil's canonical order reproduces `pvFitAdd`'s sums.
831
+ KOKKOS_INLINE_FUNCTION void pvFitAccum(PvFit& f, const PvTerm& t) {
832
+ const double w = t.w, B = t.B;
833
+ const double* s = t.s;
807
834
  for (int i = 0; i < 6; ++i) {
808
835
  f.b[i] += w * s[i] * B;
809
836
  for (int j = 0; j < 6; ++j)
810
837
  f.A[i][j] += w * s[i] * s[j];
811
838
  }
812
839
  ++f.npoly;
840
+ }
841
+
842
+ /// Fold one stencil cell's PLIC polygon into the fit: `pvFitTerm`, then `pvFitAccum` if the
843
+ /// polygon is accepted. Parameters as documented above `PvTerm`.
844
+ /// @return true if the polygon contributed.
845
+ KOKKOS_INLINE_FUNCTION bool pvFitAdd(PvFit& f, double mx, double my, double mz, double alpha,
846
+ const double off[3], const double org[3], const double t1[3],
847
+ const double t2[3], const double nn[3], double dW,
848
+ double cosMin, const VofMetric& g) {
849
+ PvTerm t;
850
+ if (!pvFitTerm(t, mx, my, mz, alpha, off, org, t1, t2, nn, dW, cosMin, g))
851
+ return false;
852
+ pvFitAccum(f, t);
813
853
  return true;
814
854
  }
815
855
 
@@ -7,7 +7,7 @@
7
7
  # peclet.core.mpi -> peclet.halo (peclet-halo, sdist, needs MPI)
8
8
  #
9
9
  # This distribution keeps `import peclet.core.{geom,mpi}` working by re-exporting them — the same
10
- # objects, not wrappers. It warns from 1.3.0 and is removed at 2.0.0, where the `<2` ceiling on its
10
+ # objects, not wrappers. It warns from 1.3.1 and is removed at 2.0.0, where the `<2` ceiling on its
11
11
  # pins makes a 2.x install fail LOUDLY at resolution instead of silently importing nothing.
12
12
  #
13
13
  # The umbrella release workflow copies this over pyproject.toml to build the shell, the same
@@ -19,7 +19,7 @@ build-backend = "hatchling.build"
19
19
 
20
20
  [project]
21
21
  name = "peclet-core"
22
- version = "1.3.0"
22
+ version = "1.3.2"
23
23
  description = "peclet.core — compatibility shell: peclet.core.geom is now peclet.geom, peclet.core.mpi is now peclet.halo"
24
24
  readme = "README.md"
25
25
  requires-python = ">=3.10"
@@ -35,7 +35,7 @@ classifiers = [
35
35
  # The `<2` ceiling is load-bearing, not caution: at 2.0.0 this shell is gone, and a 2.x environment
36
36
  # that installs peclet-core must fail at RESOLUTION with the constraint named, rather than resolve
37
37
  # and then fail at import. A pinned 1.x family keeps working forever.
38
- dependencies = ["peclet-geom>=1.0,<2", "peclet-halo>=1.1,<2"]
38
+ dependencies = ["peclet-geom>=1.0,<2", "peclet-halo>=1.2,<2"]
39
39
 
40
40
  [project.urls]
41
41
  Homepage = "https://github.com/computational-chemical-engineering/peclet"
@@ -0,0 +1,16 @@
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 from peclet-core 1.3.1 (family 1.3.0), removed in 2.0.0
5
+ (suite/docs/CORE_BOUNDARY.md).
6
+ """
7
+ import warnings
8
+
9
+ warnings.warn(
10
+ "peclet.core.geom is peclet.geom since peclet 1.2.0 — use `from peclet import geom`. "
11
+ "peclet.core is removed in peclet 2.0.0.", DeprecationWarning, stacklevel=2)
12
+
13
+ from peclet.geom import * # noqa: F401,F403,E402
14
+ from peclet import geom as _canonical # noqa: E402
15
+
16
+ __all__ = [n for n in dir(_canonical) if not n.startswith("_")]
@@ -13,7 +13,8 @@ Why the split: `peclet.core.geom` is host-only SDF authoring with no MPI in it,
13
13
  distribution with the halo bindings whose build requires an MPI toolchain — so a pure-geometry API
14
14
  could not be pip-installed without MPI. See suite/docs/CORE_BOUNDARY.md.
15
15
 
16
- These spellings keep working unchanged in peclet 1.2.0, gain a DeprecationWarning in 1.3.0, and are
16
+ These spellings keep working unchanged in peclet 1.2.0, warn (DeprecationWarning, on importing
17
+ ``peclet.core.geom`` / ``peclet.core.mpi``) from peclet-core 1.3.1 in family 1.3.0, and are
17
18
  removed in 2.0.0. The canonical spellings are ``from peclet import geom`` and
18
19
  ``from peclet import halo``.
19
20
  """
@@ -0,0 +1,16 @@
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 from peclet-core 1.3.1 (family 1.3.0), removed in 2.0.0
5
+ (suite/docs/CORE_BOUNDARY.md).
6
+ """
7
+ import warnings
8
+
9
+ warnings.warn(
10
+ "peclet.core.mpi is peclet.halo since peclet 1.2.0 — use `from peclet import halo`. "
11
+ "peclet.core is removed in peclet 2.0.0.", DeprecationWarning, stacklevel=2)
12
+
13
+ from peclet.halo import * # noqa: F401,F403,E402
14
+ from peclet import halo as _canonical # noqa: E402
15
+
16
+ __all__ = [n for n in dir(_canonical) if not n.startswith("_")]
@@ -7,7 +7,7 @@
7
7
  # peclet.core.mpi -> peclet.halo (peclet-halo, sdist, needs MPI)
8
8
  #
9
9
  # This distribution keeps `import peclet.core.{geom,mpi}` working by re-exporting them — the same
10
- # objects, not wrappers. It warns from 1.3.0 and is removed at 2.0.0, where the `<2` ceiling on its
10
+ # objects, not wrappers. It warns from 1.3.1 and is removed at 2.0.0, where the `<2` ceiling on its
11
11
  # pins makes a 2.x install fail LOUDLY at resolution instead of silently importing nothing.
12
12
  #
13
13
  # The umbrella release workflow copies this over pyproject.toml to build the shell, the same
@@ -19,7 +19,7 @@ build-backend = "hatchling.build"
19
19
 
20
20
  [project]
21
21
  name = "peclet-core"
22
- version = "1.3.0"
22
+ version = "1.3.2"
23
23
  description = "peclet.core — compatibility shell: peclet.core.geom is now peclet.geom, peclet.core.mpi is now peclet.halo"
24
24
  readme = "README.md"
25
25
  requires-python = ">=3.10"
@@ -35,7 +35,7 @@ classifiers = [
35
35
  # The `<2` ceiling is load-bearing, not caution: at 2.0.0 this shell is gone, and a 2.x environment
36
36
  # that installs peclet-core must fail at RESOLUTION with the constraint named, rather than resolve
37
37
  # and then fail at import. A pinned 1.x family keeps working forever.
38
- dependencies = ["peclet-geom>=1.0,<2", "peclet-halo>=1.1,<2"]
38
+ dependencies = ["peclet-geom>=1.0,<2", "peclet-halo>=1.2,<2"]
39
39
 
40
40
  [project.urls]
41
41
  Homepage = "https://github.com/computational-chemical-engineering/peclet"
@@ -105,6 +105,16 @@ if(PECLET_CORE_PYTHON_TESTS)
105
105
  # type exits 77 and ctest reports the gate SKIPPED (CI), never passed.
106
106
  set_tests_properties(python_state_hash PROPERTIES LABELS "python" SKIP_RETURN_CODE 77
107
107
  ENVIRONMENT "${_py_env};OMP_NUM_THREADS=1")
108
+ # The peclet-core compatibility shell (packaging/shell) warns on `import peclet.core.{geom,mpi}`
109
+ # and the canonical `peclet.geom` / `peclet.halo` stay silent — CORE_BOUNDARY step 2, gated.
110
+ # The geom half SKIPs (77) where the separate peclet-geom distribution is not installed.
111
+ foreach(_old IN ITEMS geom mpi)
112
+ add_test(NAME python_shell_deprecation_${_old}
113
+ COMMAND "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/test_shell_deprecation.py"
114
+ ${_old} "${CMAKE_CURRENT_SOURCE_DIR}/../packaging/shell")
115
+ set_tests_properties(python_shell_deprecation_${_old} PROPERTIES LABELS "python"
116
+ SKIP_RETURN_CODE 77 ENVIRONMENT "${_py_env}")
117
+ endforeach()
108
118
  if(Kokkos_FOUND)
109
119
  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../tests/python tests_python)
110
120
  else()
@@ -8,7 +8,7 @@ Needs an MPI toolchain to build and an MPI runtime to use, which is why it ships
8
8
  `pip install peclet[mpi]` while its former housemate `peclet.geom` ships wheels.
9
9
 
10
10
  Until peclet 1.2.0 this was ``peclet.core.mpi`` in the ``peclet-core`` distribution. That spelling
11
- still works and is the same object; it warns from 1.3.0 and is removed in 2.0.0.
11
+ still works and is the same object; it warns from 1.3.1 and is removed in 2.0.0.
12
12
  """
13
13
  from importlib.metadata import PackageNotFoundError, version as _version
14
14
 
@@ -0,0 +1,78 @@
1
+ """The peclet-core compatibility shell warns on the old spelling; the canonical spelling is silent.
2
+
3
+ python test_shell_deprecation.py {geom|mpi} <core>/packaging/shell
4
+
5
+ The ladder step 2 of suite/docs/CORE_BOUNDARY.md, gated rather than trusted. The three shell files
6
+ are staged as ``peclet/core/`` in a temporary directory -- the layout the peclet-core wheel installs
7
+ (packaging/pyproject-core.toml) -- and each check runs in a fresh interpreter:
8
+
9
+ 1. ``python -W error::DeprecationWarning -c "import peclet.core.<old>"`` must exit NON-ZERO, and
10
+ its stderr must carry the shell's message (so an ImportError cannot pass for the warning);
11
+ 2. ``python -c "import peclet.core.<old>"`` with the default filters must exit 0 and PRINT the
12
+ warning -- stacklevel=2 attributes it to the importing ``__main__``, which is what makes a
13
+ user see it rather than only a test runner;
14
+ 3. ``python -W error::DeprecationWarning -c "import peclet.<canonical>"`` must exit 0.
15
+
16
+ Exits 77 (ctest SKIP) when the canonical module is not importable at all: peclet.geom is a separate
17
+ distribution (peclet-geom), and without it check 1 would "fail" by ImportError for the wrong reason.
18
+ """
19
+ import os
20
+ import shutil
21
+ import subprocess
22
+ import sys
23
+ import tempfile
24
+
25
+ CANONICAL = {"geom": "geom", "mpi": "halo"}
26
+
27
+
28
+ def run(args, env):
29
+ return subprocess.run([sys.executable, *args], env=env, capture_output=True, text=True)
30
+
31
+
32
+ def main():
33
+ old, shell_dir = sys.argv[1], sys.argv[2]
34
+ canon = CANONICAL[old]
35
+ message = f"peclet.core.{old} is peclet.{canon} since peclet 1.2.0"
36
+
37
+ with tempfile.TemporaryDirectory() as tmp:
38
+ pkg = os.path.join(tmp, "peclet", "core") # `peclet` stays a PEP 420 namespace: no __init__
39
+ os.makedirs(pkg)
40
+ for src, dst in (("core_init.py", "__init__.py"), ("core_geom.py", "geom.py"),
41
+ ("core_mpi.py", "mpi.py")):
42
+ shutil.copy(os.path.join(shell_dir, src), os.path.join(pkg, dst))
43
+ env = dict(os.environ)
44
+ env["PYTHONPATH"] = os.pathsep.join(p for p in (tmp, env.get("PYTHONPATH", "")) if p)
45
+ env.pop("PYTHONWARNINGS", None)
46
+
47
+ r = run(["-c", f"import peclet.{canon}"], env)
48
+ if r.returncode != 0:
49
+ print(f"SKIP: peclet.{canon} is not importable here:\n{r.stderr}")
50
+ return 77
51
+
52
+ failures = []
53
+ r = run(["-W", "error::DeprecationWarning", "-c", f"import peclet.core.{old}"], env)
54
+ if r.returncode == 0:
55
+ failures.append(f"`import peclet.core.{old}` under -W error exited 0: no DeprecationWarning")
56
+ elif f"DeprecationWarning: {message}" not in r.stderr:
57
+ failures.append(f"`import peclet.core.{old}` failed, but not with the shell's warning:\n{r.stderr}")
58
+
59
+ r = run(["-c", f"import peclet.core.{old}"], env)
60
+ if r.returncode != 0:
61
+ failures.append(f"`import peclet.core.{old}` (default filters) failed:\n{r.stderr}")
62
+ elif message not in r.stderr:
63
+ failures.append(f"`import peclet.core.{old}` (default filters) did not show the warning; "
64
+ f"stderr was:\n{r.stderr!r}")
65
+
66
+ r = run(["-W", "error::DeprecationWarning", "-c", f"import peclet.{canon}"], env)
67
+ if r.returncode != 0:
68
+ failures.append(f"canonical `import peclet.{canon}` is not silent:\n{r.stderr}")
69
+
70
+ for f in failures:
71
+ print("FAIL:", f)
72
+ if not failures:
73
+ print(f"OK: peclet.core.{old} warns ({message}...); peclet.{canon} is silent")
74
+ return 1 if failures else 0
75
+
76
+
77
+ if __name__ == "__main__":
78
+ sys.exit(main())
@@ -282,6 +282,14 @@ if(MPI_FOUND)
282
282
  target_link_libraries(test_csr_solver PRIVATE Kokkos::kokkos)
283
283
  peclet_core_add_test(csr_solver test_csr_solver)
284
284
 
285
+ # VoF PV fit: pvFitAdd == pvFitTerm + pvFitAccum bitwise, device and host spaces (10^5
286
+ # random cases incl. rejected polygons; flow vof_step_performance_design.md §5.11, WO-7a).
287
+ add_executable(test_vof_pvfit test_vof_pvfit.cpp)
288
+ target_include_directories(test_vof_pvfit PRIVATE
289
+ ${PROJECT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
290
+ target_link_libraries(test_vof_pvfit PRIVATE Kokkos::kokkos)
291
+ peclet_core_add_test(vof_pvfit test_vof_pvfit)
292
+
285
293
  # Device GraphAMG apply vs the host oracle (no MPI; serial + device).
286
294
  add_executable(test_graph_amg_device test_graph_amg_device.cpp)
287
295
  target_include_directories(test_graph_amg_device PRIVATE