7 #include "imstkSphCollisionHandling.h" 8 #include "imstkCollisionData.h" 9 #include "imstkCollisionDetectionAlgorithm.h" 10 #include "imstkParallelFor.h" 11 #include "imstkSphModel.h" 12 #include "imstkSphObject.h" 17 SphCollisionHandling::setInputSphObject(std::shared_ptr<SphObject> sphObj)
24 const std::vector<CollisionElement>& elementsA,
25 const std::vector<CollisionElement>& imstkNotUsed(elementsB))
28 std::shared_ptr<SphModel> sphModel = obj->
getSphModel();
29 #if defined(DEBUG) || defined(_DEBUG) || !defined(NDEBUG) 30 LOG_IF(FATAL, (!sphModel)) <<
"SPH model was not initialized";
33 m_boundaryFriction = sphModel->getParameters()->m_frictionBoundary;
34 #if defined(DEBUG) || defined(_DEBUG) || !defined(NDEBUG) 35 LOG_IF(FATAL, (m_boundaryFriction<0.0 || m_boundaryFriction>1.0))
36 <<
"Invalid boundary friction coefficient (value must be in [0, 1])";
39 std::shared_ptr<SphState> state = sphModel->getCurrentState();
40 std::shared_ptr<VecDataArray<double, 3>> positionsPtr = state->getPositions();
41 std::shared_ptr<VecDataArray<double, 3>> velocitiesPtr = state->getVelocities();
46 for (
int i = 0; i < m_iterations; i++)
49 if (i != 0 && m_colDetect !=
nullptr)
52 obj->updateGeometries();
54 m_colDetect->update();
57 ParallelUtils::parallelFor(elementsA.size(), [&](
const size_t j)
60 if (colElem.m_type == CollisionElementType::PointIndexDirection)
62 const int particleIndex = colElem.m_element.m_PointIndexDirectionElement.ptIndex;
63 const Vec3d& n = -colElem.m_element.m_PointIndexDirectionElement.dir;
64 const double depth = colElem.m_element.m_PointIndexDirectionElement.penetrationDepth;
65 solve(positions[particleIndex], velocities[particleIndex], n * depth);
75 pos -= penetrationVector;
77 const auto nLengthSqr = penetrationVector.squaredNorm();
78 if (nLengthSqr < 1.0e-20)
82 const Vec3d n = penetrationVector / std::sqrt(nLengthSqr);
85 const Vec3d oldVel = velocity;
86 const double vn = oldVel.dot(n);
91 Vec3d correctedVel = oldVel - vn * n;
93 if (m_boundaryFriction > 1.0e-20)
95 const double velLength = correctedVel.norm();
96 const double frictionLength = vn * m_boundaryFriction;
97 if (frictionLength < velLength && velLength > 1.0e-10)
99 correctedVel -= (correctedVel / velLength) * frictionLength;
103 correctedVel = Vec3d::Zero();
107 velocity = correctedVel;
void setInputObjectA(std::shared_ptr< CollidingObject > objectA)
Set the input objects.
void solve(Vec3d &pos, Vec3d &velocity, const Vec3d &penetrationVector)
Solves positiona and corrects velocity of individual particle.
Base class for scene objects that move and/or deform under smooth particle hydrodynamics.
Union of collision elements. We use a union to avoid polymorphism. There may be many elements and acc...
std::shared_ptr< CollidingObject > getInputObjectA() const
Get the input objects.
std::shared_ptr< SphModel > getSphModel()
Get the model governing the Sph fluid dynamics of this object.
void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Resolve SPH particle positions.