peclet-dem
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
peclet::dem Namespace Reference

Namespaces

namespace  detail
 

Classes

struct  ContactC
 Portable mirror of ParticleSystem.cuh ContactConstraint (the fields this reduction touches). More...
 
struct  Domain
 
struct  F3
 
struct  F4
 
struct  KE2
 Berendsen thermostat: reduce translational + rotational KE over real particles, compute the two scaling factors, and rescale linear/angular velocities. More...
 
struct  ManifoldC
 Portable mirror of ManifoldConstraint. More...
 
struct  Particles
 
struct  PlaneP
 
struct  ShapeDesc
 Portable mirror of ShapeDescriptor (analytic fields + a flat-array point shell). More...
 
class  Simulation
 Host-facing facade with std::vector setters/getters (binding-agnostic). More...
 
struct  WallSdf
 Static, world-space SDF container/geometry the particles collide against (a drum barrel, a hopper, a vibrating tray, ...). More...
 

Typedefs

using BpExec = Kokkos::DefaultExecutionSpace
 
using BpMem = BpExec::memory_space
 
using CpExec = Kokkos::DefaultExecutionSpace
 
using CpMem = CpExec::memory_space
 
using V3 = Kokkos::View< float *[3], CpMem >
 
using V4 = Kokkos::View< float *[4], CpMem >
 
using Vf = Kokkos::View< float *, CpMem >
 
using Vi = Kokkos::View< int *, CpMem >
 
using PosView = Kokkos::View< const float *[3], CpMem >
 
using QuatView = Kokkos::View< const float *[4], CpMem >
 
using ScalarF = Kokkos::View< const float *, CpMem >
 
using ScalarI = Kokkos::View< const int *, CpMem >
 
using ShellView = Kokkos::View< const float *[3], CpMem >
 
using GridView = Kokkos::View< const float *, CpMem >
 
using FrManifoldCounts = Kokkos::View< float *[2], CpMem >
 

Enumerations

enum  ShapeKind { SHAPE_GRID_SDF = 0 , SPHERE = 1 , HOLLOW_CYLINDER = 2 , BOX = 3 }
 

Functions

template<class PosV , class RadV , class PairsV , class CountV >
int findCollisionsArborX (PosV pos, RadV rad, int numParticles, int numReal, float margin, PairsV outPairs, CountV outCount, float boxCap=0.0f)
 Emit candidate collision pairs (i<j) for real particles into outPairs/outCount.
 
std::uint64_t pairKey (const ContactC &c)
 Canonical pair key: (min<<32)|max, or (idA<<32)|0xFFFFFFFF for a boundary (idB<0) contact.
 
void decodeKey (std::uint64_t key, int &bodyA, int &bodyB)
 Decode the canonical (bodyA, bodyB) from a pair key (bodyB = -1 for boundary).
 
ManifoldC transformContact (const ContactC &c)
 Per-contact transform to a single-point manifold, aligned to the canonical pair.
 
int reduceContactsToManifoldsKokkos (Kokkos::View< const ContactC *, CpMem > contacts, int n, Kokkos::View< ManifoldC *, CpMem > outManifolds, Kokkos::View< int, CpMem > outCount)
 Reduce n contacts to manifolds (one per unique canonical pair).
 
F3 add3 (F3 a, F3 b)
 
F3 sub3 (F3 a, F3 b)
 
F3 scale3 (F3 a, float s)
 
float dot3 (F3 a, F3 b)
 
float len3 (F3 v)
 
F3 cross3v (F3 a, F3 b)
 
F4 cross3 (F4 a, F4 b)
 
template<class V >
F3 ldF3 (const V &v, int i)
 
template<class V >
F4 ldF4 (const V &v, int i)
 
F3 rotateVector (F4 q, F3 v)
 
F3 invRotateVector (F4 q, F3 v)
 
F4 quatInverse (F4 q)
 
F4 quatMult (F4 a, F4 b)
 
float sdfSphere (F3 p, F4 params)
 
float sdfHollowCylinder (F3 p, F4 params)
 
float sdfBox (F3 p, F4 params)
 
float sdfEval (F3 p, int type, F4 params)
 
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)
 Predict velocity (gravity + gyroscopic precession), speculative position, and clear all deltas.
 
void applyVelocityDeltasKokkos (int n, V3 velPred, V3 angVelPred, V3 deltaVel, V3 deltaAngVel)
 Add accumulated velocity/angular deltas onto the predicted velocity, then clear the delta buffers.
 
void applyVelocityAndPredictPositionKokkos (int n, V3 pos, Vf invMass, V3 vel, V4 quat, V3 velPred, V3 angVelPred, V3 posPred, V4 quatPred, V3 angVel, float dt)
 Re-integration: persist solved velocity, trapezoidal position predict, quaternion integrate.
 
void computeContactCountsKokkos (Kokkos::View< const ContactC *, CpMem > contacts, int numContacts, Vi constraintCounts)
 Per-contact constraint-count pre-pass (active contacts, dist <= 0).
 
void applyUpdatesKokkos (int n, V3 posPred, V3 velPred, V3 deltaPos, V3 deltaVel, Vi constraintCounts)
 Jacobi count-averaged apply of position/velocity deltas, then clear deltas + counts.
 
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 applyThermostatKokkos (int numReal, V3 vel, Vf invMass, V3 angVel, V3 invInertia, V4 quat, double kB, double tau, double Ttarget, float dt)
 
