QuaternionUnitTest.cpp File Reference

Functions

void test1 ()
 
void test2 ()
 
int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc  ,
char **  argv 
)
146  {
147  test1();
148  test2();
149  return 0;
150 }
void test2()
Definition: QuaternionUnitTest.cpp:86
void test1()
Definition: QuaternionUnitTest.cpp:30

References test1(), and test2().

◆ test1()

void test1 ( )
Todo:
shouldn't this be default?
30  {
31  logger(INFO, "Test 1:\n"
32  "We apply a torque T around the z-axis to a motionless\n"
33  "particle of inertia I for a time t using a time step dt.\n"
34  "The result is a final angular velocity omega=T/I*t\n"
35  "and rotation angle alpha=T/I*t^2/2.\n"
36  "\n"
37  "The input/output values should be:\n"
38  " T = 0.1*pi*(0 0 1) Nm\n"
39  " I = 0.1 kg m^2\n"
40  " t = 1 s\n"
41  " dt = 1e-5 s\n"
42  " omega=pi*(0 0 1) rad/s\n"
43  " alpha = pi/2*(0 0 1) rad\n");
44 
45  //compute mass (requires species and handler to be set)
46  DPMBase D;
47  LinearViscoelasticSpecies* S = D.speciesHandler.copyAndAddObject(LinearViscoelasticSpecies());
48  BaseParticle* P = D.particleHandler.copyAndAddObject(SphericalParticle(S));
49  D.setDimension(3);
50  S->setDensity(6.0 / constants::pi);
51  P->setRadius(0.5);
52  S->computeMass(P);
53 
54  //std::cout << "P " << *P << std::endl;
55  P->setForce({1, 0, 0});
56  P->setTorque(0.1 * constants::pi * Vec3D(0, 0, 1));
57  Mdouble timeMax = 1.0;
58  Mdouble timeStep = 1e-5;
59  for (Mdouble time = 0; time < timeMax; time += timeStep)
60  {
61  P->accelerate(P->getForce() * P->getInvMass() * timeStep);
62  P->move(P->getVelocity() * timeStep);
63  P->angularAccelerate(
64  P->getOrientation().rotateInverseInertiaTensor(P->getInvInertia()) * P->getTorque() * timeStep);
65  P->rotate(P->getAngularVelocity() * timeStep);
66  }
67 
68  logger(INFO, "Results:\n"
69  " omega= %\n"
70  " alpha= %", P->getAngularVelocity(), P->getOrientation().getEuler());
71 
72  // std::cout << P->getAngularVelocity() - Vec3D(0,0,pi) << std::endl;
73  // std::cout << P->getOrientation().getEuler() - Vec3D(0,0,pi/2) << std::endl;
74 
75  //check results (with numerical error values added))
76  if (!mathsFunc::isEqual(P->getAngularVelocity(), Vec3D(0, 0, pi + 3.14159e-05), 1e-10))
77  {
78  logger(ERROR, "angular velocity is %, but should be %", P->getAngularVelocity(), pi / 2);
79  }
80  if (!mathsFunc::isEqual(P->getOrientation().getEuler(), {0, 0, pi / 2 + 4.71241e-05}, 1e-10))
81  {
82  logger(ERROR, "orientation is %, but should be %", P->getOrientation().getEuler().Z, pi / 2);
83  }
84 }
dominoes D
Definition: Domino.cpp:76
Species< LinearViscoelasticNormalSpecies > LinearViscoelasticSpecies
Definition: LinearViscoelasticSpecies.h:33
LL< Log::INFO > INFO
Info log level.
Definition: Logger.cc:55
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
LL< Log::ERROR > ERROR
Error log level.
Definition: Logger.cc:53
Definition: BaseParticle.h:54
The DPMBase header includes quite a few header files, defining all the handlers, which are essential....
Definition: DPMBase.h:77
void setDensity(Mdouble density)
Definition: ParticleSpecies.cc:108
void computeMass(BaseParticle *p) const
Compute Particle mass function, which required a reference to the Species vector. It computes the Par...
Definition: ParticleSpecies.cc:167
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:37
Definition: Vector.h:51
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:73
const Mdouble pi
Definition: ExtendedMath.h:45
bool isEqual(Mdouble v1, Mdouble v2, Mdouble absError)
Compares the difference of two Mdouble with an absolute error, useful in UnitTests.
Definition: ExtendedMath.cc:251

