7 #include "imstkPenaltyCH.h" 8 #include "imstkCollisionData.h" 9 #include "imstkFeDeformableObject.h" 10 #include "imstkFemDeformableBodyModel.h" 11 #include "imstkParallelUtils.h" 12 #include "imstkRbdConstraint.h" 13 #include "imstkRigidObject2.h" 18 PenaltyCH::setInputFeObject(std::shared_ptr<FeDeformableObject> feObj)
24 PenaltyCH::setInputRbdObject(std::shared_ptr<RigidObject2> rbdObj)
26 setInputObjectB(rbdObj);
29 std::shared_ptr<FeDeformableObject>
30 PenaltyCH::getInputFeObject()
32 return std::dynamic_pointer_cast<FeDeformableObject>(
getInputObjectA());
35 std::shared_ptr<RigidObject2>
36 PenaltyCH::getInputRbdObject()
38 return std::dynamic_pointer_cast<RigidObject2>(getInputObjectB());
43 const std::vector<CollisionElement>& elementsA,
44 const std::vector<CollisionElement>& elementsB)
47 auto rbdObj = std::dynamic_pointer_cast<
RigidObject2>(getInputObjectB());
49 if (deformableObj !=
nullptr)
53 if (rbdObj !=
nullptr)
59 LOG(FATAL) <<
"no penalty collision handling available for " <<
getInputObjectA()->getName()
60 <<
" (rigid mesh not yet supported).";
66 const std::vector<CollisionElement>& elements,
67 std::shared_ptr<RigidObject2> analyticObj)
75 Vec3d force = Vec3d::Zero();
76 for (
size_t i = 0; i < elements.size(); i++)
79 if (elem.m_type == CollisionElementType::PointDirection)
81 const Vec3d dir = elem.m_element.m_PointDirectionElement.dir;
82 const double penetrationDepth = elem.m_element.m_PointDirectionElement.penetrationDepth;
83 force += dir * ((penetrationDepth + 1.0) * (penetrationDepth + 1.0) - 1.0) * 10.0;
88 *analyticObj->getRigidBody()->m_force = force;
93 const std::vector<CollisionElement>& elements,
94 std::shared_ptr<FeDeformableObject> deformableObj)
102 std::shared_ptr<FemDeformableBodyModel> model = deformableObj->getFEMModel();
103 Vectord& force = model->getContactForce();
104 const Vectord& velVector = model->getCurrentState()->getQDot();
108 ParallelUtils::parallelFor(elements.size(),
112 if (elem.m_type == CollisionElementType::PointIndexDirection)
114 const Vec3d dir = elem.m_element.m_PointDirectionElement.dir;
115 const double penetrationDepth = elem.m_element.m_PointDirectionElement.penetrationDepth;
116 const int ptIndex = elem.m_element.m_PointIndexDirectionElement.ptIndex;
118 const Vec3d penetrationVector = dir * penetrationDepth;
119 const Eigen::Index nodeDofID =
static_cast<Eigen::Index
>(3 * ptIndex);
121 Vec3d velocityProjection = Vec3d(velVector(nodeDofID),
122 velVector(nodeDofID + 1),
123 velVector(nodeDofID + 2));
124 velocityProjection = velocityProjection.dot(dir) * penetrationVector;
129 force(nodeDofID) += nodalForce.x();
130 force(nodeDofID + 1) += nodalForce.y();
131 force(nodeDofID + 2) += nodalForce.z();
void unlock()
End a thread-safe region.
void setInputObjectA(std::shared_ptr< CollidingObject > objectA)
Set the input objects.
double m_stiffness
Stiffness of contact.
void computeContactForcesDiscreteDeformable(const std::vector< CollisionElement > &elements, std::shared_ptr< FeDeformableObject > deformableObj)
Given the collision data, applies nodal forces in the FEM model.
Union of collision elements. We use a union to avoid polymorphism. There may be many elements and acc...
void lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
void handle(const std::vector< CollisionElement > &elementsA, const std::vector< CollisionElement > &elementsB) override
Handle the input collision data. Elements will be flipped (if needed) such that elementsA corresponds...
void computeContactForcesAnalyticRigid(const std::vector< CollisionElement > &elements, std::shared_ptr< RigidObject2 > analyticObj)
Given the collision data, applies contact as external force to the rigid body (onyl supports PointDir...
Scene objects that can deform.
std::shared_ptr< CollidingObject > getInputObjectA() const
Get the input objects.
Scene objects that are governed by rigid body dynamics under the RigidBodyModel2. ...
double m_damping
Damping of the contact.