Incorporate plasticity model. Update the tests

This commit is contained in:
Irlan 2019-05-22 18:16:47 -03:00
parent e0d2f9f512
commit 494fa0baa9
5 changed files with 110 additions and 4 deletions

View File

@ -33,7 +33,10 @@ public:
def.mesh = &m_mesh;
def.density = 0.2f;
def.E = 100.0f;
def.nu = 0.33f;
def.nu = 0.33f;
def.c_yield = 0.1f;
def.c_creep = 0.5f;
def.c_max = 1.0f;
m_body = new b3SoftBody(def);

View File

@ -39,6 +39,9 @@ public:
def.density = 0.2f;
def.E = 100.0f;
def.nu = 0.33f;
def.c_yield = 0.6f;
def.c_creep = 1.0f;
def.c_max = 1.0f;
m_body = new b3SoftBody(def);

View File

@ -42,9 +42,12 @@ struct b3SoftBodyRayCastSingleOutput
// Soft body tetrahedron element
struct b3SoftBodyElement
{
b3Mat33 K[16];
b3Mat33 K[16]; // 12 x 12
b3Mat33 invE;
b3Quat q;
float32 B[72]; // 6 x 12
float32 P[72]; // V * BT * E -> 12 x 6
float32 epsilon_plastic[6]; // 6 x 1
};
// Soft body tetrahedron triangle
@ -64,6 +67,9 @@ struct b3SoftBodyDef
density = 0.1f;
E = 100.0f;
nu = 0.3f;
c_yield = B3_MAX_FLOAT;
c_creep = 0.0f;
c_max = 0.0f;
}
// Soft body mesh
@ -79,6 +85,17 @@ struct b3SoftBodyDef
// Material Poisson ratio in [0, 0.5]
// This is a dimensionless value
float32 nu;
// Material yield in [0, inf]
// This is a dimensionless value
float32 c_yield;
// Material creep rate in [0, 1 / dt]
// Units are inverse seconds
float32 c_creep;
// Material maximum plastic strain in [0, inf]
float32 c_max;
};
// A soft body represents a deformable volume as a collection of nodes and elements.
@ -149,6 +166,15 @@ private:
// Material poisson ratio
float32 m_nu;
// Material yield
float32 m_c_yield;
// Material creep rate
float32 m_c_creep;
// Material maximum plastic strain
float32 m_c_max;
// Soft body nodes
b3SoftBodyNode* m_nodes;

View File

@ -436,6 +436,9 @@ b3SoftBody::b3SoftBody(const b3SoftBodyDef& def)
m_density = def.density;
m_E = def.E;
m_nu = def.nu;
m_c_yield = def.c_yield;
m_c_creep = def.c_creep;
m_c_max = def.c_max;
m_gravity.SetZero();
m_world = nullptr;
@ -499,7 +502,7 @@ b3SoftBody::b3SoftBody(const b3SoftBodyDef& def)
b3ComputeD(D, m_E, m_nu);
// 6 x 12
float32 B[72];
float32* B = e->B;
b3ComputeB(B, e10, e20, e30, V);
// 12 x 6
@ -519,6 +522,19 @@ b3SoftBody::b3SoftBody(const b3SoftBodyDef& def)
}
b3SetK(e->K, BT_D_B);
// 12 x 6
float32* P = e->P;
b3Mul(P, BT, 12, 6, D, 6, 6);
for (u32 i = 0; i < 72; ++i)
{
P[i] *= V;
}
for (u32 i = 0; i < 6; ++i)
{
e->epsilon_plastic[i] = 0.0f;
}
}
// Initialize triangles

View File

@ -241,6 +241,10 @@ void b3SoftBodySolver::Solve(float32 dt, const b3Vec3& gravity, u32 velocityIter
b3Mat33* Ke = e->K;
float32* Be = e->B;
float32* Pe = e->P;
float32* epsilon_plastic = e->epsilon_plastic;
u32 v1 = mt->v1;
u32 v2 = mt->v2;
u32 v3 = mt->v3;
@ -285,6 +289,7 @@ void b3SoftBodySolver::Solve(float32 dt, const b3Vec3& gravity, u32 velocityIter
}
}
// Elasticity
b3Vec3 x1 = x[v1];
b3Vec3 x2 = x[v2];
b3Vec3 x3 = x[v3];
@ -308,13 +313,66 @@ void b3SoftBodySolver::Solve(float32 dt, const b3Vec3& gravity, u32 velocityIter
f0[v2] += f0s[1];
f0[v3] += f0s[2];
f0[v4] += f0s[3];
// Plasticity
b3Vec3 ps[4] = { p1, p2, p3, p4 };
b3Vec3 RT_x_x0[4];
for (u32 i = 0; i < 4; ++i)
{
RT_x_x0[i] = RT * ps[i] - xs[i];
}
// 6 x 1
float32 epsilon_total[6];
b3Mul(epsilon_total, Be, 6, 12, &RT_x_x0[0].x, 12, 1);
// 6 x 1
float32 epsilon_elastic[6];
for (u32 i = 0; i < 6; ++i)
{
epsilon_elastic[i] = epsilon_total[i] - epsilon_plastic[i];
}
float32 len_epsilon_elastic = b3Length(epsilon_elastic, 6);
if (len_epsilon_elastic > m_body->m_c_yield)
{
float32 amount = h * b3Min(m_body->m_c_creep, inv_h);
for (u32 i = 0; i < 6; ++i)
{
epsilon_plastic[i] += amount * epsilon_elastic[i];
}
}
float32 len_epsilon_plastic = b3Length(epsilon_plastic, 6);
if (len_epsilon_plastic > m_body->m_c_max)
{
float32 scale = m_body->m_c_max / len_epsilon_plastic;
for (u32 i = 0; i < 6; ++i)
{
epsilon_plastic[i] *= scale;
}
}
b3Vec3 fs_plastic[4];
b3Mul(&fs_plastic[0].x, Pe, 12, 6, epsilon_plastic, 6, 1);
for (u32 i = 0; i < 4; ++i)
{
fs_plastic[i] = R * fs_plastic[i];
}
f_plastic[v1] += fs_plastic[0];
f_plastic[v2] += fs_plastic[1];
f_plastic[v3] += fs_plastic[2];
f_plastic[v4] += fs_plastic[3];
}
f0 = -f0;
b3SparseMat33 A = M + h * h * K;
b3DenseVec3 b = M * v - h * (K * p + f0 + f_plastic - fe);
//b3DenseVec3 b = M * v - h * (K * p + f0 + f_plastic - fe);
b3DenseVec3 b = M * v - h * (K * p + f0 - (f_plastic + fe));
// Solve Ax = b
b3DenseVec3 sx(m_mesh->vertexCount);