1#include "PJSConstraintSolver.h"
2#include "SharedFuncsForRigidBody.h"
3//#define USE_RELAXATION
4#define FILE_NAME "D:/Work Code/peridyno/Data/v2.txt"
7 IMPLEMENT_TCLASS(PJSConstraintSolver, TDataType)
9 template<typename TDataType>
10 PJSConstraintSolver<TDataType>::PJSConstraintSolver()
13 this->inContacts()->tagOptional(true);
16 template<typename TDataType>
17 PJSConstraintSolver<TDataType>::~PJSConstraintSolver()
21 template<typename TDataType>
22 void PJSConstraintSolver<TDataType>::initializeRelaxation()
24 int constraint_size = 0;
25 int contact_size = this->inContacts()->size();
27 auto topo = this->inDiscreteElements()->constDataPtr();
29 int ballAndSocketJoint_size = topo->ballAndSocketJoints().size();
30 int sliderJoint_size = topo->sliderJoints().size();
31 int hingeJoint_size = topo->hingeJoints().size();
32 int fixedJoint_size = topo->fixedJoints().size();
33 int pointJoint_size = topo->pointJoints().size();
35 if (this->varFrictionEnabled()->getData())
37 constraint_size += 3 * contact_size;
41 constraint_size = contact_size;
44 if (ballAndSocketJoint_size != 0)
46 constraint_size += 3 * ballAndSocketJoint_size;
49 if (sliderJoint_size != 0)
51 constraint_size += 8 * sliderJoint_size;
54 if (hingeJoint_size != 0)
56 constraint_size += 8 * hingeJoint_size;
59 if (fixedJoint_size != 0)
61 constraint_size += 6 * fixedJoint_size;
64 if (pointJoint_size != 0)
66 constraint_size += 3 * pointJoint_size;
69 if (constraint_size == 0)
74 mVelocityConstraints.resize(constraint_size);
76 if (contact_size != 0)
78 auto& contacts = this->inContacts()->getData();
79 setUpContactAndFrictionConstraints(
81 mContactsInLocalFrame,
82 this->inCenter()->getData(),
83 this->inRotationMatrix()->getData(),
84 this->varFrictionEnabled()->getData()
88 if (ballAndSocketJoint_size != 0)
90 auto& joints = topo->ballAndSocketJoints();
91 int begin_index = contact_size;
93 if (this->varFrictionEnabled()->getData())
95 begin_index += 2 * contact_size;
98 setUpBallAndSocketJointConstraints(
101 this->inCenter()->getData(),
102 this->inRotationMatrix()->getData(),
107 if (sliderJoint_size != 0)
109 auto& joints = topo->sliderJoints();
110 int begin_index = contact_size;
112 if (this->varFrictionEnabled()->getData())
114 begin_index += 2 * contact_size;
116 begin_index += 3 * ballAndSocketJoint_size;
117 setUpSliderJointConstraints(
118 mVelocityConstraints,
120 this->inCenter()->getData(),
121 this->inRotationMatrix()->getData(),
122 this->inQuaternion()->getData(),
127 if (hingeJoint_size != 0)
129 auto& joints = topo->hingeJoints();
130 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size;
131 if (this->varFrictionEnabled()->getData())
133 begin_index += 2 * contact_size;
135 setUpHingeJointConstraints(
136 mVelocityConstraints,
138 this->inCenter()->getData(),
139 this->inRotationMatrix()->getData(),
140 this->inQuaternion()->getData(),
145 if (fixedJoint_size != 0)
147 auto& joints = topo->fixedJoints();
148 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size + 8 * hingeJoint_size;
149 if (this->varFrictionEnabled()->getData())
151 begin_index += 2 * contact_size;
153 setUpFixedJointConstraints(
154 mVelocityConstraints,
156 this->inRotationMatrix()->getData(),
157 this->inQuaternion()->getData(),
162 if (pointJoint_size != 0)
164 auto& joints = topo->pointJoints();
165 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size + 8 * hingeJoint_size + 6 * fixedJoint_size;
166 if (this->varFrictionEnabled()->getData())
168 begin_index += 2 * contact_size;
170 setUpPointJointConstraints(
171 mVelocityConstraints,
173 this->inCenter()->getData(),
178 auto sizeOfRigids = this->inCenter()->size();
179 mContactNumber.resize(sizeOfRigids);
181 mJ.resize(4 * constraint_size);
182 mB.resize(4 * constraint_size);
183 mK_1.resize(constraint_size);
184 mK_2.resize(constraint_size);
185 mK_3.resize(constraint_size);
186 mEta.resize(constraint_size);
195 calculateJacobianMatrix(
198 this->inCenter()->getData(),
199 this->inInertia()->getData(),
200 this->inMass()->getData(),
201 this->inRotationMatrix()->getData(),
206 mVelocityConstraints,
209 this->inCenter()->getData(),
210 this->inInertia()->getData(),
211 this->inMass()->getData(),
217 calculateEtaVectorForRelaxation(
220 this->inVelocity()->getData(),
221 this->inAngularVelocity()->getData(),
228 template<typename TDataType>
229 void PJSConstraintSolver<TDataType>::initializeJacobian(Real dt)
231 int constraint_size = 0;
232 int contact_size = this->inContacts()->size();
234 auto topo = this->inDiscreteElements()->constDataPtr();
236 int ballAndSocketJoint_size = topo->ballAndSocketJoints().size();
237 int sliderJoint_size = topo->sliderJoints().size();
238 int hingeJoint_size = topo->hingeJoints().size();
239 int fixedJoint_size = topo->fixedJoints().size();
240 int pointJoint_size = topo->pointJoints().size();
242 if (this->varFrictionEnabled()->getData())
244 constraint_size += 3 * contact_size;
248 constraint_size = contact_size;
251 if (ballAndSocketJoint_size != 0)
253 constraint_size += 3 * ballAndSocketJoint_size;
256 if (sliderJoint_size != 0)
258 constraint_size += 8 * sliderJoint_size;
261 if (hingeJoint_size != 0)
263 constraint_size += 8 * hingeJoint_size;
266 if (fixedJoint_size != 0)
268 constraint_size += 6 * fixedJoint_size;
271 if (pointJoint_size != 0)
273 constraint_size += 3 * pointJoint_size;
276 if (constraint_size == 0)
281 mVelocityConstraints.resize(constraint_size);
283 if (contact_size != 0)
285 if (mContactsInLocalFrame.size() != this->inContacts()->size()) {
286 mContactsInLocalFrame.resize(this->inContacts()->size());
289 setUpContactsInLocalFrame(
290 mContactsInLocalFrame,
291 this->inContacts()->getData(),
292 this->inCenter()->getData(),
293 this->inRotationMatrix()->getData()
296 auto& contacts = this->inContacts()->getData();
297 setUpContactAndFrictionConstraints(
298 mVelocityConstraints,
299 mContactsInLocalFrame,
300 this->inCenter()->getData(),
301 this->inRotationMatrix()->getData(),
302 this->varFrictionEnabled()->getData()
306 if (ballAndSocketJoint_size != 0)
308 auto& joints = topo->ballAndSocketJoints();
309 int begin_index = contact_size;
311 if (this->varFrictionEnabled()->getData())
313 begin_index += 2 * contact_size;
316 setUpBallAndSocketJointConstraints(
317 mVelocityConstraints,
319 this->inCenter()->getData(),
320 this->inRotationMatrix()->getData(),
325 if (sliderJoint_size != 0)
327 auto& joints = topo->sliderJoints();
328 int begin_index = contact_size;
330 if (this->varFrictionEnabled()->getData())
332 begin_index += 2 * contact_size;
334 begin_index += 3 * ballAndSocketJoint_size;
335 setUpSliderJointConstraints(
336 mVelocityConstraints,
338 this->inCenter()->getData(),
339 this->inRotationMatrix()->getData(),
340 this->inQuaternion()->getData(),
345 if (hingeJoint_size != 0)
347 auto& joints = topo->hingeJoints();
348 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size;
349 if (this->varFrictionEnabled()->getData())
351 begin_index += 2 * contact_size;
353 setUpHingeJointConstraints(
354 mVelocityConstraints,
356 this->inCenter()->getData(),
357 this->inRotationMatrix()->getData(),
358 this->inQuaternion()->getData(),
363 if (fixedJoint_size != 0)
365 auto& joints = topo->fixedJoints();
366 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size + 8 * hingeJoint_size;
367 if (this->varFrictionEnabled()->getData())
369 begin_index += 2 * contact_size;
371 setUpFixedJointConstraints(
372 mVelocityConstraints,
374 this->inRotationMatrix()->getData(),
375 this->inQuaternion()->getData(),
380 if (pointJoint_size != 0)
382 auto& joints = topo->pointJoints();
383 int begin_index = contact_size + 3 * ballAndSocketJoint_size + 8 * sliderJoint_size + 8 * hingeJoint_size + 6 * fixedJoint_size;
384 if (this->varFrictionEnabled()->getData())
386 begin_index += 2 * contact_size;
388 setUpPointJointConstraints(
389 mVelocityConstraints,
391 this->inCenter()->getData(),
396 auto sizeOfRigids = this->inCenter()->size();
397 mContactNumber.resize(sizeOfRigids);
399 mJ.resize(4 * constraint_size);
400 mB.resize(4 * constraint_size);
401 mK_1.resize(constraint_size);
402 mK_2.resize(constraint_size);
403 mK_3.resize(constraint_size);
404 mEta.resize(constraint_size);
405 mLambda.resize(constraint_size);
419 mContactNumber.reset();
421 calculateJacobianMatrix(
424 this->inCenter()->getData(),
425 this->inInertia()->getData(),
426 this->inMass()->getData(),
427 this->inRotationMatrix()->getData(),
431 mErrors.resize(constraint_size);
434 calculateEtaVectorForPJSBaumgarte(
437 this->inVelocity()->getData(),
438 this->inAngularVelocity()->getData(),
439 this->inCenter()->getData(),
440 this->inQuaternion()->getData(),
441 mVelocityConstraints,
443 this->varSlop()->getValue(),
444 this->varBaumgarteRate()->getValue(),
450 mVelocityConstraints,
453 this->inCenter()->getData(),
454 this->inInertia()->getData(),
455 this->inMass()->getData(),
461 if (contact_size != 0)
463 calculateContactPoints(
464 this->inContacts()->getData(),
469 template<typename TDataType>
470 void PJSConstraintSolver<TDataType>::constrain()
472 uint bodyNum = this->inCenter()->size();
474 auto topo = this->inDiscreteElements()->constDataPtr();
476 mImpulseC.resize(bodyNum * 2);
477 mImpulseExt.resize(bodyNum * 2);
481 Real dt = this->inTimeStep()->getData();
483 if (this->varGravityEnabled()->getValue())
487 this->varGravityValue()->getValue(),
494 this->inAttribute()->getData(),
495 this->inVelocity()->getData(),
496 this->inAngularVelocity()->getData(),
498 this->varLinearDamping()->getValue(),
499 this->varAngularDamping()->getValue(),
503 if (!this->inContacts()->isEmpty() || topo->totalJointSize() > 0)
505 int contact_size = this->inContacts()->size();
506 initializeJacobian(dt);
507 errors.push_back(checkOutErrors(mErrors));
508 int constraint_size = mVelocityConstraints.size();
512 for (int i = 0; i < this->varIterationNumberForVelocitySolver()->getValue(); i++)
520 mVelocityConstraints,
525 this->inMass()->getData(),
526 this->inFrictionCoefficients()->getData(),
527 this->varFrictionCoefficient()->getData(),
528 this->varGravityValue()->getData(),
533 Real norm = checkOutError(
536 mVelocityConstraints,
541 errors.push_back(norm);
544 this->inAttribute()->getData(),
545 this->inVelocity()->getData(),
546 this->inAngularVelocity()->getData(),
548 this->varLinearDamping()->getValue(),
549 this->varAngularDamping()->getValue(),
554 this->inAttribute()->getData(),
555 this->inCenter()->getData(),
556 this->inQuaternion()->getData(),
557 this->inRotationMatrix()->getData(),
558 this->inInertia()->getData(),
559 this->inVelocity()->getData(),
560 this->inAngularVelocity()->getData(),
561 this->inInitialInertia()->getData(),
565 #ifdef USE_RELAXATION
567 initializeRelaxation();
569 for (int i = 0; i < 30; i++)
577 mVelocityConstraints,
582 this->inMass()->getData(),
583 this->varFrictionCoefficient()->getData(),
584 this->varGravityValue()->getData(),
590 this->inAttribute()->getData(),
591 this->inVelocity()->getData(),
592 this->inAngularVelocity()->getData(),
606 this->inAttribute()->getData(),
607 this->inCenter()->getData(),
608 this->inQuaternion()->getData(),
609 this->inRotationMatrix()->getData(),
610 this->inInertia()->getData(),
611 this->inVelocity()->getData(),
612 this->inAngularVelocity()->getData(),
613 this->inInitialInertia()->getData(),
623 DEFINE_CLASS(PJSConstraintSolver);