iMSTK
Interactive Medical Simulation Toolkit
imstkPbdConstantDensityConstraint.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkPbdConstantDensityConstraint.h"
8 #include "imstkParallelUtils.h"
9 
10 namespace imstk
11 {
12 PbdConstantDensityConstraint::PbdConstantDensityConstraint() : PbdConstraint()
13 {
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;
17 }
18 
19 void
21  const int bodyHandle,
22  const double particleRadius, const double density)
23 {
24  m_lambdas.resize(numParticles);
25  m_densities.resize(numParticles);
26  m_deltaPositions.resize(numParticles);
27  m_neighborList.resize(numParticles);
28  m_bodyHandle = bodyHandle;
29 
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;
35 
36  // Initialize neighbor searcher
37  m_NeighborSearcher = std::make_shared<NeighborSearch>(m_NeighborSearchMethod, m_particleRadius);
38 }
39 
40 void
42  const double imstkNotUsed(dt), const SolverType& imstkNotUsed(type))
43 {
44  const size_t numVertices = state.m_bodies[m_bodyHandle]->vertices->size();
45  VecDataArray<double, 3>& vertices = *state.m_bodies[m_bodyHandle]->vertices;
46 
47  // Search neighbor for each particle
48  m_NeighborSearcher->getNeighbors(m_neighborList, vertices);
49 
50  ParallelUtils::parallelFor(numVertices,
51  [&](const size_t idx) {
52  computeDensity(vertices[idx], idx, vertices);
53  });
54 
55  ParallelUtils::parallelFor(numVertices,
56  [&](const size_t idx) {
57  computeLambdaScalingFactor(vertices[idx], idx, vertices);
58  });
59 
60  ParallelUtils::parallelFor(numVertices,
61  [&](const size_t idx) {
62  updatePositions(vertices[idx], idx, vertices);
63  });
64 }
65 
66 void
67 PbdConstantDensityConstraint::computeDensity(const Vec3d& pi,
68  const size_t index,
69  const VecDataArray<double, 3>& positions)
70 {
71  double densitySum = 0.0;
72  for (auto q : m_neighborList[index])
73  {
74  densitySum += wPoly6(pi, positions[q]);
75  }
76 
77  m_densities[index] = densitySum;
78 }
79 
80 void
81 PbdConstantDensityConstraint::computeLambdaScalingFactor(const Vec3d& pi,
82  const size_t index,
83  const VecDataArray<double, 3>& positions)
84 {
85  const double invRestDensity = 1.0 / m_restDensity;
86  const double densityConstraint = (m_densities[index] * invRestDensity) - 1.0;
87  double gradientSum = 0.0;
88 
89  for (auto q : m_neighborList[index])
90  {
91  gradientSum += gradSpiky(pi, positions[q]).squaredNorm() * invRestDensity;
92  }
93 
94  m_lambdas[index] = densityConstraint / (gradientSum + m_relaxationParameter);
95 }
96 
97 void
98 PbdConstantDensityConstraint::updatePositions(const Vec3d& pi,
99  const size_t index,
100  VecDataArray<double, 3>& positions)
101 {
102  // Make sure the point is valid
103  Vec3d gradientLambdaSum(0.0, 0.0, 0.0);
104  for (auto q : m_neighborList[index])
105  {
106  const double lambdasDiff = (m_lambdas[index] + m_lambdas[q]);
107  const Vec3d gradKernal = gradSpiky(pi, positions[q]);
108  gradientLambdaSum += (gradKernal * lambdasDiff);
109  }
110 
111  m_deltaPositions[index] = gradientLambdaSum / m_restDensity;
112  positions[index] += m_deltaPositions[index];
113 }
114 } // namespace imstk
Compound Geometry.
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.
Definition: imstkPbdBody.h:229