7 #include "imstkPbdModel.h" 8 #include "imstkGraph.h" 9 #include "imstkLineMesh.h" 10 #include "imstkLogger.h" 11 #include "imstkParallelUtils.h" 12 #include "imstkPbdConstraintFunctor.h" 13 #include "imstkPbdModelConfig.h" 14 #include "imstkPbdSolver.h" 15 #include "imstkTaskGraph.h" 21 template<
class FunctorType>
23 eraseOldFunctor(std::vector<std::shared_ptr<imstk::PbdConstraintFunctor>>& funcs,
int bodyId)
26 funcs.erase(std::remove_if(funcs.begin(), funcs.end(), [bodyId](
auto item) {
27 if (FunctorType* functor = dynamic_cast<FunctorType*>(item.get()))
29 return functor->m_bodyIndex == bodyId;
41 if (std::abs(m_femParams->m_mu) < std::numeric_limits<double>::min()
42 && std::abs(m_femParams->m_lambda) < std::numeric_limits<double>::min())
44 const double E = m_femParams->m_YoungModulus;
45 const double nu = m_femParams->m_PoissonRatio;
46 m_femParams->m_mu = E / 2.0 / (1.0 + nu);
47 m_femParams->m_lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
51 const double mu = m_femParams->m_mu;
52 const double lambda = m_femParams->m_lambda;
53 m_femParams->m_YoungModulus = mu * (3.0 * lambda + 2.0 * mu) / (lambda + mu);
54 m_femParams->m_PoissonRatio = lambda / 2.0 / (lambda + mu);
61 auto& funcs = m_functors[type];
63 eraseOldFunctor<PbdBodyConstraintFunctor>(funcs, bodyId);
65 if (type == ConstraintGenType::Distance)
67 auto functor = std::make_shared<PbdDistanceConstraintFunctor>();
68 funcs.push_back(functor);
69 functor->setStiffness(stiffness);
70 functor->setBodyIndex(bodyId);
72 else if (type == ConstraintGenType::Volume)
74 auto functor = std::make_shared<PbdVolumeConstraintFunctor>();
75 funcs.push_back(functor);
76 functor->setStiffness(stiffness);
77 functor->setBodyIndex(bodyId);
79 else if (type == ConstraintGenType::Area)
81 auto functor = std::make_shared<PbdAreaConstraintFunctor>();
82 funcs.push_back(functor);
83 functor->setStiffness(stiffness);
84 functor->setBodyIndex(bodyId);
86 else if (type == ConstraintGenType::Bend)
88 auto functor = std::make_shared<PbdBendConstraintFunctor>();
89 funcs.push_back(functor);
90 functor->setStiffness(stiffness);
91 functor->setStride(1);
92 functor->setBodyIndex(bodyId);
94 else if (type == ConstraintGenType::Dihedral)
96 auto functor = std::make_shared<PbdDihedralConstraintFunctor>();
97 funcs.push_back(functor);
98 functor->setStiffness(stiffness);
99 functor->setBodyIndex(bodyId);
101 else if (type == ConstraintGenType::ConstantDensity)
103 auto functor = std::make_shared<PbdConstantDensityConstraintFunctor>();
104 funcs.push_back(functor);
105 functor->setStiffness(stiffness);
106 functor->setBodyIndex(bodyId);
110 LOG(FATAL) <<
"There exists no standard constraint functor for the ConstraintGenType";
117 auto& funcs = m_functors[ConstraintGenType::Distance];
119 eraseOldFunctor<PbdBodyConstraintFunctor>(funcs, bodyId);
121 auto functor = std::make_shared<PbdDistanceConstraintFunctor>();
122 funcs.push_back(functor);
123 functor->setStiffness(stiffness);
124 functor->setStretch(stretch);
125 functor->setBodyIndex(bodyId);
132 auto& funcs = m_functors[ConstraintGenType::Bend];
135 funcs.erase(std::remove_if(funcs.begin(), funcs.end(), [bodyId, stride](
auto item) {
136 if (FunctorType* functor = dynamic_cast<FunctorType*>(item.get()))
138 return functor->m_bodyIndex == bodyId && functor->getStride() == stride;
143 auto functor = std::make_shared<FunctorType>();
145 functor->setRestLength(restLength0 ? 0.0 : -1.0);
146 functor->setBodyIndex(bodyId);
147 functor->setStiffness(stiffness);
148 functor->setStride(stride);
149 funcs.push_back(functor);
154 const double particleRadius,
const double restDensity,
const int bodyId)
157 auto& funcs = m_functors[ConstraintGenType::ConstantDensity];
159 eraseOldFunctor<FunctorType>(funcs, bodyId);
161 auto functor = std::make_shared<FunctorType>();
163 functor->setParticleRadius(particleRadius);
164 functor->setBodyIndex(bodyId);
165 functor->setStiffness(stiffness);
166 functor->setRestDensity(restDensity);
168 funcs.push_back(std::move(functor));
175 auto& funcs = m_functors[ConstraintGenType::FemTet];
177 eraseOldFunctor<FunctorType>(funcs, bodyId);
179 auto functor = std::make_shared<FunctorType>();
181 functor->setBodyIndex(bodyId);
182 functor->setFemConfig(m_femParams);
183 functor->setMaterialType(material);
185 funcs.push_back(std::move(functor));
192 auto& funcs = m_functors[ConstraintGenType::FemTet];
194 eraseOldFunctor<FunctorType>(funcs, bodyId);
196 auto functor = std::make_shared<FunctorType>();
198 auto params = std::make_shared<PbdFemConstraintConfig>();
199 params->setYoungAndPoisson(youngsModulus, poisson);
201 functor->setBodyIndex(bodyId);
202 functor->setFemConfig(params);
203 functor->setMaterialType(material);
205 funcs.push_back(std::move(functor));
210 const double linearDampCoeff,
const double angularDampCoeff)
223 const double bodyDampMult = (1.0 - iter->second);
224 return 1.0 - (dampMult * bodyDampMult);
233 PbdModelConfig::getAngularDamping(
const int bodyId)
239 const double bodyDampMult = (1.0 - iter->second);
240 return 1.0 - (dampMult * bodyDampMult);
double m_linearDampingCoeff
Damping coefficient applied to linear velocity [0, 1].
PbdBendConstraintFunctor generates constraints per cell of a LineMesh.
void enableFemConstraint(PbdFemConstraint::MaterialType material, const int bodyId=2)
Enable a Fem constraint with the material provided.
void computeElasticConstants()
If lame parameters (mu+lambda) are given in femParams, then youngs modulus and poissons ratio are com...
double m_angularDampingCoeff
Damping coefficient applied to angular velcoity [0, 1].
void enableBendConstraint(const double stiffness, const int stride, const bool restLength0=true, const int bodyId=2)
Enables a bend constraint with given stiffness, stride, and flag for 0 rest length You may enable mul...
double getLinearDamping(const int bodyId)
Returns global and per body damping multiplied together for a body 1.0 is fully damped/all velocity r...
void enableConstraint(ConstraintGenType type, const double stiffness, const int bodyId=2)
Enables a constraint of type defined by ConstraintGenType with given stiffness. If constraint of that...
void setBodyDamping(const int bodyId, const double linearDampCoeff, const double angularDampCoeff=0.01)
Set damping for a specific body 1.0 is fully damped/all velocity removed, 0.0 is no damping...
void enableConstantDensityConstraint(const double stiffness, const double particleRadius, const double restDensity=6378.0, const int bodyId=2)
Enables constant density constraint given the stiffness and particleSize.
PbdFemTetConstraintFunctor generates constraints per cell of a TetrahedralMesh.
ConstraintGenType
Gives the set of standard pbd constraint generation schemes/functors provided by iMSTK. Note, these do not correspond to constraint types as there may be multiple schemes for one constraint or even multiple constraints per scheme.
PbdConstantDensityConstraintFunctor generates a global constant density constraint for an entire Poin...
std::unordered_map< int, double > m_bodyAngularDampingCoeff
Per body angular damping, Body id -> angular damping for given body [0, 1].
std::unordered_map< int, double > m_bodyLinearDampingCoeff
Per body linear damping, Body id -> linear damping for given body [0, 1].
void enableDistanceConstraint(const double stiffness, const double stretch, const int bodyId)
Enables a Distance constraint on the body Will remove an existing distance constraint on the same bod...