void updateGrowthScalesKokkos (int n, Vf scale, Vf targetScale, float factor)
 Growth mode: scale = target * factor (when active).
 
void writeLammpsDump (const std::string &filename, int step, const std::vector< float > &pos, const std::vector< float > &vel, const std::vector< float > &quat, const std::vector< float > &radii, const float *boxMin, const float *boxMax, bool pbcEnabled)
 
void writeSdfVti (const std::string &filename, const std::vector< float > &grid, int rx, int ry, int rz, const float *minB, const float *maxB)
 
F3 loadF3 (PosView v, int i)
 
F4 loadF4 (QuatView v, int i)
 
float sampleGridSdf (F3 p, const ShapeDesc &d, GridView grid)
 Trilinearly sample an imported grid SDF at canonical point p.
 
float sampleWallSdf (F3 p, const WallSdf &w, GridView grid)
 Trilinearly sample a static world-space wall SDF at world point p (same "clamp + residual" extension as sampleGridSdf, so a probe outside the stored box gets a well-signed growing distance and a sane central-difference normal at the boundary).
 
float sdfEvalShape (F3 p, const ShapeDesc &d, GridView grid)
 Canonical-space SDF of a shape: analytic dispatch, or a trilinear grid sample for an imported grid SDF.
 
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{})
 Pair point-shell vs SDF contacts.
 
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)
 Per-real-particle contacts against a static world-space wall SDF set (a drum barrel, hopper, vibrating tray, ...).
 
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; analytic spheres use centre-minus-radius).
 
std::vector< float > generateSdfKokkos (int rx, int ry, int rz, F3 dmin, F3 dmax, int numReal, PosView pos, QuatView quat, ScalarF scale, ScalarI shapeId, Kokkos::View< const ShapeDesc *, CpMem > shapes, bool px, bool py, bool pz, GridView sdfGrid=GridView{})
 
int calculateGhostCapacity (int nReal, Domain dom, float skin)
 Padded particle-array capacity that leaves room for the periodic ghosts generateGhostsKokkos will emit: the real count plus an estimate of the boundary-shell ghost population, gated on which axes are actually periodic.
 
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)
 Generate periodic ghosts for particles [0,numReal).
 
std::vector< F3genCylinderShell (float radius, float height, float thickness, float spacing)
 
std::vector< F3genBoxShell (float hx, float hy, float hz, float spacing)
 
int readInt (Kokkos::View< int, CpMem > v)
 
float maxOwnedRadius (const Particles &P)
 Largest effective particle radius over the owned set (= max scale × globalScale, growth included).
 
int findCollisionsGrow (Particles &P, float margin)
 Broad phase with an automatically-grown pair buffer.
 
void demStep (Particles &P)
 One full XPBD DEM substep over the particle SoA (mirrors simulation.cpp Simulation::step()).
 
float computeOverlapsKokkos (Particles &P)
 Max pair interpenetration on the committed state (faithful to CUDA Simulation::compute_overlaps): copy committed pos/quat into the predicted buffers, regenerate the periodic ghosts from that state, then run the same broad/narrow phase as demStep and return the recorded max overlap.
 
void accumulateNormalImpulseKokkos (Kokkos::View< ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const float *[3], CpMem > velPred, Kokkos::View< const float *[3], CpMem > angVelPred, Kokkos::View< const int *, CpMem > realIdx, float growthRate)
 Force-chain normal load, accumulated over the velocity iterations: contacts(idx).friction_lambda_n += approach / w_n.
 
void computePlaneLoadKokkos (Kokkos::View< ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const float *[3], CpMem > velPred, Kokkos::View< const float *[3], CpMem > angVelPred, FrManifoldCounts planeFriction)
 Plane (idB<0) one-shot loads.
 
void countFrictionContactsKokkos (Kokkos::View< const ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const int *, CpMem > realIdx, FrManifoldCounts planeFriction)
 Per-body active-contact count into planeFriction(:,1).
 
void solveContactFrictionKokkos (Kokkos::View< const ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const float *[3], CpMem > velPred, Kokkos::View< const float *[3], CpMem > angVelPred, Kokkos::View< const int *, CpMem > realIdx, FrManifoldCounts planeFriction, float frictionDynamic, Kokkos::View< float *[3], CpMem > deltaVel, Kokkos::View< float *[3], CpMem > deltaAngVel)
 One count-averaged Coulomb friction sweep.
 
void solvePositionKokkos (Kokkos::View< const ContactC *, CpMem > contacts, int numContacts, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > posPred, Kokkos::View< const float *[4], CpMem > quatPred, Kokkos::View< const float *[4], CpMem > quatStatic, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< float *[3], CpMem > deltaPos, Kokkos::View< float *[4], CpMem > deltaQuat, Kokkos::View< int *, CpMem > constraintCounts, Kokkos::View< float, CpMem > maxOverlap)
 Accumulate XPBD position corrections for numContacts contacts.
 
void solveVelocityKokkos (Kokkos::View< const ManifoldC *, CpMem > manifolds, int numManifolds, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const float *[4], CpMem > quat, Kokkos::View< const float *[3], CpMem > velPred, Kokkos::View< const float *[3], CpMem > angVelPred, Kokkos::View< const int *, CpMem > realIdx, float growthRate, float restitutionNormal, Kokkos::View< float *[3], CpMem > deltaVel, Kokkos::View< float *[3], CpMem > deltaAngVel)
 Accumulate normal-restitution velocity deltas for numManifolds manifolds.
 

Typedef Documentation

◆ BpExec

