7 #include "imstkPbdConstantDensityConstraint.h" 8 #include "imstkParallelUtils.h" 12 PbdConstantDensityConstraint::PbdConstantDensityConstraint() : PbdConstraint()
14 m_particleRadiusSqr = m_particleRadius * m_particleRadius;
15 m_wPoly6Coeff = 315.0 / (64.0 * PI * pow(m_particleRadius, 9));
16 m_wSpikyCoeff = 15.0 / (PI * pow(m_particleRadius, 6)) * -3.0;
22 const double particleRadius,
const double density)
24 m_lambdas.resize(numParticles);
25 m_densities.resize(numParticles);
26 m_deltaPositions.resize(numParticles);
27 m_neighborList.resize(numParticles);
28 m_bodyHandle = bodyHandle;
30 m_restDensity = density;
31 m_particleRadius = particleRadius;
32 m_particleRadiusSqr = m_particleRadius * m_particleRadius;
33 m_wPoly6Coeff = 315.0 / (64.0 * PI * pow(m_particleRadius, 9));
34 m_wSpikyCoeff = 15.0 / (PI * pow(m_particleRadius, 6)) * -3.0;
37 m_NeighborSearcher = std::make_shared<NeighborSearch>(m_NeighborSearchMethod, m_particleRadius);
42 const double imstkNotUsed(dt),
const SolverType& imstkNotUsed(type))
44 const size_t numVertices = state.m_bodies[m_bodyHandle]->vertices->size();
48 m_NeighborSearcher->getNeighbors(m_neighborList, vertices);
50 ParallelUtils::parallelFor(numVertices,
51 [&](
const size_t idx) {
52 computeDensity(vertices[idx], idx, vertices);
55 ParallelUtils::parallelFor(numVertices,
56 [&](
const size_t idx) {
57 computeLambdaScalingFactor(vertices[idx], idx, vertices);
60 ParallelUtils::parallelFor(numVertices,
61 [&](
const size_t idx) {
62 updatePositions(vertices[idx], idx, vertices);
67 PbdConstantDensityConstraint::computeDensity(
const Vec3d& pi,
71 double densitySum = 0.0;
72 for (
auto q : m_neighborList[index])
74 densitySum += wPoly6(pi, positions[q]);
77 m_densities[index] = densitySum;
81 PbdConstantDensityConstraint::computeLambdaScalingFactor(
const Vec3d& pi,
85 const double invRestDensity = 1.0 / m_restDensity;
86 const double densityConstraint = (m_densities[index] * invRestDensity) - 1.0;
87 double gradientSum = 0.0;
89 for (
auto q : m_neighborList[index])
91 gradientSum += gradSpiky(pi, positions[q]).squaredNorm() * invRestDensity;
94 m_lambdas[index] = densityConstraint / (gradientSum + m_relaxationParameter);
98 PbdConstantDensityConstraint::updatePositions(
const Vec3d& pi,
103 Vec3d gradientLambdaSum(0.0, 0.0, 0.0);
104 for (
auto q : m_neighborList[index])
106 const double lambdasDiff = (m_lambdas[index] + m_lambdas[q]);
107 const Vec3d gradKernal = gradSpiky(pi, positions[q]);
108 gradientLambdaSum += (gradKernal * lambdasDiff);
111 m_deltaPositions[index] = gradientLambdaSum / m_restDensity;
112 positions[index] += m_deltaPositions[index];
void projectConstraint(PbdState &bodies, const double dt, const SolverType &type) override
Solves the constant density constraint.
void initConstraint(const int numParticles, const int bodyHandle, const double particleRadius, const double density)
Constant Density Constraint Initialization.
SolverType
Type of solvers.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.