7#ifndef DEM_STEP_SOLVE_HPP
8#define DEM_STEP_SOLVE_HPP
12#include <Kokkos_Core.hpp>
45 const long want = std::max(
54 P.
contacts = Kokkos::View<ContactC*, CpMem>(
"contacts", want);
55 P.
manifolds = Kokkos::View<ManifoldC*, CpMem>(
"manifolds", want);
56 P.
manifoldColor = Kokkos::View<int*, CpMem>(
"manifoldColor", want);
57 P.
pairKeys = Kokkos::View<unsigned long long*, CpMem>(
"pairKeys", want);
58 P.
prevPairKeys = Kokkos::View<unsigned long long*, CpMem>(
"prevPairKeys", want);
59 P.
manifoldPersistent = Kokkos::View<unsigned char*, CpMem>(
"manifoldPersistent", want);
60 P.
contactColor = Kokkos::View<int*, CpMem>(
"contactColor", want);
61 P.
unitStart = Kokkos::View<int*, CpMem>(
"unitStart", want + 1);
62 P.
unitContacts = Kokkos::View<int*, CpMem>(
"unitContacts", want);
63 P.
unitColor = Kokkos::View<int*, CpMem>(
"unitColor", want);
64 P.
lambdaAcc = Kokkos::View<float*, CpMem>(
"lambdaAcc", want);
65 P.
lambdaT = Kokkos::View<float* [3], CpMem>(
"lambdaT", want);
67 P.
posImpulse = Kokkos::View<float*, CpMem>(
"posImpulse", want);
68 P.
prevPosImpulse = Kokkos::View<float*, CpMem>(
"prevPosImpulse", want);
69 P.
restBank = Kokkos::View<float*, CpMem>(
"restBank", want);
70 P.
prevRestBank = Kokkos::View<float*, CpMem>(
"prevRestBank", want);
71 P.
restRel = Kokkos::View<float*, CpMem>(
"restRel", want);
72 P.
restVPeak = Kokkos::View<float*, CpMem>(
"restVPeak", want);
73 P.
prevRestVPeak = Kokkos::View<float*, CpMem>(
"prevRestVPeak", want);
74 P.
prevMatched = Kokkos::View<unsigned char*, CpMem>(
"prevMatched", want);
75 P.
velPerm = Kokkos::View<int*, CpMem>(
"velPerm", want);
76 P.
commitPerm = Kokkos::View<int*, CpMem>(
"commitPerm", want);
77 P.
sideFlags = Kokkos::View<unsigned char*, CpMem>(
"sideFlags", want);
78 P.
prevLambdaT = Kokkos::View<float* [3], CpMem>(
"prevLambdaT", want);
79 P.
contactSlot = Kokkos::View<int*, CpMem>(
"contactSlot", want);
80 P.
prevLambda = Kokkos::View<float*, CpMem>(
"prevLambda", want);
81 P.
vn0 = Kokkos::View<float*, CpMem>(
"vn0", want);
82 P.
vt0 = Kokkos::View<float* [3], CpMem>(
"vt0", want);
83 P.
levelKey = Kokkos::View<int*, CpMem>(
"levelKey", want);
84 P.
levelPerm = Kokkos::View<int*, CpMem>(
"levelPerm", want);
85 P.
mlColorPacked = Kokkos::View<long long*, CpMem>(
"mlColorPacked", want);
91 P.
contactKeys = Kokkos::View<unsigned long long*, CpMem>(
"contactKeys", want);
92 P.
prevContactKeys = Kokkos::View<unsigned long long*, CpMem>(
"prevContactKeys", want);
94 P.
posCommitPerm = Kokkos::View<int*, CpMem>(
"posCommitPerm", want);
95 P.
posPerm = Kokkos::View<int*, CpMem>(
"posPerm", want);
96 P.
manifoldSleep = Kokkos::View<unsigned char*, CpMem>(
"manifoldSleep", want);
97 P.
contactSleep = Kokkos::View<unsigned char*, CpMem>(
"contactSleep", want);
120 auto detect = [&]() {
161 const float margin = 0.1f * maxRad;
174 const bool sleepStep =
176 const float sleepVRest = 2.0f * P.
dt * gMag;
183 Kokkos::parallel_for(
184 "self", Kokkos::RangePolicy<CpExec>(space, 0, P.
numReal),
185 KOKKOS_LAMBDA(
int i) { ri(i) = i; });
197 const float ghostBand = 2.0f * maxRad + margin;
212 Kokkos::parallel_for(
214 KOKKOS_LAMBDA(
int q) {
216 for (
int c = 0; c < 3; ++c)
217 sh(q, c) = pp(q, c) - pp(i, c);
266 if (
static_cast<int>(savedInvMass.extent(0)) < P.
capacity)
267 Kokkos::resize(savedInvMass, P.
capacity);
293 const float margin = 0.1f * maxRad;
299 Kokkos::parallel_for(
300 "self", Kokkos::RangePolicy<CpExec>(space, 0, P.
numReal),
301 KOKKOS_LAMBDA(
int i) { ri(i) = i; });
304 const float ghostBand = 2.0f * maxRad + margin;
dem — portable (Kokkos) time integration kernels (integration.cu).
int narrowPhaseGrow(Particles &P, int np, float margin)
Narrow phase with an automatically-grown contact buffer.
void computeContactSleepKokkos(Kokkos::View< const ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const unsigned char *, CpMem > asleep, Kokkos::View< unsigned char *, CpMem > contactSleep)
Per-contact twin of computeManifoldSleepKokkos for the position colouring.
float maxOwnedRadius(const Particles &P)
Largest effective particle radius over the owned set (= max scale × globalScale, growth included).
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).
void demSolveContacts(Particles &P, int nc, int nm, int nBodies, Kokkos::View< const int *, CpMem > keyIdx, const Hooks &hooks)
One full velocity + position contact solve over the already-built contacts/manifolds (see file commen...
Kokkos::View< float *, CpMem > Vf
void detectBoundaryKokkos(int numReal, int numPlanes, PosView pos, QuatView quat, ScalarF scale, ScalarI shapeId, Kokkos::View< const ShapeDesc *, CpMem > shapes, ShellView shell, Kokkos::View< const PlaneP *, CpMem > planes, float globalScale, float margin, Kokkos::View< ContactC *, CpMem > outContacts, Kokkos::View< int, CpMem > outCount, Kokkos::View< float, CpMem > maxOverlap)
Per-real-particle contacts against explicit planes (point-shell shapes test each surface point; analy...
void updateSleepKokkos(int numReal, Kokkos::View< const float *[3], CpMem > vel, Kokkos::View< const float *[3], CpMem > angVel, Kokkos::View< const float *, CpMem > rad, Kokkos::View< const unsigned char *, CpMem > grounded, Kokkos::View< const unsigned char *, CpMem > movingWall, Kokkos::View< unsigned char *, CpMem > asleep, Kokkos::View< unsigned char *, CpMem > sleepCounter, float sleepSpeed, int K, Kokkos::View< float *[3], CpMem > velOut, Kokkos::View< float *[3], CpMem > angVelOut)
Sleep detection (after the commit): an AWAKE, grounded body whose linear AND angular motion has staye...
void freezeAsleepKokkos(int numReal, Kokkos::View< const unsigned char *, CpMem > asleep, Kokkos::View< const float *[3], CpMem > pos, Kokkos::View< const float *[4], CpMem > quat, Kokkos::View< float *[3], CpMem > posPred, Kokkos::View< float *[4], CpMem > quatPred, Kokkos::View< float *[3], CpMem > velPred, Kokkos::View< float *[3], CpMem > angVelPred)
After predictVelocity: re-freeze the currently-asleep bodies so gravity/prediction do not move them —...
int readInt(Kokkos::View< int, CpMem > v)
int reduceContactsToManifoldsKokkos(Kokkos::View< const ContactC *, CpMem > contacts, int n, Kokkos::View< ManifoldC *, CpMem > outManifolds, Kokkos::View< int, CpMem > outCount, Kokkos::View< int *, CpMem > contactSlot={}, int numOwnedContacts=-1, int *numOwnedManifolds=nullptr)
Reduce n contacts to manifolds (one per unique canonical pair).
void detectWallSdfKokkos(int numReal, int numWalls, PosView pos, QuatView quat, ScalarF scale, ScalarI shapeId, Kokkos::View< const ShapeDesc *, CpMem > shapes, ShellView shell, Kokkos::View< const WallSdf *, CpMem > walls, GridView wallGrid, float globalScale, float margin, Kokkos::View< ContactC *, CpMem > outContacts, Kokkos::View< int, CpMem > outCount, Kokkos::View< float, CpMem > maxOverlap, MatIdView matId=MatIdView{}, PairTableView pairTable=PairTableView{}, int wallIdBase=0)
Per-real-particle contacts against a static world-space wall SDF set (a drum barrel,...
int findCollisionsGrow(Particles &P, float margin)
Broad phase with an automatically-grown pair buffer.
void finalCommitKokkos(int n, V3 pos, Vf invMass, V3 posPred, V4 quat, V4 quatPred, Domain dom)
Final commit: periodic wrap of the predicted position into the domain, commit position + quat.
void growContactBuffers(Particles &P, long nBodies, long floorWant=0)
Grow every maxContacts-sized collision buffer to match the CURRENT particle capacity.
void fillWorldRadiiKokkos(Vf scale, Vf rad, float gs, float bR, int n)
World radii rad(i) = scale(i) * globalScale * baseRadius over [0, n): the owned span before a step,...
void updateGrowthScalesKokkos(int n, Vf scale, Vf targetScale, float factor)
Growth mode: scale = target * factor (when active).
void detectContactsKokkos(Kokkos::View< const int *[2], CpMem > pairs, int numPairs, PosView pos, QuatView quat, ScalarF scale, ScalarI shapeId, Kokkos::View< const ShapeDesc *, CpMem > shapes, ShellView shell, float globalScale, float margin, Kokkos::View< ContactC *, CpMem > outContacts, Kokkos::View< int, CpMem > outCount, Kokkos::View< float, CpMem > maxOverlap, GridView sdfGrid=GridView{}, MatIdView matId=MatIdView{}, PairTableView pairTable=PairTableView{}, bool twoWay=false)
Pair point-shell vs SDF contacts.
float computeOverlapsKokkos(Particles &P)
Max pair interpenetration on the committed state (faithful to CUDA Simulation::compute_overlaps): cop...
void demStep(Particles &P)
One full XPBD DEM substep over the particle SoA (mirrors simulation.cpp Simulation::step()).
void buildInvMassEffKokkos(int numBodies, Kokkos::View< const unsigned char *, CpMem > asleep, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< float *, CpMem > invMassEff, float sleeperFrac)
Effective inverse mass for the solve: a sleeping body (real, or a periodic ghost whose real is asleep...
void wakeDisturbedKokkos(Kokkos::View< const ManifoldC *, CpMem > manifolds, int numManifolds, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const float *[3], CpMem > velPred, float wakeSpeed, Kokkos::View< unsigned char *, CpMem > asleep, Kokkos::View< unsigned char *, CpMem > sleepCounter, Kokkos::View< unsigned char *, CpMem > movingWall, Kokkos::View< int *, CpMem > curCount, int numReal)
Wake pass (before the solve): a sleeper is woken when actually disturbed.
int findCollisionsVerlet(Particles &P, float margin, float maxRad)
Verlet-cached impulse broadphase (single-GPU, non-periodic).
void computeManifoldSleepKokkos(Kokkos::View< const ManifoldC *, CpMem > manifolds, int numManifolds, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const unsigned char *, CpMem > asleep, Kokkos::View< unsigned char *, CpMem > manifoldSleep)
Per-manifold "both endpoints asleep" flag (a static wall, bodyB < 0, counts as asleep).
void growCopyView(V &v, std::size_t n, const char *label)
Grow-only (re)allocation of a copy-machinery view to at least n entries.
void wakeContactChangeKokkos(int numReal, Kokkos::View< const int *, CpMem > curCount, Kokkos::View< int *, CpMem > prevCount, Kokkos::View< const unsigned char *, CpMem > movingWall, Kokkos::View< unsigned char *, CpMem > asleep, Kokkos::View< unsigned char *, CpMem > sleepCounter, bool wakeOnChange)
Contact-set-change wake rule (b): wake any still-asleep body whose live contact count differs from th...
void predictVelocityKokkos(int n, V3 pos, Vf invMass, V3 vel, V4 quat, V3 angVel, V3 invInertia, V3 posPred, V4 quatPred, V3 velPred, V3 angVelPred, V3 deltaPos, V4 deltaQuat, V3 deltaVel, V3 deltaAngVel, Vi constraintCounts, F3 gravity, float dt, V3 extForce, V3 extTorque)
Predict velocity (gravity + gyroscopic precession), speculative position, and clear all deltas.
void applyThermostatKokkos(int numReal, V3 vel, Vf invMass, V3 angVel, V3 invInertia, V4 quat, double kB, double tau, double Ttarget, float dt)
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...
dem — portable (Kokkos) narrow-phase: SDF point-shell collision + boundary planes.
dem — portable (Kokkos) particle SoA container: the storage the dem flip pivots on.
dem — portable (Kokkos) periodic ghost generation (periodicity.cu / integration.cu).
dem — island sleeping / freezing for the single-GPU PGS statics path.
dem — the shared contact-solve driver: the full modern velocity + position solve sequence (warm-start...
Kokkos::View< WallSdf *, CpMem > walls
Kokkos::View< int *, CpMem > commitPerm
Kokkos::View< unsigned char *, CpMem > asleep
Kokkos::View< unsigned char *, CpMem > materialId
Kokkos::View< unsigned char *, CpMem > sideFlags
Kokkos::View< unsigned long long *, CpMem > prevContactKeys
Kokkos::View< unsigned char *, CpMem > manifoldPersistent
Kokkos::View< int, CpMem > manifoldCount
Kokkos::View< int *, CpMem > velPerm
Kokkos::View< unsigned char *, CpMem > contactSleep
Kokkos::View< float *, CpMem > prevLambda
void ensureCapacity(int newCap)
Kokkos::View< int *, CpMem > unitStart
Kokkos::View< ManifoldC *, CpMem > manifolds
Kokkos::View< float *, CpMem > vn0
Kokkos::View< int *, CpMem > levelKey
Kokkos::View< int *, CpMem > sleepCurCount
Kokkos::View< int *[2], CpMem > pairs
Kokkos::View< float *[3], CpMem > imageShift
Kokkos::View< int, CpMem > contactCount
Kokkos::View< unsigned char *, CpMem > sleepMovingWall
Kokkos::View< float *[3], CpMem > vt0
Kokkos::View< float *, CpMem > restRel
Kokkos::View< int *, CpMem > levelPerm
Kokkos::View< int *, CpMem > prevManifoldColor
Kokkos::View< unsigned long long *, CpMem > contactKeys
Kokkos::View< float *, CpMem > pairMaterials
Kokkos::View< ShapeDesc *, CpMem > shapes
Kokkos::View< int *, CpMem > prevContactColor
Kokkos::View< unsigned char *, CpMem > prevMatched
Kokkos::View< float *, CpMem > prevRestBank
Kokkos::View< float *, CpMem > restVPeak
Kokkos::View< float *, CpMem > restBank
Kokkos::View< int *, CpMem > posCommitPerm
Kokkos::View< unsigned long long *, CpMem > pairKeys
Kokkos::View< int, CpMem > topGhost
Kokkos::View< unsigned long long *, CpMem > prevPairKeys
Kokkos::View< int *, CpMem > posPerm
Kokkos::View< float *, CpMem > invMassEff
Kokkos::View< float *, CpMem > prevPosImpulse
Kokkos::View< int *, CpMem > contactColor
Kokkos::View< int *, CpMem > sleepPrevCount
Kokkos::View< float *, CpMem > sdfGrid
Kokkos::View< float *[3], CpMem > lambdaT
bool sleepWakeLostContact
Kokkos::View< float *[3], CpMem > prevLambdaT
Kokkos::View< int *, CpMem > unitColor
Kokkos::View< float, CpMem > maxOverlap
Kokkos::View< float *, CpMem > posLambdaContact
Kokkos::View< float *, CpMem > posImpulse
Kokkos::View< int *, CpMem > contactSlot
Kokkos::View< unsigned char *, CpMem > sleepCounter
Kokkos::View< float *, CpMem > lambdaAcc
Kokkos::View< long long *, CpMem > mlColorPacked
Kokkos::View< float *, CpMem > wallGrid
Kokkos::View< unsigned char *, CpMem > manifoldSleep
Kokkos::View< float *[3], CpMem > shell
Kokkos::View< float *, CpMem > prevRestVPeak
Kokkos::View< ContactC *, CpMem > contacts
Kokkos::View< unsigned char *, CpMem > groundedLevel
Kokkos::View< int *, CpMem > unitContacts
Kokkos::View< PlaneP *, CpMem > planes
Kokkos::View< int *, CpMem > manifoldColor
Single-GPU hooks: no ghost refresh, residuals are already global. Everything inlines away.