1#ifndef PBAT_SIM_VBD_KERNELS_H
2#define PBAT_SIM_VBD_KERNELS_H
5#include "pbat/HostDevice.h"
22namespace mini = math::linalg::mini;
25 mini::CMatrix TMatrixXT,
26 mini::CMatrix TMatrixVT,
27 mini::CMatrix TMatrixA,
28 class ScalarType =
typename TMatrixXT::ScalarType>
29PBAT_HOST_DEVICE mini::SVector<ScalarType, TMatrixXT::kRows> InertialTarget(
36 return xt + dt * vt + dt2 * aext;
40 mini::CMatrix TMatrixXT,
41 mini::CMatrix TMatrixVTM1,
42 mini::CMatrix TMatrixVT,
43 mini::CMatrix TMatrixA,
44 class ScalarType =
typename TMatrixXT::ScalarType>
45PBAT_HOST_DEVICE mini::SVector<ScalarType, TMatrixXT::kRows> InitialPositionsForSolve(
47 TMatrixVTM1
const& vtm1,
55 if (strategy == EInitializationStrategy::Position)
59 else if (strategy == EInitializationStrategy::Inertia)
63 else if (strategy == EInitializationStrategy::KineticEnergyMinimum)
65 return xt + dt * vt + dt2 * aext;
69 ScalarType
const aextn2 = SquaredNorm(aext);
70 bool const bHasZeroExternalAcceleration = (aextn2 == ScalarType(0));
72 if (not bHasZeroExternalAcceleration)
75 auto constexpr kRows = TMatrixXT::kRows;
76 if (strategy == EInitializationStrategy::AdaptiveVbd)
78 SVector<ScalarType, kRows>
const ati = (vt - vtm1) / dt;
79 atilde = Dot(ati, aext) / aextn2;
80 atilde = min(max(atilde, ScalarType(0)), ScalarType(1));
82 if (strategy == EInitializationStrategy::AdaptivePbat)
84 SVector<ScalarType, kRows>
const dti =
85 vt / (Norm(vt) + std::numeric_limits<ScalarType>::min());
86 atilde = Dot(dti, aext) / aextn2;
89 atilde = min(abs(atilde), ScalarType(1));
92 return xt + dt * vt + dt2 * atilde * aext;
96template <
class ScalarType,
class IndexType>
97PBAT_HOST [[maybe_unused]] ScalarType ChebyshevOmega(IndexType k, ScalarType rho2, ScalarType omega)
99 return (k == IndexType(0)) ? ScalarType{1} :
100 (k == IndexType(1)) ? ScalarType{2} / (ScalarType{2} - rho2) :
101 ScalarType{4} / ScalarType{4} - rho2 * omega;
105 mini::CMatrix TMatrixXKM2,
106 mini::CMatrix TMatrixXKM1,
107 mini::CMatrix TMatrixXK,
109 class ScalarType =
typename TMatrixXK::ScalarType>
110PBAT_HOST_DEVICE [[maybe_unused]]
void
111ChebyshevUpdate(IndexType k, ScalarType omega, TMatrixXKM2& xkm2, TMatrixXKM1& xkm1, TMatrixXK& xk)
115 xk = omega * (xk - xkm2) + xkm2;
122 mini::CMatrix TMatrixXT,
123 mini::CMatrix TMatrixX,
124 class ScalarType =
typename TMatrixXT::ScalarType>
125PBAT_HOST_DEVICE mini::SVector<ScalarType, TMatrixXT::kRows>
126IntegrateVelocity(TMatrixXT
const& xt, TMatrixX
const& x, ScalarType dt)
128 return (x - xt) / dt;
132 mini::CMatrix TMatrixGP,
133 mini::CMatrix TMatrixHF,
134 mini::CMatrix TMatrixHI,
136 class ScalarType =
typename TMatrixGP::ScalarType>
137PBAT_HOST_DEVICE
void AccumulateElasticHessian(
144 auto constexpr kDims = TMatrixGP::kCols;
148 Hi += wg * GP(ilocal, ki) * GP(ilocal, kj) *
149 HF.template Slice<kDims, kDims>(ki * kDims, kj * kDims);
155 mini::CMatrix TMatrixGP,
156 mini::CMatrix TMatrixGF,
157 mini::CMatrix TMatrixGI,
159 class ScalarType =
typename TMatrixGP::ScalarType>
160PBAT_HOST_DEVICE
void AccumulateElasticGradient(
167 auto constexpr kDims = TMatrixGP::kCols;
170 [&]<
auto k>() { gi += wg * GP(ilocal, k) * gF.template Slice<kDims, 1>(k * kDims, 0); });
174 mini::CMatrix TMatrixXT,
175 mini::CMatrix TMatrixX,
176 mini::CMatrix TMatrixG,
177 mini::CMatrix TMatrixH,
178 class ScalarType =
typename TMatrixXT::ScalarType>
179PBAT_HOST_DEVICE
void AddDamping(
188 ScalarType
const D = kD / dt;
189 g += D * (H * (x - xt));
190 H *= ScalarType{1} + D;
216 mini::CMatrix TMatrixXTV,
217 mini::CMatrix TMatrixXV,
218 mini::CMatrix TMatrixXTF,
219 mini::CMatrix TMatrixXF,
220 mini::CMatrix TMatrixG,
221 mini::CMatrix TMatrixH,
222 class ScalarType =
typename TMatrixXV::ScalarType>
223PBAT_HOST_DEVICE ScalarType AccumulateVertexTriangleContact(
224 TMatrixXTV
const& xtv,
226 TMatrixXTF
const& xtf,
232 TMatrixG* g =
nullptr,
233 TMatrixH* H =
nullptr)
235 using namespace mini;
239 SMatrix<ScalarType, 3, 2> T{};
240 T.Col(0) = xf.Col(1) - xf.Col(0);
241 T.Col(1) = xf.Col(2) - xf.Col(0);
242 SVector<ScalarType, 3> n = Cross(T.Col(0), T.Col(1));
243 ScalarType
const doublearea = Norm(n);
244 bool const bIsTriangleDegenerate = doublearea <= ScalarType(1e-8);
245 if (bIsTriangleDegenerate)
249 using namespace pbat::geometry;
250 SVector<ScalarType, 3> xc = ClosestPointQueries::PointOnPlane(xv, xf.Col(0), n);
252 SVector<ScalarType, 3> b =
253 IntersectionQueries::TriangleBarycentricCoordinates(xc - xf.Col(0), T.Col(0), T.Col(1));
256 bool const bIsVertexInsideTriangle = All(b >= ScalarType(0) and b <= ScalarType(1));
258 if (not bIsVertexInsideTriangle)
262 SVector<ScalarType, 3> xb = xf * b;
263 ScalarType d = min(ScalarType(0), Dot(xv - xb, n));
264 ScalarType lambda = muC * d;
265 E += ScalarType(0.5) * lambda * d;
271 (*H) += muC * (n * n.Transpose());
274 T.Col(1) = Cross(n, T.Col(0));
276 auto dx = (xv - xtv) - (xb - xtb);
277 SVector<ScalarType, 2> u = T.Transpose() * dx;
278 ScalarType unorm = Norm(u) + std::numeric_limits<ScalarType>::epsilon();
279 ScalarType epsvh = epsv * dt;
280 ScalarType muFlambda = muF * abs(lambda);
281 ScalarType uepsvh = unorm / epsvh;
282 ScalarType f1 = (uepsvh < 1) ? 2 * uepsvh - (uepsvh * uepsvh) : ScalarType(1);
284 ScalarType muFlambdaf1unorm = muFlambda * f1 / unorm;
286 (*g) += muFlambdaf1unorm * T * u;
288 (*H) += muFlambdaf1unorm * T * T.Transpose();
293 ScalarType unorm2 = unorm * unorm;
296 (ScalarType(1) / ScalarType(3) * epsvh) +
298 (unorm2 * unorm / (ScalarType(3) * epsvh * epsvh));
305 mini::CMatrix TMatrixXTL,
306 mini::CMatrix TMatrixX,
307 mini::CMatrix TMatrixG,
308 mini::CMatrix TMatrixH,
309 class ScalarType =
typename TMatrixXTL::ScalarType>
310PBAT_HOST_DEVICE
void AddInertiaDerivatives(
313 TMatrixXTL
const& xtilde,
319 ScalarType
const K = m / dt2;
321 g += K * (x - xtilde);
325 mini::CMatrix TMatrixX,
326 mini::CMatrix TMatrixG,
327 mini::CMatrix TMatrixH,
328 class ScalarType =
typename TMatrixX::ScalarType>
329PBAT_HOST_DEVICE
void IntegratePositions(
333 ScalarType detHZero = ScalarType(1e-7))
336 if (abs(Determinant(H)) <= detHZero)
338 x -= (Inverse(H) * g);
This file contains functions to answer closest point queries.
This file contains functions to answer intersection queries.
This file includes all the mini linear algebra headers.
Tetrahedron finite element.
constexpr void ForRange(F &&f)
Compile-time for loop over a range of values.
Definition ConstexprFor.h:55
Mini linear algebra related functionality.
Definition Assign.h:12
PBAT's Vertex Block Descent (VBD) anka2024vbd API.
Definition AndersonIntegrator.cpp:10
EInitializationStrategy
Initialization strategies for the VBD time step minimization.
Definition Enums.h:9
PBAT simulation algorithms.
The main namespace of the library.
Definition Aliases.h:15