46 Kokkos::View<const float*, CpMem> invMass,
47 Kokkos::View<
const float* [3],
CpMem> invInertia,
48 Kokkos::View<
const float* [3],
CpMem> velPred,
49 Kokkos::View<
const float* [3],
CpMem> angVelPred,
50 Kokkos::View<const int*, CpMem> realIdx,
float growthRate,
51 bool dedupTwins =
true) {
55 "peclet::dem::fric_accum", Kokkos::RangePolicy<CpExec>(space, 0, numContacts),
56 KOKKOS_LAMBDA(
int idx) {
62 const int idA = c.
bodyA;
63 const float invMA = invMass(idA);
66 const F3 invIA =
ldF3(invInertia, idA);
70 const float approach = -
dot3(
sub3(vAc, vWall), n);
73 const float w_n = computeW(rA, n, invMA, invIA);
75 contacts(idx).friction_lambda_n += approach / w_n;
78 const int realA = realIdx(c.
bodyA), realB = realIdx(c.
bodyB);
79 if (dedupTwins && realA > realB)
81 const float invMA = invMass(realA), invMB = invMass(realB);
82 const F3 invIA =
ldF3(invInertia, realA), invIB =
ldF3(invInertia, realB);
89 const float approach = -
dot3(vrel, n);
92 const float w_n = computeW(rA, n, invMA, invIA) + computeW(rB, n, invMB, invIB);
94 contacts(idx).friction_lambda_n += approach / w_n;
102 Kokkos::View<const float*, CpMem> invMass,
103 Kokkos::View<
const float* [3],
CpMem> invInertia,
104 Kokkos::View<
const float* [3],
CpMem> velPred,
105 Kokkos::View<
const float* [3],
CpMem> angVelPred,
109 Kokkos::deep_copy(space, planeFriction, 0.0f);
110 Kokkos::parallel_for(
111 "peclet::dem::fric_plane_load", Kokkos::RangePolicy<CpExec>(space, 0, numContacts),
112 KOKKOS_LAMBDA(
int idx) {
116 const int idA = c.
bodyA;
117 const float invMA = invMass(idA);
120 const F3 invIA =
ldF3(invInertia, idA);
126 const float approach = -
dot3(
sub3(vAc, vWall), n);
127 if (approach <= 0.0f)
129 const float w_n = computeW(rA, n, invMA, invIA);
130 contacts(idx).friction_lambda_n = (w_n > 1e-6f) ? approach / w_n : 0.0f;
131 Kokkos::atomic_max(&planeFriction(idA, 0), approach / invMA);
166 Kokkos::View<const ContactC*, CpMem> contacts,
int numContacts,
167 Kokkos::View<const float*, CpMem> invMass, Kokkos::View<
const float* [3],
CpMem> invInertia,
168 Kokkos::View<
const float* [4],
CpMem> quat, Kokkos::View<
const float* [3],
CpMem> velPred,
169 Kokkos::View<
const float* [3],
CpMem> angVelPred, Kokkos::View<const int*, CpMem> realIdx,
171 Kokkos::View<
float* [3],
CpMem> deltaAngVel) {
173 Kokkos::deep_copy(space, deltaVel, 0.0f);
174 Kokkos::deep_copy(space, deltaAngVel, 0.0f);
175 Kokkos::parallel_for(
176 "peclet::dem::fric_solve", Kokkos::RangePolicy<CpExec>(space, 0, numContacts),
177 KOKKOS_LAMBDA(
int idx) {
180 if (lambda_n <= 0.0f)
183 const int realA = realIdx(idA);
184 const int realB = (idB >= 0) ? realIdx(idB) : -1;
185 const float invMA = invMass(realA);
186 const float invMB = (idB >= 0) ? invMass(realB) : 0.0f;
187 const F3 invIA =
ldF3(invInertia, realA);
188 const F3 invIB = (idB >= 0) ?
ldF3(invInertia, realB) :
F3{0, 0, 0};
201 const F3 vrel =
sub3(vAc, vBc);
202 const float vn =
dot3(vrel, n);
204 const float vt_len = Kokkos::sqrt(
dot3(vt, vt));
207 const F3 t =
scale3(vt, 1.0f / vt_len);
211 const bool isoA = invIA.
x == invIA.
y && invIA.
y == invIA.
z;
212 const bool isoB = invIB.
x == invIB.
y && invIB.
y == invIB.
z;
213 F4 qA{0, 0, 0, 1}, qB{0, 0, 0, 1};
215 qA =
F4{quat(realA, 0), quat(realA, 1), quat(realA, 2), quat(realA, 3)};
217 qB =
F4{quat(realB, 0), quat(realB, 1), quat(realB, 2), quat(realB, 3)};
218 const float w_t = (isoA && isoB)
219 ? invMA + invMB + rnA.
x * rnA.
x * invIA.
x + rnA.
y * rnA.
y * invIA.
y +
220 rnA.
z * rnA.
z * invIA.
z + rnB.x * rnB.x * invIB.
x +
221 rnB.y * rnB.y * invIB.
y + rnB.z * rnB.z * invIB.
z
230 const float bound = lambda_n;
231 const float nA = planeFriction(realA, 1);
232 const float nB = (idB >= 0) ? planeFriction(realB, 1) : 0.0f;
233 const float inv_n = 1.0f / Kokkos::fmax(Kokkos::fmax(nA, nB), 1.0f);
234 float lt = -vt_len / w_t;
238 const float maxf = mu * bound;
243 Kokkos::atomic_add(&deltaVel(realA, 0), t.
x * lt * invMA);
244 Kokkos::atomic_add(&deltaVel(realA, 1), t.
y * lt * invMA);
245 Kokkos::atomic_add(&deltaVel(realA, 2), t.
z * lt * invMA);
247 Kokkos::atomic_add(&deltaAngVel(realA, 0), rnA.
x * invIA.
x * lt);
248 Kokkos::atomic_add(&deltaAngVel(realA, 1), rnA.
y * invIA.
y * lt);
249 Kokkos::atomic_add(&deltaAngVel(realA, 2), rnA.
z * invIA.
z * lt);
253 Kokkos::atomic_add(&deltaAngVel(realA, 0), dww.
x);
254 Kokkos::atomic_add(&deltaAngVel(realA, 1), dww.
y);
255 Kokkos::atomic_add(&deltaAngVel(realA, 2), dww.
z);
258 Kokkos::atomic_add(&deltaVel(realB, 0), -t.
x * lt * invMB);
259 Kokkos::atomic_add(&deltaVel(realB, 1), -t.
y * lt * invMB);
260 Kokkos::atomic_add(&deltaVel(realB, 2), -t.
z * lt * invMB);
262 Kokkos::atomic_add(&deltaAngVel(realB, 0), -rnB.x * invIB.
x * lt);
263 Kokkos::atomic_add(&deltaAngVel(realB, 1), -rnB.y * invIB.
y * lt);
264 Kokkos::atomic_add(&deltaAngVel(realB, 2), -rnB.z * invIB.
z * lt);
268 Kokkos::atomic_add(&deltaAngVel(realB, 0), dww.
x);
269 Kokkos::atomic_add(&deltaAngVel(realB, 1), dww.
y);
270 Kokkos::atomic_add(&deltaAngVel(realB, 2), dww.
z);
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 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 *[4], CpMem > quat, 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 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, bool dedupTwins=true)
Force-chain normal load, accumulated over the velocity iterations: contacts(idx).friction_lambda_n +=...