using peclet::dem::BpExec = typedef Kokkos::DefaultExecutionSpace

Definition at line 21 of file broadphase_arborx.hpp.

◆ BpMem

using peclet::dem::BpMem = typedef BpExec::memory_space

Definition at line 22 of file broadphase_arborx.hpp.

◆ CpExec

using peclet::dem::CpExec = typedef Kokkos::DefaultExecutionSpace

Definition at line 27 of file contact_preprocessing.hpp.

◆ CpMem

using peclet::dem::CpMem = typedef CpExec::memory_space

Definition at line 28 of file contact_preprocessing.hpp.

◆ V3

using peclet::dem::V3 = typedef Kokkos::View<float* [3], CpMem>

Definition at line 24 of file integration.hpp.

◆ V4

using peclet::dem::V4 = typedef Kokkos::View<float* [4], CpMem>

Definition at line 25 of file integration.hpp.

◆ Vf

using peclet::dem::Vf = typedef Kokkos::View<float*, CpMem>

Definition at line 26 of file integration.hpp.

◆ Vi

using peclet::dem::Vi = typedef Kokkos::View<int*, CpMem>

Definition at line 27 of file integration.hpp.

◆ PosView

using peclet::dem::PosView = typedef Kokkos::View<const float* [3], CpMem>

Definition at line 76 of file narrowphase.hpp.

◆ QuatView

using peclet::dem::QuatView = typedef Kokkos::View<const float* [4], CpMem>

Definition at line 77 of file narrowphase.hpp.

◆ ScalarF

using peclet::dem::ScalarF = typedef Kokkos::View<const float*, CpMem>

Definition at line 78 of file narrowphase.hpp.

◆ ScalarI

using peclet::dem::ScalarI = typedef Kokkos::View<const int*, CpMem>

Definition at line 79 of file narrowphase.hpp.

◆ ShellView

using peclet::dem::ShellView = typedef Kokkos::View<const float* [3], CpMem>

Definition at line 80 of file narrowphase.hpp.

◆ GridView

using peclet::dem::GridView = typedef Kokkos::View<const float*, CpMem>

Definition at line 81 of file narrowphase.hpp.

◆ FrManifoldCounts

using peclet::dem::FrManifoldCounts = typedef Kokkos::View<float* [2], CpMem>

Definition at line 25 of file solver_friction.hpp.

Enumeration Type Documentation

◆ ShapeKind

Enumerator
SHAPE_GRID_SDF 
SPHERE 
HOLLOW_CYLINDER 
BOX 

Definition at line 77 of file dem_portable.hpp.

Function Documentation

◆ findCollisionsArborX()

template<class PosV , class RadV , class PairsV , class CountV >
int peclet::dem::findCollisionsArborX ( PosV  pos,
RadV  rad,
int  numParticles,
int  numReal,
float  margin,
PairsV  outPairs,
CountV  outCount,
float  boxCap = 0.0f 
)
inline

Emit candidate collision pairs (i<j) for real particles into outPairs/outCount.

pos[numParticles][3] positions of all particles (real first, then ghosts) rad[numParticles] effective radius per particle (scale * global_scale) numReal only particles [0,numReal) issue queries (own real particles) margin safety margin added to every box half-width (cuBQL uses 0.1*global_scale) outPairs[maxPairs][2] preallocated output; outCount is the (clamped) number found Returns the number of pairs found (may exceed maxPairs if the buffer is too small).

Definition at line 36 of file broadphase_arborx.hpp.

References PECLET_DEM_SANE_BOX.

Referenced by findCollisionsGrow().

◆ pairKey()

std::uint64_t peclet::dem::pairKey ( const ContactC c)

Canonical pair key: (min<<32)|max, or (idA<<32)|0xFFFFFFFF for a boundary (idB<0) contact.

Definition at line 65 of file contact_preprocessing.hpp.

References peclet::dem::ContactC::bodyA, and peclet::dem::ContactC::bodyB.

Referenced by reduceContactsToManifoldsKokkos().

◆ decodeKey()

void peclet::dem::decodeKey ( std::uint64_t  key,
int &  bodyA,
int &  bodyB 
)

Decode the canonical (bodyA, bodyB) from a pair key (bodyB = -1 for boundary).

Definition at line 75 of file contact_preprocessing.hpp.

Referenced by reduceContactsToManifoldsKokkos().

◆ transformContact()

ManifoldC peclet::dem::transformContact ( const ContactC c)

Per-contact transform to a single-point manifold, aligned to the canonical pair.

Inactive contacts (dist > 0) contribute a zero manifold with num_points = 0. Mirrors ContactToManifold + TransformAndFilter from contact_preprocessing.cu.

Definition at line 84 of file contact_preprocessing.hpp.

References peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, peclet::dem::ContactC::boundaryRestitution, peclet::dem::ContactC::boundaryVel, cross3(), peclet::dem::ContactC::dist, peclet::dem::ContactC::normal, peclet::dem::ContactC::rA, peclet::dem::ContactC::rB, peclet::dem::F4::x, peclet::dem::F4::y, and peclet::dem::F4::z.

Referenced by reduceContactsToManifoldsKokkos().

◆ reduceContactsToManifoldsKokkos()

int peclet::dem::reduceContactsToManifoldsKokkos ( Kokkos::View< const ContactC *, CpMem contacts,
int  n,
Kokkos::View< ManifoldC *, CpMem outManifolds,
Kokkos::View< int, CpMem outCount 
)
inline

◆ add3()

◆ sub3()

◆ scale3()