References ParticleSpecies::computeMass(), D, ERROR, INFO, mathsFunc::isEqual(), logger, Global_Physical_Variables::P, constants::pi, and ParticleSpecies::setDensity().

Referenced by main().

◆ test2()

void test2 ( )
Todo:
shouldn't this be default?
87 {
88  logger(INFO, "Test 2:\n"
89  "We apply a torque T around the z-axis to a motionless\n"
90  "particle of inertia I for a time t using a time step dt.\n"
91  "The result is a final angular velocity omega=inv(I)*T*t\n"
92  "and rotation angle alpha=inv(I)*T*t^2/2.\n"
93  "\n"
94  "The input/output values should be:\n"
95  " T = 0.1*pi*(0 0 1) Nm\n"
96  " I = 0.1*(2 0 0;0 2 0;0 0 1) kg m^2\n"
97  " t = 1 s\n"
98  " dt = 1e-5 s\n"
99  " omega=pi*(0 0 1) rad/s\n"
100  " alpha = pi/2*(0 0 1) rad\n");
101 
102  //compute mass (requires species and handler to be set)
103  DPMBase D;
104  LinearViscoelasticSpecies* S = D.speciesHandler.copyAndAddObject(LinearViscoelasticSpecies());
105  BaseParticle* P = D.particleHandler.copyAndAddObject(SphericalParticle(S));
106  D.setDimension(3);
107  S->setDensity(6.0 / constants::pi);
108  P->setRadius(0.5);
109  S->computeMass(P);
110  P->setInertia(MatrixSymmetric3D(2, 1, 0,
111  2, 0,
112  1) * 0.1);
113 
114  //std::cout << "P " << *P << std::endl;
115  P->setForce({1, 0, 0});
116  P->setTorque(0.1 * constants::pi * Vec3D(0, 0, 1));
117  Mdouble timeMax = 1.0;
118  Mdouble timeStep = 1e-5;
119  for (Mdouble time = 0; time < timeMax; time += timeStep)
120  {
121  P->accelerate(P->getForce() * P->getInvMass() * timeStep);
122  P->move(P->getVelocity() * timeStep);
123  P->angularAccelerate(
124  P->getOrientation().rotateInverseInertiaTensor(P->getInvInertia()) * P->getTorque() * timeStep);
125  P->rotate(P->getAngularVelocity() * timeStep);
126  }
127 
128  logger(INFO, "Results:\n"
129  " omega= %\n"
130  " alpha= %", P->getAngularVelocity(), P->getOrientation().getEuler());
131 
132  // std::cout << P->getAngularVelocity() - Vec3D(0,0,pi) << std::endl;
133  // std::cout << P->getOrientation().getEuler() - Vec3D(0,0,pi/2) << std::endl;
134 
135  //check results (with numerical error values added))
136  if (!mathsFunc::isEqual(P->getAngularVelocity(), Vec3D(0, 0, pi + 3.14159e-05), 1e-10))
137  {
138  logger(ERROR, "angular velocity is %, but should be %", P->getAngularVelocity(), pi / 2);
139  }
140  if (!mathsFunc::isEqual(P->getOrientation().getEuler(), {0, 0, pi / 2 + 4.71241e-05}, 1e-10))
141  {
142  logger(ERROR, "orientation is %, but should be %", P->getOrientation().getEuler().Z, pi / 2);
143  }
144 }
Implementation of a 3D symmetric matrix.
Definition: MatrixSymmetric.h:37

References ParticleSpecies::computeMass(), D, ERROR, INFO, mathsFunc::isEqual(), logger, Global_Physical_Variables::P, constants::pi, and ParticleSpecies::setDensity().

Referenced by main().