7 #include "imstkPbdFemTetConstraint.h" 13 const Vec3d& p0,
const Vec3d& p1,
const Vec3d& p2,
const Vec3d& p3,
32 const double det = m.determinant();
33 if (fabs(det) > 1.0e-16)
35 m_invRestMat = m.inverse();
44 double& c, std::vector<Vec3d>& dcdx)
46 const Vec3d& p0 = bodies.getPosition(
m_particles[0]);
47 const Vec3d& p1 = bodies.getPosition(
m_particles[1]);
48 const Vec3d& p2 = bodies.getPosition(
m_particles[2]);
49 const Vec3d& p3 = bodies.getPosition(
m_particles[3]);
57 Mat3d defgrad = m * m_invRestMat;
60 Mat3d U = Mat3d::Identity();
61 Mat3d Fhat = Mat3d::Identity();
62 Mat3d VT = Mat3d::Identity();
67 if (m_handleInversions && defgrad.determinant() <= 1E-8)
78 const double mu = m_config.
m_mu;
79 const double lambda = m_config.
m_lambda;
85 case MaterialType::StVK:
87 Mat3d I = Mat3d::Identity();
88 Mat3d E = 0.5 * (F.transpose() * F - I);
90 P = F * (2.0 * mu * E + lambda * E.trace() * I);
95 C = 0.5 * lambda * (E.trace() * E.trace()) + mu * (E * E).trace();
100 case MaterialType::Corotation:
102 Eigen::JacobiSVD<Mat3d> svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
103 Mat3d R = svd.matrixU() * svd.matrixV().adjoint();
104 Vec3d Sigma(svd.singularValues());
105 Mat3d invFT = svd.matrixU();
106 invFT.col(0) /= Sigma(0);
107 invFT.col(1) /= Sigma(1);
108 invFT.col(2) /= Sigma(2);
109 invFT *= svd.matrixV().adjoint();
110 double J = Sigma(0) * Sigma(1) * Sigma(2);
113 P = 2 * mu * FR + lambda * (J - 1) * J * invFT;
115 C = FR(0, 0) * FR(0, 0) + FR(0, 1) * FR(0, 1) + FR(0, 2) * FR(0, 2)
116 + FR(1, 0) * FR(1, 0) + FR(1, 1) * FR(1, 1) + FR(1, 2) * FR(1, 2)
117 + FR(2, 0) * FR(2, 0) + FR(2, 1) * FR(2, 1) + FR(2, 2) * FR(2, 2);
118 C = mu * C + 0.5 * lambda * (J - 1) * (J - 1);
124 case MaterialType::NeoHookean:
127 double I1 = (F * F.transpose()).trace();
130 double I3 = (F.transpose() * F).determinant();
131 auto logI3 = log(I3);
133 auto F_invT = F.inverse().transpose();
135 P = mu * (F - F_invT) + 0.5 * lambda * logI3 * F_invT;
137 C = 0.5 * mu * (I1 - logI3 - 3.0) + 0.125 * lambda * (logI3 * logI3);
143 case MaterialType::Linear:
145 Mat3d I = Mat3d::Identity();
147 Mat3d e = 0.5 * (F * F.transpose() - I);
149 P = 2.0 * mu * e + lambda * e.trace() * I;
150 C = mu * (e * e).trace() + 0.5 * lambda * e.trace() * e.trace();
164 dcdx[0] = gradC.col(0);
165 dcdx[1] = gradC.col(1);
166 dcdx[2] = gradC.col(2);
167 dcdx[3] = -dcdx[0] - dcdx[1] - dcdx[2];
180 Eigen::JacobiSVD<Mat3d> svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
183 Vec3d sigma(svd.singularValues());
186 for (
int i = 0; i < 3; i++)
188 Fhat(i, i) = sigma(i);
193 Mat3d V = svd.matrixV();
196 const double detV = V.determinant();
202 double minLambda = IMSTK_DOUBLE_MAX;
204 for (
int i = 0; i < 3; i++)
206 if (Fhat(i, i) < minLambda)
209 minLambda = Fhat(i, i);
213 V.col(column) *= -1.0;
222 for (
int i = 0; i < 3; i++)
224 if (fabs(Fhat(i, i)) < 1E-4)
243 for (
int i = 0; i < 3; i++)
247 for (
int j = 0; j < 3; j++)
249 U(j, i) *= 1.0 / Fhat(i, i);
256 Eigen::Matrix<double, 3, 1, 2> v[2];
258 for (
int i = 0; i < 3; i++)
262 v[index++] = Eigen::Matrix<double, 3, 1, 2>(U(0, i), U(1, i), U(2, i));
266 Vec3d vec = v[0].cross(v[1]).normalized();
267 U.col(position) = vec;
272 U = F * V * Fhat.inverse();
276 const double detU = U.determinant();
281 double minLambda = IMSTK_DOUBLE_MAX;
282 for (
int i = 0; i < 3; i++)
284 if (Fhat(i, i) < minLambda)
287 minLambda = Fhat(i, i);
293 Fhat(positionU, positionU) *= -1.0;
294 for (
int i = 0; i < 3; i++)
296 U(i, positionU) *= -1.0;
301 const double clamp = 0.577;
302 for (
int i = 0; i < 3; i++)
304 if (Fhat(i, i) < clamp)
std::pair< int, int > PbdParticleId
Index pair that refers to a particle in a PbdState. Index 0 is the body id, Index 1 is the particle i...
std::vector< PbdParticleId > m_particles
body, particle index
MaterialType m_material
Material type.
double m_initialElementVolume
Volume of the element.
double m_compliance
used in xPBD, inverse of Stiffness
void handleInversions(Mat3d &F, Mat3d &U, Mat3d &Fhat, Mat3d &VT) const
Handle inverted tets with the method described by Irving et. al. in "Invertible Finite Elements For R...
double m_lambda
Lame constant, if constraint type is Fem.
double m_mu
Lame constant, if constraint type is Fem.
bool initConstraint(const Vec3d &p0, const Vec3d &p1, const Vec3d &p2, const Vec3d &p3, const PbdParticleId &pIdx0, const PbdParticleId &pIdx1, const PbdParticleId &pIdx2, const PbdParticleId &pIdx3, PbdFemConstraintConfig config)
Initialize the constraint.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Either mu/lambda used, may be computed from youngs modulus and poissons ratio.
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of constraint function.