◆ dot3()

◆ len3()

float peclet::dem::len3 ( F3  v)

Definition at line 37 of file dem_portable.hpp.

References dot3().

Referenced by detectWallSdfKokkos(), and sdfSphere().

◆ cross3v()

◆ cross3()

F4 peclet::dem::cross3 ( F4  a,
F4  b 
)

Definition at line 43 of file dem_portable.hpp.

References peclet::dem::F4::x, peclet::dem::F4::y, and peclet::dem::F4::z.

Referenced by transformContact().

◆ ldF3()

◆ ldF4()

template<class V >
F4 peclet::dem::ldF4 ( const V &  v,
int  i 
)

◆ rotateVector()

◆ invRotateVector()

◆ quatInverse()

F4 peclet::dem::quatInverse ( F4  q)

◆ quatMult()

F4 peclet::dem::quatMult ( F4  a,
F4  b 
)

◆ sdfSphere()

float peclet::dem::sdfSphere ( F3  p,
F4  params 
)

Definition at line 79 of file dem_portable.hpp.

References len3(), and peclet::dem::F4::x.

Referenced by sdfEval().

◆ sdfHollowCylinder()

float peclet::dem::sdfHollowCylinder ( F3  p,
F4  params 
)

◆ sdfBox()

float peclet::dem::sdfBox ( F3  p,
F4  params 
)

◆ sdfEval()

float peclet::dem::sdfEval ( F3  p,
int  type,
F4  params 
)

Definition at line 105 of file dem_portable.hpp.

References BOX, HOLLOW_CYLINDER, sdfBox(), sdfHollowCylinder(), sdfSphere(), and SPHERE.

Referenced by sdfEvalShape().

◆ predictVelocityKokkos()

void peclet::dem::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 
)
inline

Predict velocity (gravity + gyroscopic precession), speculative position, and clear all deltas.

Definition at line 44 of file integration.hpp.

References add3(), cross3v(), invRotateVector(), ldF3(), ldF4(), rotateVector(), scale3(), peclet::dem::detail::st3(), peclet::dem::detail::st4(), peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by demStep().

◆ applyVelocityDeltasKokkos()

void peclet::dem::applyVelocityDeltasKokkos ( int  n,
V3  velPred,
V3  angVelPred,
V3  deltaVel,
V3  deltaAngVel 
)
inline

Add accumulated velocity/angular deltas onto the predicted velocity, then clear the delta buffers.

Definition at line 97 of file integration.hpp.

References add3(), ldF3(), and peclet::dem::detail::st3().

Referenced by demStep().

◆ applyVelocityAndPredictPositionKokkos()

void peclet::dem::applyVelocityAndPredictPositionKokkos ( int  n,
V3  pos,
Vf  invMass,
V3  vel,
V4  quat,
V3  velPred,
V3  angVelPred,
V3  posPred,
V4  quatPred,
V3  angVel,
float  dt 
)
inline

Re-integration: persist solved velocity, trapezoidal position predict, quaternion integrate.

Definition at line 112 of file integration.hpp.

References add3(), ldF3(), ldF4(), scale3(), peclet::dem::detail::st3(), peclet::dem::detail::st4(), peclet::dem::F4::w, peclet::dem::F3::x, peclet::dem::F4::x, peclet::dem::F3::y, peclet::dem::F4::y, peclet::dem::F3::z, and peclet::dem::F4::z.

Referenced by demStep().

◆ computeContactCountsKokkos()

void peclet::dem::computeContactCountsKokkos ( Kokkos::View< const ContactC *, CpMem contacts,
int  numContacts,
Vi  constraintCounts 
)
inline

Per-contact constraint-count pre-pass (active contacts, dist <= 0).

Definition at line 151 of file integration.hpp.

References peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, and peclet::dem::ContactC::dist.

◆ applyUpdatesKokkos()

void peclet::dem::applyUpdatesKokkos ( int  n,
V3  posPred,
V3  velPred,
V3  deltaPos,
V3  deltaVel,
Vi  constraintCounts 
)
inline

Jacobi count-averaged apply of position/velocity deltas, then clear deltas + counts.

Definition at line 168 of file integration.hpp.

References add3(), ldF3(), scale3(), and peclet::dem::detail::st3().

Referenced by demStep().

◆ finalCommitKokkos()

void peclet::dem::finalCommitKokkos ( int  n,
V3  pos,
Vf  invMass,
V3  posPred,
V4  quat,
V4  quatPred,
Domain  dom 
)
inline

◆ applyThermostatKokkos()

void peclet::dem::applyThermostatKokkos ( int  numReal,
V3  vel,
Vf  invMass,
V3  angVel,
V3  invInertia,
V4  quat,
double  kB,
double  tau,
double  Ttarget,
float  dt 
)
inline

◆ updateGrowthScalesKokkos()

void peclet::dem::updateGrowthScalesKokkos ( int  n,
Vf  scale,
Vf  targetScale,
float  factor 
)
inline

Growth mode: scale = target * factor (when active).

Definition at line 275 of file integration.hpp.

Referenced by demStep(), and peclet::dem::Simulation::setGrowthParams().

◆ writeLammpsDump()

void peclet::dem::writeLammpsDump ( const std::string &  filename,
int  step,
const std::vector< float > &  pos,
const std::vector< float > &  vel,
const std::vector< float > &  quat,
const std::vector< float > &  radii,
const float *  boxMin,
const float *  boxMax,
bool  pbcEnabled 
)
inline

Definition at line 23 of file io.hpp.

