peclet-dem 1.1.0
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
solve_copies.hpp File Reference

dem — body copies of the contact solve (docs/contact_solve_framework.md §4.4, §4.5, §WO-4 item 2): hub copies of a colouring vertex above kHubEdgeBudget edges, the fold groups of a phase (hubs; demStep's periodic images in the position phase), the mass-split solve views, and the seed / fold / re-seed kernels demSolveContacts runs around its sweeps. More...

#include <cstddef>
#include <cstdint>
#include <Kokkos_Core.hpp>
#include <Kokkos_Sort.hpp>
#include <string>
#include "contact_preprocessing.hpp"
#include "particles.hpp"

Go to the source code of this file.

Namespaces

namespace  peclet
 
namespace  peclet::dem
 

Functions

template<class V >
void peclet::dem::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 peclet::dem::velocityEdgeEndsKokkos (Kokkos::View< const ManifoldC *, CpMem > manifolds, int nm, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const int *, CpMem > color, Kokkos::View< int *, CpMem > eA, Kokkos::View< int *, CpMem > eB)
 Velocity-phase colouring edges: the vertices realIdx(bodyA / bodyB) of each manifold (-1: a wall end, or both ends of an inactive (-2) manifold).
 
void peclet::dem::positionEdgeEndsKokkos (Kokkos::View< const ContactC *, CpMem > contacts, const PosUnits &units, int nu, Kokkos::View< const int *, CpMem > color, Kokkos::View< int *, CpMem > eA, Kokkos::View< int *, CpMem > eB)
 Position-phase colouring edges: one per unit, the leader contact's raw (bodyA, bodyB); active = the unit is not sleep-masked (colour != -2).
 
void peclet::dem::vertexDegreeKokkos (Kokkos::View< const int *, CpMem > eA, Kokkos::View< const int *, CpMem > eB, int nE, int nV, Kokkos::View< int *, CpMem > deg)
 Per-vertex active degree over [0, nV) (§4.4 step 1). Wall edges have one endpoint.
 
void peclet::dem::buildHubCopiesKokkos (Kokkos::View< const int *, CpMem > eA, Kokkos::View< const int *, CpMem > eB, int nE, int nV, int slotBase, Kokkos::View< const int *, CpMem > deg, PhaseCopies &H)
 Build one phase's hub copies (§4.4 steps 2, 3 and 5): every vertex with d > kHubEdgeBudget active edges gets s = ceil(d / 32) copies – its own slot plus s - 1 slots appended at [slotBase, slotBase + nCopies).
 
void peclet::dem::buildCopyGroupsKokkos (Kokkos::View< const int *, CpMem > realIdx, int span, int numReal, Kokkos::View< const int *, CpMem > deg, Kokkos::View< const float *[3], CpMem > imageShift, PhaseCopies &H, bool identityBodies=false)
 Build the fold groups of a phase (§4.4 "local fold", §WO-4 item 2): every body with more than one slot among [0, span) (the phase's vertex slots) and the hub copies.
 
void peclet::dem::buildSolveViewsKokkos (Particles &P, const PhaseCopies &H, int nSlots, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia)
 Solve views of a phase (§4.5): invMassSolve / invInertiaSolve = the phase's masses on every slot in [0, nSlots), times k on every member of a group, and splitSlot = (k > 1).
 
void peclet::dem::seedCopySlotStateKokkos (Particles &P, const PhaseCopies &H)
 Seed the copy slots' read-only state from their hub vertex (§4.4 step 6): orientation, local inverse inertia and grounded level (velocity), predicted orientation (position).
 
void peclet::dem::markCopySeedsKokkos (const PhaseCopies &H, Kokkos::View< float *[3], CpMem > x, Kokkos::View< float *[3], CpMem > w, Kokkos::View< float *, CpMem > orphan, Kokkos::View< float *, CpMem > orphanPeak, bool shareFromBase=false)
 Mark the phase seed sigma of every group and re-seed its members from the base (§4.4 step 6, and after every rank sync): x(q) = sigma + shift(q); w likewise (velocity, no shift).
 
void peclet::dem::foldCopiesKokkos (CpExec space, const PhaseCopies &H, Kokkos::View< float *[3], CpMem > x, Kokkos::View< float *[3], CpMem > w, Kokkos::View< float *, CpMem > orphan, Kokkos::View< float *, CpMem > orphanPeak, Kokkos::View< float, CpMem > consensus={})
 The local fold (§4.4), once per iteration after the sweep: per group T = sum over the ACTIVE members of (x(q) - sigma - shift(q)) (the M-consensus of §1.3: an inactive member carries no increment of its own, only the re-seeded consensus); the base takes sigma + T / k and every member is re-seeded to it (plus its shift).
 
void peclet::dem::reseedCopiesKokkos (CpExec space, const PhaseCopies &H, Kokkos::View< float *[3], CpMem > x, Kokkos::View< float *[3], CpMem > w)
 Re-seed every member from its base, sigma unchanged (the multilevel pass, after the coarse cycle has moved the bases; §4.4 "copies re-seeded again after the coarse cycle").
 
void peclet::dem::unfoldOrphanKokkos (const PhaseCopies &H, Kokkos::View< float *, CpMem > orphan)
 Orphan accounts back from share form (before a rank sync and at the end of the velocity phase): the base holds the body's balance, the sum of its members' shares.
 
void peclet::dem::activityHitVelocityKokkos (Kokkos::View< const ManifoldC *, CpMem > manifolds, int nm, Kokkos::View< const int *, CpMem > realIdx, Kokkos::View< const int *, CpMem > color, SlotOverride ov, Kokkos::View< unsigned char *, CpMem > hit, int nSlots)
 Rank-level activity pass (docs/contact_solve_framework.md §13.3 C4; the distributed step only), velocity phase: hit(slot) = 1 for every slot that is an end – through the hub-copy overrides, else realIdx – of an owned manifold of colour >= 0 in the final colouring.
 
void peclet::dem::activityHitPositionKokkos (Kokkos::View< const ContactC *, CpMem > contacts, const PosUnits &units, int nu, Kokkos::View< const int *, CpMem > color, SlotOverride ov, Kokkos::View< unsigned char *, CpMem > hit, int nSlots)
 The same over the position phase's units (raw slots of the leader contact, through the overrides).
 
void peclet::dem::finishActivityKokkos (Kokkos::View< const unsigned char *, CpMem > hit, int nSlots, PhaseCopies &H, Kokkos::View< int *, CpMem > a)
 a(q) from the pass (§13.3): hit(q) for a slot outside any group; at a hub base the number of its group's members (base + copies) that were hit, which also refills groupActive and groupK (floored at 1, WO-4's local fold divisor).
 
void peclet::dem::buildSolveViewsRankKKokkos (Particles &P, const PhaseCopies &H, int nSlots, Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const int *, CpMem > kRank)
 Solve views under rank-level M (§13.3, §4.5): invMassSolve / invInertiaSolve = k x the body's masses on every slot in [0, nSlots) (nSlots = slotBase + the phase's copies), with k the slot's global active copy count kRank (owner-computed, forwarded); a hub copy takes its base's k.
 
