Bullet Collision Detection & Physics Library: btDeformableBackwardEulerObjective.cpp Source File

Bullet Collision Detection & Physics Library

btDeformableBackwardEulerObjective.cpp
Go to the documentation of this file.
1 /*
2 Written by Xuchen Han <xuchenhan2015@u.northwestern.edu>
3
4 Bullet Continuous Collision Detection and Physics Library
5 Copyright (c) 2019 Google Inc. http://bulletphysics.org
6 This software is provided 'as-is', without any express or implied warranty.
7 In no event will the authors be held liable for any damages arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it freely,
10 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "btDeformableBackwardEulerObjective.h"
17 #include "btPreconditioner.h"
18 #include "LinearMath/btQuickprof.h"
19
20 btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray<btSoftBody *>& softBodies, const TVStack& backup_v)
21 : m_softBodies(softBodies)
22 , m_projection(softBodies)
23 , m_backupVelocity(backup_v)
24 , m_implicit(false)
25 {
26 m_preconditioner = new MassPreconditioner(m_softBodies);
27 }
28
29 btDeformableBackwardEulerObjective::~btDeformableBackwardEulerObjective()
30 {
31 delete m_preconditioner;
32 }
33
34 void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar dt)
35 {
36 BT_PROFILE("reinitialize");
37 if (dt > 0)
38 {
39 setDt(dt);
40 }
41 if(nodeUpdated)
42 {
43 updateId();
44 }
45 for (int i = 0; i < m_lf.size(); ++i)
46 {
47 m_lf[i]->reinitialize(nodeUpdated);
48 }
49 m_projection.reinitialize(nodeUpdated);
50 m_preconditioner->reinitialize(nodeUpdated);
51 }
52
53 void btDeformableBackwardEulerObjective::setDt(btScalar dt)
54 {
55 m_dt = dt;
56 }
57
58 void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const
59 {
60 BT_PROFILE("multiply");
61 // add in the mass term
62 size_t counter = 0;
63 for (int i = 0; i < m_softBodies.size(); ++i)
64 {
65 btSoftBody* psb = m_softBodies[i];
66 for (int j = 0; j < psb->m_nodes.size(); ++j)
67 {
68 const btSoftBody::Node& node = psb->m_nodes[j];
69 b[counter] = (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im;
70 ++counter;
71 }
72 }
73
74 for (int i = 0; i < m_lf.size(); ++i)
75 {
76 // add damping matrix
77 m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b);
78 if (m_implicit)
79 {
80 m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b);
81 }
82 }
83 }
84
85 void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv)
86 {
87 for (int i = 0; i < m_softBodies.size(); ++i)
88 {
89 btSoftBody* psb = m_softBodies[i];
90 for (int j = 0; j < psb->m_nodes.size(); ++j)
91 {
92 btSoftBody::Node& node = psb->m_nodes[j];
93 node.m_v = m_backupVelocity[node.index] + dv[node.index];
94 }
95 }
96 }
97
98 void btDeformableBackwardEulerObjective::applyForce(TVStack& force, bool setZero)
99 {
100 size_t counter = 0;
101 for (int i = 0; i < m_softBodies.size(); ++i)
102 {
103 btSoftBody* psb = m_softBodies[i];
104 if (!psb->isActive())
105 {
106 counter += psb->m_nodes.size();
107 continue;
108 }
109 for (int j = 0; j < psb->m_nodes.size(); ++j)
110 {
111 btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im;
112 psb->m_nodes[j].m_v += one_over_mass * force[counter++];
113 }
114 }
115 if (setZero)
116 {
117 for (int i = 0; i < force.size(); ++i)
118 force[i].setZero();
119 }
120 }
121
122 void btDeformableBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual)
123 {
124 BT_PROFILE("computeResidual");
125 // add implicit force
126 for (int i = 0; i < m_lf.size(); ++i)
127 {
128 if (m_implicit)
129 {
130 m_lf[i]->addScaledForces(dt, residual);
131 }
132 else
133 {
134 m_lf[i]->addScaledDampingForce(dt, residual);
135 }
136 }
137 m_projection.project(residual);
138 }
139
140 btScalar btDeformableBackwardEulerObjective::computeNorm(const TVStack& residual) const
141 {
142 btScalar mag = 0;
143 for (int i = 0; i < residual.size(); ++i)
144 {
145 mag += residual[i].length2();
146 }
147 return std::sqrt(mag);
148 }
149
150 btScalar btDeformableBackwardEulerObjective::totalEnergy(btScalar dt)
151 {
152 btScalar e = 0;
153 for (int i = 0; i < m_lf.size(); ++i)
154 {
155 e += m_lf[i]->totalEnergy(dt);
156 }
157 return e;
158 }
159
160 void btDeformableBackwardEulerObjective::applyExplicitForce(TVStack& force)
161 {
162 for (int i = 0; i < m_softBodies.size(); ++i)
163 {
164 m_softBodies[i]->advanceDeformation();
165 }
166
167 for (int i = 0; i < m_lf.size(); ++i)
168 {
169 m_lf[i]->addScaledExplicitForce(m_dt, force);
170 }
171 applyForce(force, true);
172 }
173
174 void btDeformableBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual)
175 {
176 size_t counter = 0;
177 for (int i = 0; i < m_softBodies.size(); ++i)
178 {
179 btSoftBody* psb = m_softBodies[i];
180 for (int j = 0; j < psb->m_nodes.size(); ++j)
181 {
182 dv[counter] = psb->m_nodes[j].m_im * residual[counter];
183 ++counter;
184 }
185 }
186 }
187
188 //set constraints as projections
189 void btDeformableBackwardEulerObjective::setConstraints()
190 {
191 m_projection.setConstraints();
192 }
193
194 void btDeformableBackwardEulerObjective::applyDynamicFriction(TVStack& r)
195 {
196 m_projection.applyDynamicFriction(r);
197 }
btDeformableBackwardEulerObjective::m_lf
btAlignedObjectArray< btDeformableLagrangianForce * > m_lf
Definition: btDeformableBackwardEulerObjective.h:35
btDeformableContactProjection::reinitialize
virtual void reinitialize(bool nodeUpdated)
Definition: btDeformableContactProjection.cpp:485
Preconditioner::reinitialize
virtual void reinitialize(bool nodeUpdated)=0
btDeformableContactProjection::setConstraints
virtual void setConstraints()
Definition: btDeformableContactProjection.cpp:111
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btDeformableBackwardEulerObjective::setDt
void setDt(btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:53
btDeformableBackwardEulerObjective::applyForce
void applyForce(TVStack &force, bool setZero)
Definition: btDeformableBackwardEulerObjective.cpp:98
btDeformableBackwardEulerObjective::m_implicit
bool m_implicit
Definition: btDeformableBackwardEulerObjective.h:41
btDeformableBackwardEulerObjective::m_projection
btDeformableContactProjection m_projection
Definition: btDeformableBackwardEulerObjective.h:38
btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective
btDeformableBackwardEulerObjective(btAlignedObjectArray< btSoftBody * > &softBodies, const TVStack &backup_v)
Definition: btDeformableBackwardEulerObjective.cpp:20
btDeformableContactProjection::applyDynamicFriction
virtual void applyDynamicFriction(TVStack &f)
Definition: btDeformableContactProjection.cpp:434
btDeformableBackwardEulerObjective::m_dt
btScalar m_dt
Definition: btDeformableBackwardEulerObjective.h:34
btDeformableBackwardEulerObjective::reinitialize
void reinitialize(bool nodeUpdated, btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:34
btDeformableBackwardEulerObjective::m_preconditioner
Preconditioner * m_preconditioner
Definition: btDeformableBackwardEulerObjective.h:37
btDeformableBackwardEulerObjective::setConstraints
void setConstraints()
Definition: btDeformableBackwardEulerObjective.cpp:189
btSoftBody::Node
Definition: btSoftBody.h:256
btDeformableBackwardEulerObjective::applyDynamicFriction
void applyDynamicFriction(TVStack &r)
Definition: btDeformableBackwardEulerObjective.cpp:194
btDeformableBackwardEulerObjective::updateId
virtual void updateId()
Definition: btDeformableBackwardEulerObjective.h:98
btDeformableBackwardEulerObjective::updateVelocity
void updateVelocity(const TVStack &dv)
Definition: btDeformableBackwardEulerObjective.cpp:85
btDeformableBackwardEulerObjective::computeResidual
void computeResidual(btScalar dt, TVStack &residual)
Definition: btDeformableBackwardEulerObjective.cpp:122
btDeformableBackwardEulerObjective::computeNorm
btScalar computeNorm(const TVStack &residual) const
Definition: btDeformableBackwardEulerObjective.cpp:140
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
btDeformableContactProjection::project
virtual void project(TVStack &x)
Definition: btDeformableContactProjection.cpp:206
btSoftBody::Node::index
int index
Definition: btSoftBody.h:268
btDeformableBackwardEulerObjective::initialGuess
void initialGuess(TVStack &dv, const TVStack &residual)
Definition: btDeformableBackwardEulerObjective.cpp:174
btAlignedObjectArray< btSoftBody * >
btDeformableBackwardEulerObjective::~btDeformableBackwardEulerObjective
virtual ~btDeformableBackwardEulerObjective()
Definition: btDeformableBackwardEulerObjective.cpp:29
btDeformableBackwardEulerObjective::multiply
void multiply(const TVStack &x, TVStack &b) const
Definition: btDeformableBackwardEulerObjective.cpp:58
btSoftBody
The btSoftBody is an class to simulate cloth and volumetric soft bodies.
Definition: btSoftBody.h:73
btDeformableBackwardEulerObjective::totalEnergy
btScalar totalEnergy(btScalar dt)
Definition: btDeformableBackwardEulerObjective.cpp:150
btDeformableBackwardEulerObjective::m_backupVelocity
const TVStack & m_backupVelocity
Definition: btDeformableBackwardEulerObjective.h:39
btQuickprof.h
btDeformableBackwardEulerObjective::m_softBodies
btAlignedObjectArray< btSoftBody * > & m_softBodies
Definition: btDeformableBackwardEulerObjective.h:36
btCollisionObject::isActive
bool isActive() const
Definition: btCollisionObject.h:294
btDeformableBackwardEulerObjective::applyExplicitForce
void applyExplicitForce(TVStack &force)
Definition: btDeformableBackwardEulerObjective.cpp:160
MassPreconditioner
Definition: btPreconditioner.h:45
btSoftBody::Node::m_im
btScalar m_im
Definition: btSoftBody.h:264
btSoftBody::Node::m_v
btVector3 m_v
Definition: btSoftBody.h:259
btPreconditioner.h
BT_PROFILE
#define BT_PROFILE(name)
Definition: btQuickprof.h:198
btDeformableBackwardEulerObjective.h
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btSoftBody::m_nodes
tNodeArray m_nodes
Definition: btSoftBody.h:777