Referenced by peclet::dem::Simulation::exportLammps(), and NB_MODULE().

◆ writeSdfVti()

void peclet::dem::writeSdfVti ( const std::string &  filename,
const std::vector< float > &  grid,
int  rx,
int  ry,
int  rz,
const float *  minB,
const float *  maxB 
)
inline

Definition at line 86 of file io.hpp.

Referenced by peclet::dem::Simulation::exportSdf().

◆ loadF3()

F3 peclet::dem::loadF3 ( PosView  v,
int  i 
)

Definition at line 83 of file narrowphase.hpp.

Referenced by detectBoundaryKokkos(), and detectWallSdfKokkos().

◆ loadF4()

F4 peclet::dem::loadF4 ( QuatView  v,
int  i 
)

Definition at line 86 of file narrowphase.hpp.

Referenced by detectBoundaryKokkos(), and detectWallSdfKokkos().

◆ sampleGridSdf()

float peclet::dem::sampleGridSdf ( F3  p,
const ShapeDesc d,
GridView  grid 
)

Trilinearly sample an imported grid SDF at canonical point p.

The query is clamped into the sample lattice and the Euclidean distance from p to that clamped point is added back, so a probe outside the stored box gets a monotonically growing (positive) distance instead of a flat clamped value — the standard "clamp + residual" extension that keeps the far field well-signed and the central-difference normal sane near the grid boundary. Interior samples are exact trilinear. Requires nx,ny,nz >= 2 (the shape builder guarantees this).

Definition at line 96 of file narrowphase.hpp.

References peclet::dem::ShapeDesc::gridInvSpacing, peclet::dem::ShapeDesc::gridOffset, peclet::dem::ShapeDesc::gridOrigin, peclet::dem::ShapeDesc::nx, peclet::dem::ShapeDesc::ny, peclet::dem::ShapeDesc::nz, peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by sdfEvalShape().

◆ sampleWallSdf()

float peclet::dem::sampleWallSdf ( F3  p,
const WallSdf w,
GridView  grid 
)

Trilinearly sample a static world-space wall SDF at world point p (same "clamp + residual" extension as sampleGridSdf, so a probe outside the stored box gets a well-signed growing distance and a sane central-difference normal at the boundary).

Positive in the void, negative in the wall.

Definition at line 128 of file narrowphase.hpp.

References peclet::dem::WallSdf::gridOffset, peclet::dem::WallSdf::invSpacing, peclet::dem::WallSdf::nx, peclet::dem::WallSdf::ny, peclet::dem::WallSdf::nz, peclet::dem::WallSdf::origin, peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by detectWallSdfKokkos().

◆ sdfEvalShape()

float peclet::dem::sdfEvalShape ( F3  p,
const ShapeDesc d,
GridView  grid 
)

Canonical-space SDF of a shape: analytic dispatch, or a trilinear grid sample for an imported grid SDF.

grid may be an empty View when no grid shape is present.

Definition at line 158 of file narrowphase.hpp.

References peclet::dem::ShapeDesc::params, sampleGridSdf(), sdfEval(), SHAPE_GRID_SDF, and peclet::dem::ShapeDesc::type.

◆ detectContactsKokkos()

void peclet::dem::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{} 
)
inline

Pair point-shell vs SDF contacts.

pairs[numPairs][2] are (idA,idB) from the broad-phase; emits ContactC into outContacts guarded by atomic outCount (clamped to outContacts.extent(0)).

Definition at line 166 of file narrowphase.hpp.

Referenced by computeOverlapsKokkos(), and demStep().

◆ detectWallSdfKokkos()

void peclet::dem::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 
)
inline

Per-real-particle contacts against a static world-space wall SDF set (a drum barrel, hopper, vibrating tray, ...).

Mirrors detectBoundaryKokkos but the boundary is the wall's zero level set: each surface point (or the sphere centre) is tested against sampleWallSdf, the outward gradient is the contact normal, and every emitted contact carries the wall's rigid-body surface velocity at the contact point plus the wall's binary (particle–wall) restitution/friction — so the moving-wall terms flow through the manifold velocity solve and the per-contact friction sweep. bodyB = -1 (a boundary, like a plane); the wall surface point is stored in rB for the position solve's plane-linearised non-penetration constraint.

Definition at line 259 of file narrowphase.hpp.

References add3(), peclet::dem::WallSdf::angVel, peclet::dem::ContactC::bodyA, peclet::dem::WallSdf::center, cross3v(), peclet::dem::WallSdf::friction, len3(), peclet::dem::WallSdf::linVel, loadF3(), loadF4(), peclet::dem::ShapeDesc::numPoints, peclet::dem::ShapeDesc::params, peclet::dem::WallSdf::restitution, rotateVector(), sampleWallSdf(), scale3(), peclet::dem::ShapeDesc::shellOffset, sub3(), peclet::dem::F3::x, peclet::dem::F4::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by computeOverlapsKokkos(), and demStep().

◆ detectBoundaryKokkos()

void peclet::dem::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 
)
inline

Per-real-particle contacts against explicit planes (point-shell shapes test each surface point; analytic spheres use centre-minus-radius).

bodyB = -1; plane anchor stored in rB.

Definition at line 345 of file narrowphase.hpp.

References add3(), peclet::dem::ContactC::bodyA, dot3(), loadF3(), loadF4(), peclet::dem::PlaneP::normal, peclet::dem::ShapeDesc::numPoints, peclet::dem::ShapeDesc::params, peclet::dem::PlaneP::point, rotateVector(), scale3(), peclet::dem::ShapeDesc::shellOffset, sub3(), peclet::dem::F3::x, peclet::dem::F4::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by computeOverlapsKokkos(), and demStep().

