add newton solver
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "btSoftBody.h"
|
||||
#include <LinearMath/btHashMap.h>
|
||||
#include <iostream>
|
||||
|
||||
enum btDeformableLagrangianForceType
|
||||
{
|
||||
@@ -40,12 +41,21 @@ public:
|
||||
|
||||
virtual ~btDeformableLagrangianForce(){}
|
||||
|
||||
virtual void addScaledImplicitForce(btScalar scale, TVStack& force) = 0;
|
||||
// add all forces
|
||||
virtual void addScaledForces(btScalar scale, TVStack& force) = 0;
|
||||
|
||||
virtual void addScaledForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0;
|
||||
// add damping df
|
||||
virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0;
|
||||
|
||||
// add elastic df
|
||||
virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0;
|
||||
|
||||
// add all forces that are explicit in explicit solve
|
||||
virtual void addScaledExplicitForce(btScalar scale, TVStack& force) = 0;
|
||||
|
||||
// add all damping forces
|
||||
virtual void addScaledDampingForce(btScalar scale, TVStack& force) = 0;
|
||||
|
||||
virtual btDeformableLagrangianForceType getForceType() = 0;
|
||||
|
||||
virtual void reinitialize(bool nodeUpdated)
|
||||
@@ -71,5 +81,261 @@ public:
|
||||
{
|
||||
m_nodes = nodes;
|
||||
}
|
||||
|
||||
virtual btMatrix3x3 Ds(int id0, int id1, int id2, int id3, const TVStack& dx)
|
||||
{
|
||||
btVector3 c1 = dx[id1] - dx[id0];
|
||||
btVector3 c2 = dx[id2] - dx[id0];
|
||||
btVector3 c3 = dx[id3] - dx[id0];
|
||||
btMatrix3x3 dF(c1.getX(), c2.getX(), c3.getX(),
|
||||
c1.getY(), c2.getY(), c3.getY(),
|
||||
c1.getZ(), c2.getZ(), c3.getZ());
|
||||
return dF;
|
||||
}
|
||||
|
||||
virtual void testDerivative()
|
||||
{
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q += btVector3(randomDouble(-.1, .1), randomDouble(-.1, .1), randomDouble(-.1, .1));
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
|
||||
|
||||
TVStack dx;
|
||||
dx.resize(getNumNodes());
|
||||
TVStack dphi_dx;
|
||||
dphi_dx.resize(dx.size());
|
||||
for (int i =0; i < dphi_dx.size();++i)
|
||||
{
|
||||
dphi_dx[i].setZero();
|
||||
}
|
||||
addScaledForces(-1, dphi_dx);
|
||||
|
||||
// write down the current position
|
||||
TVStack x;
|
||||
x.resize(dx.size());
|
||||
int counter = 0;
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
x[counter] = psb->m_nodes[j].m_q;
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
// populate dx with random vectors
|
||||
for (int i = 0; i < dx.size(); ++i)
|
||||
{
|
||||
dx[i].setX(randomDouble(-1, 1));
|
||||
dx[i].setY(randomDouble(-1, 1));
|
||||
dx[i].setZ(randomDouble(-1, 1));
|
||||
}
|
||||
|
||||
btAlignedObjectArray<double> errors;
|
||||
double h = 1;
|
||||
for (int it = 0; it < 10; ++it)
|
||||
{
|
||||
for (int i = 0; i < dx.size(); ++i)
|
||||
{
|
||||
dx[i] *= 0.5;
|
||||
}
|
||||
|
||||
// get dphi/dx * dx
|
||||
double dphi = 0;
|
||||
for (int i = 0; i < dx.size(); ++i)
|
||||
{
|
||||
dphi += dphi_dx[i].dot(dx[i]);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter] + dx[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
double f1 = totalElasticEnergy();
|
||||
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter] - dx[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
double f2 = totalElasticEnergy();
|
||||
|
||||
//restore m_q
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
double error = f1-f2-2*dphi;
|
||||
errors.push_back(error);
|
||||
std::cout << "Iteration = " << it <<", f1 = " << f1 << ", f2 = " << f2 << ", error = " << error << std::endl;
|
||||
}
|
||||
for (int i = 1; i < errors.size(); ++i)
|
||||
{
|
||||
std::cout << "Iteration = " << i << ", ratio = " << errors[i-1]/errors[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void testHessian()
|
||||
{
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q += btVector3(randomDouble(-.1, .1), randomDouble(-.1, .1), randomDouble(-.1, .1));
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
|
||||
|
||||
TVStack dx;
|
||||
dx.resize(getNumNodes());
|
||||
TVStack df;
|
||||
df.resize(dx.size());
|
||||
TVStack f1;
|
||||
f1.resize(dx.size());
|
||||
TVStack f2;
|
||||
f2.resize(dx.size());
|
||||
|
||||
|
||||
// write down the current position
|
||||
TVStack x;
|
||||
x.resize(dx.size());
|
||||
int counter = 0;
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
x[counter] = psb->m_nodes[j].m_q;
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
// populate dx with random vectors
|
||||
for (int i = 0; i < dx.size(); ++i)
|
||||
{
|
||||
dx[i].setX(randomDouble(-1, 1));
|
||||
dx[i].setY(randomDouble(-1, 1));
|
||||
dx[i].setZ(randomDouble(-1, 1));
|
||||
}
|
||||
|
||||
btAlignedObjectArray<double> errors;
|
||||
for (int it = 0; it < 10; ++it)
|
||||
{
|
||||
for (int i = 0; i < dx.size(); ++i)
|
||||
{
|
||||
dx[i] *= 0.5;
|
||||
}
|
||||
|
||||
// get df
|
||||
for (int i =0; i < df.size();++i)
|
||||
{
|
||||
df[i].setZero();
|
||||
f1[i].setZero();
|
||||
f2[i].setZero();
|
||||
}
|
||||
|
||||
//set df
|
||||
addScaledElasticForceDifferential(-1, dx, df);
|
||||
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter] + dx[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
//set f1
|
||||
addScaledForces(-1, f1);
|
||||
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter] - dx[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
|
||||
//set f2
|
||||
addScaledForces(-1, f2);
|
||||
|
||||
//restore m_q
|
||||
for (int i = 0; i<m_softBodies.size();++i)
|
||||
{
|
||||
btSoftBody* psb = m_softBodies[i];
|
||||
for (int j = 0; j < psb->m_nodes.size(); ++j)
|
||||
{
|
||||
psb->m_nodes[j].m_q = x[counter];
|
||||
counter++;
|
||||
}
|
||||
psb->updateDeformation();
|
||||
}
|
||||
counter = 0;
|
||||
double error = 0;
|
||||
for (int i = 0; i < df.size();++i)
|
||||
{
|
||||
btVector3 error_vector = f1[i]-f2[i]-2*df[i];
|
||||
error += error_vector.length2();
|
||||
}
|
||||
error = btSqrt(error);
|
||||
errors.push_back(error);
|
||||
std::cout << "Iteration = " << it << ", error = " << error << std::endl;
|
||||
}
|
||||
for (int i = 1; i < errors.size(); ++i)
|
||||
{
|
||||
std::cout << "Iteration = " << i << ", ratio = " << errors[i-1]/errors[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual double totalElasticEnergy()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
double randomDouble(double low, double high)
|
||||
{
|
||||
return low + static_cast<double>(rand()) / RAND_MAX * (high - low);
|
||||
}
|
||||
};
|
||||
#endif /* BT_DEFORMABLE_LAGRANGIAN_FORCE */
|
||||
|
||||
Reference in New Issue
Block a user