void peclet::dem::buildInvMassCoarseKokkos (Kokkos::View< const float *, CpMem > invMass, Kokkos::View< const int *, CpMem > k, Kokkos::View< const int *, CpMem > a, int n, Kokkos::View< float *, CpMem > out)
 The multilevel coarse vertex's inverse mass (§13.2): invMass(q) (k(q) / max(1, a(q))), the ratio computed first so that k = a gives invMass bit for bit.
 
void peclet::dem::buildInvInertiaCoarseKokkos (Kokkos::View< const float *[3], CpMem > invInertia, Kokkos::View< const int *, CpMem > k, Kokkos::View< const int *, CpMem > a, int n, Kokkos::View< float *[3], CpMem > out)
 The multilevel coarse vertex's inverse inertia (docs/contact_physics_followups.md §2.5): the same fraction a / k of the body's inertia as its mass, invInertia(q) (k(q) / max(1, a(q))) per component, the ratio computed first exactly as buildInvMassCoarseKokkos (k = a gives invInertia bit for bit).
 
int peclet::dem::countInactiveAggregatedKokkos (Kokkos::View< const int *, CpMem > parent, int off, int nV, int nGroups1, Kokkos::View< const int *, CpMem > a)
 Debug-build check (§13.2, §13.5 WO-5 item 4): the vertices with a = 0 that sit in a level-1 multilevel group of >= 2 members (must be none: an inactive copy never joins a coarse edge).
 
int peclet::dem::countSplitBodiesKokkos (const PhaseCopies &H)
 Count the bodies whose group has k > 1 (split_stats).
 
int peclet::dem::countSplitAggregatedKokkos (Kokkos::View< const int *, CpMem > parent, int off, int nV, int nGroups1, Kokkos::View< const unsigned char *, CpMem > split)
 split_stats.mlHubAggregated (§13.2's positive control): the vertices v in [0, nV) with split(v) != 0 (k > 1) whose level-1 multilevel group – parent(off + v), the first level's parent map – has at least two members.
 
int peclet::dem::countLightHubsKokkos (const PhaseCopies &H, Kokkos::View< const int *, CpMem > eA, Kokkos::View< const int *, CpMem > eB, int nE, int nV, Kokkos::View< const float *, CpMem > invMass)
 Light hubs (split_stats, R-P3): velocity hubs whose mass is below 10x the mean mass of their partners over the hub's active edges.
 

Variables

constexpr int peclet::dem::kHubEdgeBudget = 32
 Hub edge budget (§4.4): a colouring vertex with more active edges is split into ceil(d / kHubEdgeBudget) copies, so no copy carries more than 32 and the 64-colour greedy provably succeeds (§1.6).
 
constexpr float peclet::dem::kSplitOmegaVelocity = 1.0f
 Split relaxation (§4.5, §13.1): the PGS normal step on an edge touching a mass-split slot is scaled by kSplitOmegaVelocity before the clamp (1: no relaxation; the pre-designed lever of R-F2, legitimate there because the PGS normal multiplier is accumulated and its clamp can retract an overshoot).
 

Detailed Description

dem — body copies of the contact solve (docs/contact_solve_framework.md §4.4, §4.5, §WO-4 item 2): hub copies of a colouring vertex above kHubEdgeBudget edges, the fold groups of a phase (hubs; demStep's periodic images in the position phase), the mass-split solve views, and the seed / fold / re-seed kernels demSolveContacts runs around its sweeps.

Free functions over the Particles SoA; no ArborX, no MPI.

Definition in file solve_copies.hpp.