◆ generateSdfKokkos()

std::vector< float > peclet::dem::generateSdfKokkos ( int  rx,
int  ry,
int  rz,
F3  dmin,
F3  dmax,
int  numReal,
PosView  pos,
QuatView  quat,
ScalarF  scale,
ScalarI  shapeId,
Kokkos::View< const ShapeDesc *, CpMem shapes,
bool  px,
bool  py,
bool  pz,
GridView  sdfGrid = GridView{} 
)
inline

Definition at line 25 of file output_sdf.hpp.

Referenced by peclet::dem::Simulation::getSdfGrid().

◆ calculateGhostCapacity()

int peclet::dem::calculateGhostCapacity ( int  nReal,
Domain  dom,
float  skin 
)
inline

Padded particle-array capacity that leaves room for the periodic ghosts generateGhostsKokkos will emit: the real count plus an estimate of the boundary-shell ghost population, gated on which axes are actually periodic.

Faithful port of the CUDA Simulation::calculate_capacity (small/dense box -> full 26-neighbour headroom; large box -> a few times the boundary-shell volume fraction), with the periodicity gating added so a closed or partly-periodic box is not over-allocated. skin is the ghost band width at each periodic face (1.0*globalScale in the solver).

Definition at line 25 of file periodicity.hpp.

References peclet::dem::Domain::periodic_x, peclet::dem::Domain::periodic_y, peclet::dem::Domain::periodic_z, peclet::dem::Domain::size, peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by computeOverlapsKokkos(), and demStep().

◆ generateGhostsKokkos()

void peclet::dem::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 
)
inline

Generate periodic ghosts for particles [0,numReal).

topGhost must be pre-seeded to numReal (the first free slot); on return it holds the total particle count. Slots beyond capacity are dropped. skin is the ghost band width at each periodic face.

Definition at line 43 of file periodicity.hpp.

References add3(), ldF3(), ldF4(), peclet::dem::Domain::max, peclet::dem::Domain::min, peclet::dem::Domain::periodic_x, peclet::dem::Domain::periodic_y, peclet::dem::Domain::periodic_z, peclet::dem::Domain::size, peclet::dem::detail::st3(), peclet::dem::detail::st4(), peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by computeOverlapsKokkos(), and demStep().

◆ genCylinderShell()

std::vector< F3 > peclet::dem::genCylinderShell ( float  radius,
float  height,
float  thickness,
float  spacing 
)
inline

Definition at line 21 of file shapes_portable.hpp.

Referenced by peclet::dem::Simulation::initializeShape().

◆ genBoxShell()

std::vector< F3 > peclet::dem::genBoxShell ( float  hx,
float  hy,
float  hz,
float  spacing 
)
inline

Definition at line 80 of file shapes_portable.hpp.

Referenced by peclet::dem::Simulation::initializeShape().

◆ readInt()

int peclet::dem::readInt ( Kokkos::View< int, CpMem v)
inline

◆ maxOwnedRadius()

float peclet::dem::maxOwnedRadius ( const Particles P)
inline

Largest effective particle radius over the owned set (= max scale × globalScale, growth included).

The ghost band + broadphase margin are sized off THIS, not globalScale directly, so they scale with the actual grain size — set particles in SI (radius = 1e-3, globalScale left at 1) and the halo layer follows automatically. For the usual convention (globalScale ≈ grain size, scale ≈ 1) it is numerically identical to the old 1.0*globalScale.

Definition at line 51 of file sim.hpp.

References peclet::dem::Particles::baseRadius, peclet::dem::Particles::globalScale, peclet::dem::Particles::numReal, and peclet::dem::Particles::scale.

Referenced by computeOverlapsKokkos(), and demStep().

◆ findCollisionsGrow()

int peclet::dem::findCollisionsGrow ( Particles P,
float  margin 
)
inline

Broad phase with an automatically-grown pair buffer.

findCollisionsArborX guards its pair WRITES at maxPairs but returns the RAW candidate count, which can exceed P.pairs' capacity once a bed compacts (more neighbour pairs than the buffer holds — e.g. a fluidized bed driven denser by the CFD-DEM drag). Feeding that raw count straight into detectContactsKokkos as its loop bound makes the narrowphase read P.pairs out of bounds → cudaErrorIllegalAddress. Here we detect the overflow, reallocate P.pairs (with headroom so an oscillating count doesn't realloc every step) and re-run once so no candidate pair is silently dropped, then clamp defensively so the returned count is ALWAYS ≤ the buffer extent — the narrowphase can never walk off the end regardless.

Definition at line 72 of file sim.hpp.

References peclet::dem::Particles::crad(), peclet::dem::Particles::domain, findCollisionsArborX(), peclet::dem::Particles::maxPairs, peclet::dem::Particles::numParticles, peclet::dem::Particles::numReal, peclet::dem::Particles::pairCount, peclet::dem::Particles::pairs, peclet::dem::Particles::posPred, peclet::dem::Domain::size, peclet::dem::F3::x, peclet::dem::F3::y, and peclet::dem::F3::z.

Referenced by computeOverlapsKokkos(), and demStep().

◆ demStep()

void peclet::dem::demStep ( Particles P)
inline

One full XPBD DEM substep over the particle SoA (mirrors simulation.cpp Simulation::step()).

