peclet-dem 1.1.0
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
periodicity.hpp
Go to the documentation of this file.
1
9#ifndef DEM_PERIODICITY_HPP
10#define DEM_PERIODICITY_HPP
11
12#include <Kokkos_Core.hpp>
13
14#include "dem_portable.hpp"
15#include "integration.hpp" // Domain, V3/V4/Vf/Vi, detail::st3/st4
16
17namespace peclet::dem {
18
26inline int calculateGhostCapacity(int nReal, Domain dom, float skin) {
27 const float sx = dom.periodic_x ? skin : 0.0f;
28 const float sy = dom.periodic_y ? skin : 0.0f;
29 const float sz = dom.periodic_z ? skin : 0.0f;
30 const double innerX = (dom.size.x - 2.0f * sx > 0.0f) ? (dom.size.x - 2.0f * sx) : 0.0;
31 const double innerY = (dom.size.y - 2.0f * sy > 0.0f) ? (dom.size.y - 2.0f * sy) : 0.0;
32 const double innerZ = (dom.size.z - 2.0f * sz > 0.0f) ? (dom.size.z - 2.0f * sz) : 0.0;
33 const double volTotal = static_cast<double>(dom.size.x) * dom.size.y * dom.size.z;
34 if (volTotal <= 0.0)
35 return nReal * 8; // degenerate box (domain not set yet) -> generous fallback
36 const double ghostFraction = (volTotal - innerX * innerY * innerZ) / volTotal;
37 const double estGhosts = (ghostFraction > 0.5) ? nReal * 32.0 : nReal * ghostFraction * 4.0;
38 return nReal + static_cast<int>(estGhosts) + 4096; // + fixed buffer (matches CUDA)
39}
40
44inline void generateGhostsKokkos(int numReal, int capacity, Domain dom, float skin, V3 pos,
45 Vf invMass, V3 posPred, V3 vel, V3 velPred, V4 quat, V4 quatPred,
46 V3 angVel, V3 angVelPred, Vf scale, Vi shapeId, Vi realIndices,
47 Kokkos::View<int, CpMem> topGhost, Vi gid = Vi{},
48 Kokkos::View<unsigned char*, CpMem> materialId = {}) {
49 using detail::st3;
50 using detail::st4;
51 CpExec space;
52 Kokkos::parallel_for(
53 "peclet::dem::generate_ghosts", Kokkos::RangePolicy<CpExec>(space, 0, numReal),
54 KOKKOS_LAMBDA(int i) {
55 const F3 p = ldF3(pos, i);
56 const int sx = dom.periodic_x
57 ? ((p.x < dom.min.x + skin) ? 1 : ((p.x > dom.max.x - skin) ? -1 : 0))
58 : 0;
59 const int sy = dom.periodic_y
60 ? ((p.y < dom.min.y + skin) ? 1 : ((p.y > dom.max.y - skin) ? -1 : 0))
61 : 0;
62 const int sz = dom.periodic_z
63 ? ((p.z < dom.min.z + skin) ? 1 : ((p.z > dom.max.z - skin) ? -1 : 0))
64 : 0;
65 const int ax[2] = {0, sx}, ay[2] = {0, sy}, az[2] = {0, sz};
66 const int nx = (sx == 0) ? 1 : 2, ny = (sy == 0) ? 1 : 2, nz = (sz == 0) ? 1 : 2;
67
68 const F3 pPred = ldF3(posPred, i);
69 for (int a = 0; a < nx; ++a)
70 for (int b = 0; b < ny; ++b)
71 for (int c = 0; c < nz; ++c) {
72 const int ix = ax[a], iy = ay[b], iz = az[c];
73 if (ix == 0 && iy == 0 && iz == 0)
74 continue;
75 const int slot = Kokkos::atomic_fetch_add(&topGhost(), 1);
76 if (slot >= capacity) {
77 Kokkos::atomic_add(&topGhost(), -1);
78 continue;
79 }
80 const F3 shift{ix * dom.size.x, iy * dom.size.y, iz * dom.size.z};
81 st3(pos, slot, add3(p, shift));
82 st3(posPred, slot, add3(pPred, shift));
83 invMass(slot) = invMass(i);
84 st3(vel, slot, ldF3(vel, i));
85 st3(velPred, slot, ldF3(velPred, i));
86 st4(quat, slot, ldF4(quat, i));
87 st4(quatPred, slot, ldF4(quatPred, i));
88 st3(angVel, slot, ldF3(angVel, i));
89 st3(angVelPred, slot, ldF3(angVelPred, i));
90 scale(slot) = scale(i);
91 shapeId(slot) = shapeId(i);
92 realIndices(slot) = i;
93 if (gid.extent(0) > 0)
94 gid(slot) = gid(i);
95 // Ghost slots must carry the owner's material id: the narrowphase reads matId by RAW
96 // slot index, so a stale/zero ghost entry silently applied material 0's pair row to
97 // every cross-periodic-boundary contact.
98 if (materialId.extent(0) > 0)
99 materialId(slot) = materialId(i);
100 }
101 });
102 space.fence();
103}
104
105} // namespace peclet::dem
106
107#endif // DEM_PERIODICITY_HPP
dem — portable POD types + math + analytic SDFs shared by the Kokkos kernel ports.
dem — portable (Kokkos) time integration kernels (integration.cu).
void st3(const V3 &v, int i, F3 a)
void st4(const V4 &v, int i, F4 a)
void generateGhostsKokkos(int numReal, int capacity, Domain dom, float skin, V3 pos, Vf invMass, V3 posPred, V3 vel, V3 velPred, V4 quat, V4 quatPred, V3 angVel, V3 angVelPred, Vf scale, Vi shapeId, Vi realIndices, Kokkos::View< int, CpMem > topGhost, Vi gid=Vi{}, Kokkos::View< unsigned char *, CpMem > materialId={})
Generate periodic ghosts for particles [0,numReal).
Kokkos::View< float *, CpMem > Vf
Kokkos::View< int *, CpMem > Vi
Kokkos::View< float *[3], CpMem > V3
F3 ldF3(const V &v, int i)
F4 ldF4(const V &v, int i)
Kokkos::View< float *[4], CpMem > V4
F3 add3(F3 a, F3 b)
Kokkos::DefaultExecutionSpace CpExec
int calculateGhostCapacity(int nReal, Domain dom, float skin)
Padded particle-array capacity that leaves room for the periodic ghosts generateGhostsKokkos will emi...