iMSTK
Interactive Medical Simulation Toolkit
imstkPbdConstantDensityConstraint.h
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 #pragma once
8 
9 #include "imstkNeighborSearch.h"
10 #include "imstkPbdConstraint.h"
11 #include "imstkTypes.h"
12 
13 namespace imstk
14 {
22 {
23 public:
25 
26  IMSTK_TYPE_NAME(PbdConstantDensityConstraint)
27 
28 
29  void initConstraint(const int numParticles,
35  const int bodyHandle,
36  const double particleRadius,
37  const double density);
38 
42  void projectConstraint(PbdState& bodies, const double dt,
43  const SolverType& type) override;
44 
45  bool computeValueAndGradient(
46  PbdState& imstkNotUsed(bodies),
47  double& imstkNotUsed(c),
48  std::vector<Vec3d>& imstkNotUsed(dcdx)) override
49  {
50  return true;
51  }
52 
56  void setDensity(const double density) { m_restDensity = density; }
57  double getDensity() const { return m_restDensity; }
59 
60 private:
64  inline double wPoly6(const Vec3d& pi, const Vec3d& pj) const
65  {
66  const double rLengthSqr = (Vec3d(pi - pj)).squaredNorm();
67  if (rLengthSqr > m_particleRadiusSqr || rLengthSqr == 0.0)
68  {
69  return 0.0;
70  }
71  else
72  {
73  const double maxDiff = m_particleRadiusSqr - rLengthSqr;
74  return m_wPoly6Coeff * maxDiff * maxDiff * maxDiff;
75  }
76  }
77 
81  inline Vec3d gradSpiky(const Vec3d& pi, const Vec3d& pj) const
82  {
83  const Vec3d r = pi - pj;
84  const double rLengthSqr = r.squaredNorm();
85 
86  if (rLengthSqr > m_particleRadiusSqr || rLengthSqr < 1e-20)
87  {
88  return Vec3d::Zero();
89  }
90 
91  const double rLength = std::sqrt(rLengthSqr);
92  return r * (m_wSpikyCoeff * (m_particleRadius - rLength) * (m_particleRadius - rLength));
93  }
94 
98  void computeDensity(const Vec3d& pi, const size_t index, const VecDataArray<double, 3>& positions);
99 
103  void computeLambdaScalingFactor(const Vec3d& pi, const size_t index, const VecDataArray<double, 3>& positions);
104 
108  void updatePositions(const Vec3d& pi, const size_t index, VecDataArray<double, 3>& positions);
109 
113  void setNeighborSearchMethod(NeighborSearch::Method method) { m_NeighborSearchMethod = method; }
114  NeighborSearch::Method getNeighborSearchMethod() const { return m_NeighborSearchMethod; }
115 
119  double getRestValue() const { return m_restDensity; }
120 
121 private:
122  int m_bodyHandle = -1;
123  double m_wPoly6Coeff = 0.0;
124  double m_wSpikyCoeff = 0.0;
125 
126  double m_particleRadius = 0.2;
127  double m_particleRadiusSqr = 0.04;
128  double m_relaxationParameter = 600.0;
129  double m_restDensity = 6378.0;
130 
131  std::vector<double> m_lambdas;
132  std::vector<double> m_densities;
133  std::vector<Vec3d> m_deltaPositions;
134  std::vector<std::vector<size_t>> m_neighborList;
135 
136  NeighborSearch::Method m_NeighborSearchMethod = NeighborSearch::Method::UniformGridBasedSearch;
137  std::shared_ptr<NeighborSearch> m_NeighborSearcher;
138 };
139 } // namespace imstk
Compound Geometry.
void projectConstraint(PbdState &bodies, const double dt, const SolverType &type) override
Solves the constant density constraint.
Base Constraint class for Position based dynamics constraints.
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
void setDensity(const double density)
Set/Get rest density.
Implements the constant density constraint to simulate fluids. This constraint is global and applied ...