Definition at line 87 of file sim.hpp.

References accumulateNormalImpulseKokkos(), peclet::dem::Particles::angVel, peclet::dem::Particles::angVelPred, applyThermostatKokkos(), applyUpdatesKokkos(), applyVelocityAndPredictPositionKokkos(), applyVelocityDeltasKokkos(), peclet::dem::Particles::baseRadius, calculateGhostCapacity(), peclet::dem::Particles::capacity, computePlaneLoadKokkos(), peclet::dem::Particles::constraintCounts, peclet::dem::Particles::contactCount, peclet::dem::Particles::contacts, countFrictionContactsKokkos(), peclet::dem::Particles::deltaAngVel, peclet::dem::Particles::deltaPos, peclet::dem::Particles::deltaQuat, peclet::dem::Particles::deltaVel, detectBoundaryKokkos(), detectContactsKokkos(), detectWallSdfKokkos(), peclet::dem::Particles::domain, peclet::dem::Particles::dt, peclet::dem::Particles::ensureCapacity(), peclet::dem::Particles::extForce, finalCommitKokkos(), findCollisionsGrow(), peclet::dem::Particles::frictionDynamic, generateGhostsKokkos(), peclet::dem::Particles::globalScale, peclet::dem::Particles::gravity, peclet::dem::Particles::growthFactor, peclet::dem::Particles::growthRate, peclet::dem::Particles::invInertia, peclet::dem::Particles::invMass, peclet::dem::Particles::manifoldCount, peclet::dem::Particles::manifolds, peclet::dem::Particles::maxOverlap, maxOwnedRadius(), peclet::dem::Particles::numParticles, peclet::dem::Particles::numPlanes, peclet::dem::Particles::numReal, peclet::dem::Particles::numWalls, peclet::dem::Particles::pairs, peclet::dem::Particles::planeFriction, peclet::dem::Particles::planes, peclet::dem::Particles::pos, peclet::dem::Particles::positionIterations, peclet::dem::Particles::posPred, predictVelocityKokkos(), peclet::dem::Particles::quat, peclet::dem::Particles::quatPred, peclet::dem::Particles::rad, readInt(), peclet::dem::Particles::realIndices, reduceContactsToManifoldsKokkos(), peclet::dem::Particles::restitutionNormal, peclet::dem::Particles::scale, peclet::dem::Particles::sdfGrid, peclet::dem::Particles::shapeId, peclet::dem::Particles::shapes, peclet::dem::Particles::shell, solveContactFrictionKokkos(), solvePositionKokkos(), solveVelocityKokkos(), peclet::dem::Particles::targetScale, peclet::dem::Particles::thermostatKB, peclet::dem::Particles::thermostatTau, peclet::dem::Particles::thermostatTemp, peclet::dem::Particles::topGhost, updateGrowthScalesKokkos(), peclet::dem::Particles::vel, peclet::dem::Particles::velocityIterations, peclet::dem::Particles::velPred, peclet::dem::Particles::wallFrictionMax, peclet::dem::Particles::wallGrid, and peclet::dem::Particles::walls.

Referenced by peclet::dem::Simulation::step().

◆ computeOverlapsKokkos()

float peclet::dem::computeOverlapsKokkos ( Particles P)
inline

Max pair interpenetration on the committed state (faithful to CUDA Simulation::compute_overlaps): copy committed pos/quat into the predicted buffers, regenerate the periodic ghosts from that state, then run the same broad/narrow phase as demStep and return the recorded max overlap.

No solve.

Definition at line 203 of file sim.hpp.

References peclet::dem::Particles::angVel, peclet::dem::Particles::angVelPred, peclet::dem::Particles::baseRadius, calculateGhostCapacity(), peclet::dem::Particles::capacity, peclet::dem::Particles::contactCount, peclet::dem::Particles::contacts, detectBoundaryKokkos(), detectContactsKokkos(), detectWallSdfKokkos(), peclet::dem::Particles::domain, peclet::dem::Particles::ensureCapacity(), findCollisionsGrow(), generateGhostsKokkos(), peclet::dem::Particles::globalScale, peclet::dem::Particles::invMass, peclet::dem::Particles::maxOverlap, maxOwnedRadius(), peclet::dem::Particles::numParticles, peclet::dem::Particles::numPlanes, peclet::dem::Particles::numReal, peclet::dem::Particles::numWalls, peclet::dem::Particles::pairs, peclet::dem::Particles::planes, peclet::dem::Particles::pos, peclet::dem::Particles::posPred, peclet::dem::Particles::quat, peclet::dem::Particles::quatPred, peclet::dem::Particles::rad, readInt(), peclet::dem::Particles::realIndices, peclet::dem::Particles::scale, peclet::dem::Particles::sdfGrid, peclet::dem::Particles::shapeId, peclet::dem::Particles::shapes, peclet::dem::Particles::shell, peclet::dem::Particles::topGhost, peclet::dem::Particles::vel, peclet::dem::Particles::velPred, peclet::dem::Particles::wallGrid, and peclet::dem::Particles::walls.

Referenced by peclet::dem::Simulation::computeOverlaps().

◆ accumulateNormalImpulseKokkos()

void peclet::dem::accumulateNormalImpulseKokkos ( Kokkos::View< ContactC *, CpMem contacts,
int  numContacts,
Kokkos::View< const float *, CpMem invMass,
Kokkos::View< const float *[3], CpMem invInertia,
Kokkos::View< const float *[3], CpMem velPred,
Kokkos::View< const float *[3], CpMem angVelPred,
Kokkos::View< const int *, CpMem realIdx,
float  growthRate 
)
inline

