KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
quaternion.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Massimo Petracca
11 //
12 //
13 
14 #if !defined(QUATERNION_H_INCLUDED)
15 #define QUATERNION_H_INCLUDED
16 
18 #include "includes/serializer.h"
19 
20 namespace Kratos
21 {
22 
26  template<class T>
27  class Quaternion
28  {
29 
30  public:
31 
33 
34  typedef T value_type;
36  typedef value_type const& const_reference;
37 
40 
44  Quaternion() : mQuaternionValues(zero_vector<T>(4)) {
45  }
46 
54  Quaternion(T w, T x, T y, T z){
55  SetX(x);
56  SetY(y);
57  SetZ(z);
58  SetW(w);
59  }
60 
65  Quaternion(const Quaternion& other) : mQuaternionValues(other.mQuaternionValues) {
66  }
67 
69 
71  virtual ~Quaternion(){};
72 
73  public:
74 
77 
82  Quaternion& operator= (const Quaternion& other) {
83  if(this != &other) {
84  mQuaternionValues=other.mQuaternionValues;
85  }
86  return *this;
87  }
88 
89  const_reference operator [] (size_t i) const {
90  return mQuaternionValues[i];
91  }
92 
94  return mQuaternionValues[i];
95  }
96 
97  template<class AE>
98  BOOST_UBLAS_INLINE
99  Quaternion& operator = (const boost::numeric::ublas::vector_expression<AE> &ae)
100  {
101  SetX(ae()(0));
102  SetY(ae()(1));
103  SetZ(ae()(2));
104  SetW(ae()(3));
105 
106  return *this;
107  }
108 
110 
111  public:
112 
115 
120  KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T x()const { return mQuaternionValues[0]; }
121  inline const T X()const { return mQuaternionValues[0]; }
122  inline void SetX(const T& value) { mQuaternionValues[0] = value; }
123 
128  KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T y()const { return mQuaternionValues[1]; }
129  inline const T Y()const { return mQuaternionValues[1]; }
130  inline void SetY(const T& value) { mQuaternionValues[1] = value; }
131 
136  KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T z()const { return mQuaternionValues[2]; }
137  inline const T Z()const { return mQuaternionValues[2]; }
138  inline void SetZ(const T& value) { mQuaternionValues[2] = value; }
139 
144  KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T w()const { return mQuaternionValues[3]; }
145  inline const T W()const { return mQuaternionValues[3]; }
146  inline void SetW(const T& value) { mQuaternionValues[3] = value; }
147 
149 
150  public:
151 
154 
160  inline const T squaredNorm()const
161  {
162  return X()*X() + Y()*Y() + Z()*Z() + W()*W();
163  }
164 
170  inline const T norm()const
171  {
172  return std::sqrt( this->squaredNorm() );
173  }
174 
179  inline void normalize()
180  {
181  T n = this->squaredNorm();
182  if(n > 0.0 && n != 1.0) {
183  n = std::sqrt(n);
184  mQuaternionValues[0] /= n;
185  mQuaternionValues[1] /= n;
186  mQuaternionValues[2] /= n;
187  mQuaternionValues[3] /= n;
188  }
189  }
190 
195  inline Quaternion conjugate()const
196  {
197  return Quaternion(W(), -X(), -Y(), -Z());
198  }
199 
212  template<class TMatrix3x3>
213  inline void ToRotationMatrix(TMatrix3x3& R)const
214  {
215  if( R.size1()!=3 || R.size2()!=3 )
216  R.resize(3,3,false);
217 
218  R(0, 0) = 2.0 * ( W()*W() + X()*X() - 0.5 );
219  R(0, 1) = 2.0 * ( X()*Y() - W()*Z() );
220  R(0, 2) = 2.0 * ( X()*Z() + W()*Y() );
221 
222  R(1, 0) = 2.0 * ( Y()*X() + W()*Z() );
223  R(1, 1) = 2.0 * ( W()*W() + Y()*Y() - 0.5 );
224  R(1, 2) = 2.0 * ( Y()*Z() - X()*W() );
225 
226  R(2, 0) = 2.0 * ( Z()*X() - W()*Y() );
227  R(2, 1) = 2.0 * ( Z()*Y() + W()*X() );
228  R(2, 2) = 2.0 * ( W()*W() + Z()*Z() - 0.5 );
229  }
230 
236  inline void ToEulerAngles(array_1d<double, 3>& EA)const
237  {
238  double test = W() * W() - X() * X() - Y() * Y() + Z() * Z();
239  if (test > (1.0 - 1.0e-6)) { // singularity at north pole
240  EA[0] = -atan2 (2 * Z() * W(), (W() * W() - Z() * Z()));
241  EA[1] = 0.0;
242  EA[2] = 0.0;
243  }
244  else if (test < (-1.0 + 1.0e-6)) { // singularity at south pole
245  EA[0] = atan2 (2 * Z() * W(), (W() * W() - Z() * Z()));
246  EA[1] = Globals::Pi;
247  EA[2] = 0.0;
248  }
249  else {
250  EA[0] = atan2((X() * Z() + Y() * W()), -(Y() * Z() - X() * W()));
251  EA[1] = -acos (test);
252  EA[2] = atan2((X() * Z() - Y() * W()), (Y() * Z() + X() * W()));
253  }
254  }
255 
262  inline void ToRotationVector(T& rx, T& ry, T& rz)const
263  {
264  T xx, yy, zz, ww;
265 
266  if(W() < 0.0) {
267  xx = -X();
268  yy = -Y();
269  zz = -Z();
270  ww = -W();
271  }
272  else {
273  xx = X();
274  yy = Y();
275  zz = Z();
276  ww = W();
277  }
278 
279  T vNorm = xx*xx + yy*yy + zz*zz;
280  if(vNorm == 0.0) {
281  rx = 0.0;
282  ry = 0.0;
283  rz = 0.0;
284  return;
285  }
286 
287  if(vNorm != 1.0)
288  vNorm = std::sqrt(vNorm);
289 
290  T mult = (vNorm < ww) ? (2.0 / vNorm * std::asin(vNorm)) : (2.0 / vNorm * std::acos(ww));
291 
292  rx = xx * mult;
293  ry = yy * mult;
294  rz = zz * mult;
295  }
296 
305  template<class TVector3>
306  inline void ToRotationVector(TVector3& v)const {
307  if( v.size()!=3 )
308  v.resize(3);
309 
310  this->ToRotationVector(v(0), v(1), v(2));
311  }
312 
324  template<class TVector3_A, class TVector3_B>
325  inline void RotateVector3(const TVector3_A& a, TVector3_B& b)const
326  {
327  // b = 2.0 * cross( this->VectorialPart, a )
328  b(0) = 2.0 * (Y() * a(2) - Z() * a(1));
329  b(1) = 2.0 * (Z() * a(0) - X() * a(2));
330  b(2) = 2.0 * (X() * a(1) - Y() * a(0));
331 
332  // c = cross( this->VectorialPart, b )
333  T c0 = Y() * b(2) - Z() * b(1);
334  T c1 = Z() * b(0) - X() * b(2);
335  T c2 = X() * b(1) - Y() * b(0);
336 
337  // set results
338  b(0) = a(0) + b(0)*W() + c0;
339  b(1) = a(1) + b(1)*W() + c1;
340  b(2) = a(2) + b(2)*W() + c2;
341  }
342 
353  template<class TVector3>
354  inline void RotateVector3(TVector3& a)const
355  {
356  // b = 2.0 * cross( this->VectorialPart, a )
357  T b0 = 2.0 * (Y() * a(2) - Z() * a(1));
358  T b1 = 2.0 * (Z() * a(0) - X() * a(2));
359  T b2 = 2.0 * (X() * a(1) - Y() * a(0));
360 
361  // c = cross( this->VectorialPart, b )
362  T c0 = Y() * b2 - Z() * b1;
363  T c1 = Z() * b0 - X() * b2;
364  T c2 = X() * b1 - Y() * b0;
365 
366  // set results
367  a(0) += b0*W() + c0;
368  a(1) += b1*W() + c1;
369  a(2) += b2*W() + c2;
370  }
371 
373 
374  public:
375 
378 
383  static inline Quaternion Identity()
384  {
385  return Quaternion(1.0, 0.0, 0.0, 0.0);
386  }
387 
396  static inline Quaternion FromAxisAngle(T x, T y, T z, T radians)
397  {
398  T sqnorm = x*x + y*y + z*z;
399  if (sqnorm == 0.0)
400  return Quaternion::Identity();
401 
402  if(sqnorm != 1.0) {
403  T norm = std::sqrt(sqnorm);
404  x /= norm;
405  y /= norm;
406  z /= norm;
407  }
408 
409  T halfAngle = radians * 0.5;
410 
411  T s = std::sin(halfAngle);
412  T q0 = std::cos(halfAngle);
413 
414  Quaternion result(q0, s*x, s*y, s*z);
415  result.normalize();
416 
417  return result;
418  }
419 
427  static inline Quaternion FromRotationVector(T rx, T ry, T rz)
428  {
429  T rModulus = rx*rx + ry*ry + rz*rz;
430  if(rModulus == 0.0)
431  return Quaternion::Identity();
432 
433  if(rModulus != 1.0) {
434  rModulus = std::sqrt(rModulus);
435  rx /= rModulus;
436  ry /= rModulus;
437  rz /= rModulus;
438  }
439 
440  T halfAngle = rModulus * 0.5;
441 
442  T q0 = std::cos(halfAngle);
443  T s = std::sin(halfAngle);
444 
445  return Quaternion(q0, rx*s, ry*s, rz*s);
446  }
447 
457  template<class TVector3>
458  static inline Quaternion FromRotationVector(const TVector3& v)
459  {
460  return Quaternion::FromRotationVector(v(0), v(1), v(2));
461  }
462 
474  template<class TMatrix3x3>
475  static inline Quaternion FromRotationMatrix(const TMatrix3x3 & m)
476  {
477  T xx = m(0, 0);
478  T yy = m(1, 1);
479  T zz = m(2, 2);
480  T tr = xx + yy + zz;
481  Quaternion Q;
482  if ((tr > xx) && (tr > yy) && (tr > zz))
483  {
484  T S = std::sqrt(tr + 1.0) * 2.0;
485  Q = Quaternion(
486  0.25 * S,
487  (m(2, 1) - m(1, 2)) / S,
488  (m(0, 2) - m(2, 0)) / S,
489  (m(1, 0) - m(0, 1)) / S
490  );
491  }
492  else if ((xx > yy) && (xx > zz))
493  {
494  T S = std::sqrt(1.0 + xx - yy - zz) * 2.0;
495  Q = Quaternion(
496  (m(2, 1) - m(1, 2)) / S,
497  0.25 * S,
498  (m(0, 1) + m(1, 0)) / S,
499  (m(0, 2) + m(2, 0)) / S
500  );
501  }
502  else if (yy > zz)
503  {
504  T S = std::sqrt(1.0 + yy - xx - zz) * 2.0;
505  Q = Quaternion(
506  (m(0, 2) - m(2, 0)) / S,
507  (m(0, 1) + m(1, 0)) / S,
508  0.25 * S,
509  (m(1, 2) + m(2, 1)) / S
510  );
511  }
512  else
513  {
514  T S = std::sqrt(1.0 + zz - xx - yy) * 2.0;
515  Q = Quaternion(
516  (m(1, 0) - m(0, 1)) / S,
517  (m(0, 2) + m(2, 0)) / S,
518  (m(1, 2) + m(2, 1)) / S,
519  0.25 * S
520  );
521  }
522 
523 
524  Q.normalize();
525  return Q;
526  }
527 
535  {
536  Quaternion Q;
537  double c2 = cos(-EA[1]/2); double c1p3 = cos((EA[0]+EA[2])/2); double c1m3 = cos((EA[0]-EA[2])/2);
538  double s2 = sin(-EA[1]/2); double s1p3 = sin((EA[0]+EA[2])/2); double s1m3 = sin((EA[0]-EA[2])/2);
539 
540  Q = Quaternion(
541  c2 * c1p3,
542  s2 * c1m3,
543  s2 * s1m3,
544  c2 * s1p3);
545  Q.normalize();
546  return Q;
547  }
548 
550  virtual void PrintInfo(std::ostream& rOStream) const {
551  rOStream << Info();
552  }
553 
555  virtual void PrintData(std::ostream& rOStream) const {
556  rOStream << std::endl << this->X() <<" " << this->Y() << " " << this->Z() << " " <<this->W()<< std::endl;
557  }
558 
559  private:
560 
563 
564  array_1d<T,4> mQuaternionValues;
565 
567 
570 
571  friend class Serializer;
572 
573  void save(Serializer& rSerializer) const
574  {
575  rSerializer.save("mQuaternionValues", mQuaternionValues);
576  }
577 
578  void load(Serializer& rSerializer)
579  {
580  rSerializer.load("mQuaternionValues", mQuaternionValues);
581  }
582 
583  virtual std::string Info() const {
584  std::stringstream buffer;
585  buffer << "Quaternion " ;
586  return buffer.str();
587  }
588 
589  };
590 
598  template<class T>
600  {
601  return Quaternion<T>(
602  a.W() * b.W() - a.X() * b.X() - a.Y() * b.Y() - a.Z() * b.Z(),
603  a.W() * b.X() + a.X() * b.W() + a.Y() * b.Z() - a.Z() * b.Y(),
604  a.W() * b.Y() + a.Y() * b.W() + a.Z() * b.X() - a.X() * b.Z(),
605  a.W() * b.Z() + a.Z() * b.W() + a.X() * b.Y() - a.Y() * b.X()
606  );
607  }
608 
609 
610  template<class T>
611  inline std::istream& operator >> (std::istream& rIStream, Quaternion<T>& rThis);
612 
613  template<class T>
614  inline std::ostream& operator << (std::ostream& rOStream, const Quaternion<T>& rThis)
615  {
616  rThis.PrintInfo(rOStream);
617  rOStream << " : ";
618  rThis.PrintData(rOStream);
619 
620  return rOStream;
621  }
622 
623 } // namespace Kratos
624 
625 #endif // QUATERNION_H_INCLUDED
std::string Info() const override
Turn back information as a string.
Definition: periodic_interface_process.hpp:93
Quaternion A simple class that implements the main features of quaternion algebra.
Definition: quaternion.h:28
KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T x() const
Definition: quaternion.h:120
void SetX(const T &value)
Definition: quaternion.h:122
T value_type
Definition: quaternion.h:34
static Quaternion Identity()
Definition: quaternion.h:383
const T norm() const
Definition: quaternion.h:170
void SetZ(const T &value)
Definition: quaternion.h:138
static Quaternion FromRotationMatrix(const TMatrix3x3 &m)
Definition: quaternion.h:475
void ToRotationVector(TVector3 &v) const
Definition: quaternion.h:306
static Quaternion FromRotationVector(const TVector3 &v)
Definition: quaternion.h:458
void normalize()
Definition: quaternion.h:179
Quaternion()
Definition: quaternion.h:44
void SetW(const T &value)
Definition: quaternion.h:146
void ToRotationMatrix(TMatrix3x3 &R) const
Definition: quaternion.h:213
Quaternion(T w, T x, T y, T z)
Definition: quaternion.h:54
KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T w() const
Definition: quaternion.h:144
const T W() const
Definition: quaternion.h:145
void SetY(const T &value)
Definition: quaternion.h:130
static Quaternion FromEulerAngles(const array_1d< double, 3 > &EA)
Definition: quaternion.h:534
KRATOS_CLASS_POINTER_DEFINITION(Quaternion)
KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T z() const
Definition: quaternion.h:136
Quaternion & operator=(const Quaternion &other)
Definition: quaternion.h:82
const T Y() const
Definition: quaternion.h:129
Quaternion(const Quaternion &other)
Definition: quaternion.h:65
void ToRotationVector(T &rx, T &ry, T &rz) const
Definition: quaternion.h:262
void ToEulerAngles(array_1d< double, 3 > &EA) const
Definition: quaternion.h:236
void RotateVector3(const TVector3_A &a, TVector3_B &b) const
Definition: quaternion.h:325
value_type const & const_reference
Definition: quaternion.h:36
virtual ~Quaternion()
Destructor.
Definition: quaternion.h:71
const T X() const
Definition: quaternion.h:121
const_reference operator[](size_t i) const
Definition: quaternion.h:89
const T Z() const
Definition: quaternion.h:137
void RotateVector3(TVector3 &a) const
Definition: quaternion.h:354
virtual void PrintInfo(std::ostream &rOStream) const
Definition: quaternion.h:550
value_type & reference
Definition: quaternion.h:35
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: quaternion.h:555
KRATOS_DEPRECATED_MESSAGE("Deprecated method due to style") inline const T y() const
Definition: quaternion.h:128
const T squaredNorm() const
Definition: quaternion.h:160
static Quaternion FromRotationVector(T rx, T ry, T rz)
Definition: quaternion.h:427
static Quaternion FromAxisAngle(T x, T y, T z, T radians)
Definition: quaternion.h:396
Quaternion conjugate() const
Definition: quaternion.h:195
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
void load(std::string const &rTag, TDataType &rObject)
Definition: serializer.h:207
void save(std::string const &rTag, std::array< TDataType, TDataSize > const &rObject)
Definition: serializer.h:545
z
Definition: GenerateWind.py:163
constexpr double Pi
Definition: global_variables.h:25
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
Expression::Pointer operator*(const Expression::ConstPointer &rpLeft, const double Right)
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
y
Other simbols definition.
Definition: generate_axisymmetric_navier_stokes_element.py:54
v
Definition: generate_convection_diffusion_explicit_element.py:114
w
Definition: generate_convection_diffusion_explicit_element.py:108
a
Definition: generate_stokes_twofluid_element.py:77
S
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:39
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
R
Definition: isotropic_damage_automatic_differentiation.py:172
tuple Q
Definition: isotropic_damage_automatic_differentiation.py:235
def load(f)
Definition: ode_solve.py:307
tuple const
Definition: ode_solve.py:403
def mult(A, x)
Definition: ode_solve.py:320
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
test
Definition: run_make_mesh_ethier_benchmark.py:26
int m
Definition: run_marine_rain_substepping.py:8
x
Definition: sensitivityMatrix.py:49
integer i
Definition: TensorModule.f:17