Force-chain normal load, accumulated over the velocity iterations: contacts(idx).friction_lambda_n += approach / w_n.

Body-body AND wall (boundary) contacts — a grain buried under the bed thus gets the WEIGHT TRANSMITTED FROM ABOVE pressing it into the wall, not just its own one-shot gravity approach (computePlaneLoad). Without this a deep bed slips against a moving wall instead of being dragged up (a rotating drum stays flat).

Definition at line 32 of file solver_friction.hpp.

References add3(), peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, peclet::dem::ContactC::boundaryVel, peclet::dem::detail::computeW(), cross3v(), dot3(), ldF3(), peclet::dem::ContactC::normal, peclet::dem::ContactC::rA, peclet::dem::ContactC::rB, scale3(), sub3(), peclet::dem::F4::x, peclet::dem::F4::y, and peclet::dem::F4::z.

Referenced by demStep().

◆ computePlaneLoadKokkos()

void peclet::dem::computePlaneLoadKokkos ( Kokkos::View< ContactC *, CpMem contacts,
int  numContacts,
Kokkos::View< const float *, CpMem invMass,
Kokkos::View< const float *[3], CpMem invInertia,
Kokkos::View< const float *[3], CpMem velPred,
Kokkos::View< const float *[3], CpMem angVelPred,
FrManifoldCounts  planeFriction 
)
inline

Plane (idB<0) one-shot loads.

Zeros planeFriction first (both columns), then sets the per-contact friction_lambda_n and the per-body max plane load (.x).

Definition at line 87 of file solver_friction.hpp.

References add3(), peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, peclet::dem::ContactC::boundaryVel, peclet::dem::detail::computeW(), cross3v(), dot3(), ldF3(), peclet::dem::ContactC::normal, peclet::dem::ContactC::rA, sub3(), peclet::dem::F4::x, peclet::dem::F4::y, and peclet::dem::F4::z.

Referenced by demStep().

◆ countFrictionContactsKokkos()

void peclet::dem::countFrictionContactsKokkos ( Kokkos::View< const ContactC *, CpMem contacts,
int  numContacts,
Kokkos::View< const int *, CpMem realIdx,
FrManifoldCounts  planeFriction 
)
inline

Per-body active-contact count into planeFriction(:,1).

Definition at line 123 of file solver_friction.hpp.

References peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, and peclet::dem::ContactC::friction_lambda_n.

Referenced by demStep().

◆ solveContactFrictionKokkos()

void peclet::dem::solveContactFrictionKokkos ( Kokkos::View< const ContactC *, CpMem contacts,
int  numContacts,
Kokkos::View< const float *, CpMem invMass,
Kokkos::View< const float *[3], CpMem invInertia,
Kokkos::View< const float *[3], CpMem velPred,
Kokkos::View< const float *[3], CpMem angVelPred,
Kokkos::View< const int *, CpMem realIdx,
FrManifoldCounts  planeFriction,
float  frictionDynamic,
Kokkos::View< float *[3], CpMem deltaVel,
Kokkos::View< float *[3], CpMem deltaAngVel 
)
inline

One count-averaged Coulomb friction sweep.

Zeros the delta arrays first, then accumulates the tangential impulse (clamped by mu*normal-load, divided by the larger contact count) into them.

Definition at line 142 of file solver_friction.hpp.

References add3(), peclet::dem::ContactC::bodyA, peclet::dem::ContactC::bodyB, peclet::dem::ContactC::boundaryFriction, peclet::dem::ContactC::boundaryVel, cross3v(), dot3(), peclet::dem::ContactC::friction_lambda_n, ldF3(), peclet::dem::ContactC::normal, peclet::dem::ContactC::rA, peclet::dem::ContactC::rB, scale3(), sub3(), peclet::dem::F3::x, peclet::dem::F4::x, peclet::dem::F3::y, peclet::dem::F4::y, peclet::dem::F3::z, and peclet::dem::F4::z.

Referenced by demStep().

◆ solvePositionKokkos()

void peclet::dem::solvePositionKokkos ( Kokkos::View< const ContactC *, CpMem contacts,
int  numContacts,
Kokkos::View< const float *, CpMem invMass,
Kokkos::View< const float *[3], CpMem posPred,
Kokkos::View< const float *[4], CpMem quatPred,
Kokkos::View< const float *[4], CpMem quatStatic,
Kokkos::View< const float *[3], CpMem invInertia,
Kokkos::View< float *[3], CpMem deltaPos,
Kokkos::View< float *[4], CpMem deltaQuat,
Kokkos::View< int *, CpMem constraintCounts,
Kokkos::View< float, CpMem maxOverlap 
)
inline

◆ solveVelocityKokkos()

void peclet::dem::solveVelocityKokkos ( Kokkos::View< const ManifoldC *, CpMem manifolds,
int  numManifolds,
Kokkos::View< const float *, CpMem invMass,
Kokkos::View< const float *[3], CpMem invInertia,
Kokkos::View< const float *[4], CpMem quat,
Kokkos::View< const float *[3], CpMem velPred,
Kokkos::View< const float *[3], CpMem angVelPred,
Kokkos::View< const int *, CpMem realIdx,
float  growthRate,
float  restitutionNormal,
Kokkos::View< float *[3], CpMem deltaVel,
Kokkos::View< float *[3], CpMem deltaAngVel 
)
inline