Loading...
Searching...
No Matches
quaternionI.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2019-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30
32:
33 w_(0),
34 v_(Zero)
35{}
36
37
38inline Foam::quaternion::quaternion(const scalar w, const vector& v)
39:
40 w_(w),
41 v_(v)
42{}
43
44
45inline Foam::quaternion::quaternion(const vector& d, const scalar theta)
46:
47 w_(cos(0.5*theta)),
48 v_(sin(0.5*theta)*Foam::normalised(d))
49{}
50
51
53(
54 const vector& d,
55 const scalar cosTheta,
56 const bool isNormalised
57)
58{
59 const scalar cosHalfTheta2 = 0.5*(cosTheta + 1);
60 w_ = sqrt(cosHalfTheta2);
61
62 if (isNormalised)
63 {
64 v_ = sqrt(1 - cosHalfTheta2)*d;
65 }
66 else
67 {
68 v_ = sqrt(1 - cosHalfTheta2)*Foam::normalised(d);
69 }
70}
71
72
73inline Foam::quaternion::quaternion(const scalar w)
74:
75 w_(w),
76 v_(Zero)
77{}
78
79
81:
82 w_(0),
83 v_(v)
84{}
85
88{
89 return quaternion(sqrt(1 - magSqr(v)), v);
90}
91
92
94(
95 const eulerOrder order,
96 const vector& angles
97)
98{
99 switch (order)
100 {
101 case ZYX:
102 {
103 operator=(quaternion(vector(0, 0, 1), angles.x()));
104 operator*=(quaternion(vector(0, 1, 0), angles.y()));
105 operator*=(quaternion(vector(1, 0, 0), angles.z()));
106 break;
107 }
108
109 case ZYZ:
110 {
111 operator=(quaternion(vector(0, 0, 1), angles.x()));
112 operator*=(quaternion(vector(0, 1, 0), angles.y()));
113 operator*=(quaternion(vector(0, 0, 1), angles.z()));
114 break;
115 }
116
117 case ZXY:
118 {
119 operator=(quaternion(vector(0, 0, 1), angles.x()));
120 operator*=(quaternion(vector(1, 0, 0), angles.y()));
121 operator*=(quaternion(vector(0, 1, 0), angles.z()));
122 break;
123 }
124
125 case ZXZ:
126 {
127 operator=(quaternion(vector(0, 0, 1), angles.x()));
128 operator*=(quaternion(vector(1, 0, 0), angles.y()));
129 operator*=(quaternion(vector(0, 0, 1), angles.z()));
130 break;
131 }
132
133 case YXZ:
134 {
135 operator=(quaternion(vector(0, 1, 0), angles.x()));
136 operator*=(quaternion(vector(1, 0, 0), angles.y()));
137 operator*=(quaternion(vector(0, 0, 1), angles.z()));
138 break;
139 }
140
141 case YXY:
142 {
143 operator=(quaternion(vector(0, 1, 0), angles.x()));
144 operator*=(quaternion(vector(1, 0, 0), angles.y()));
145 operator*=(quaternion(vector(0, 1, 0), angles.z()));
146 break;
147 }
148
149 case YZX:
150 {
151 operator=(quaternion(vector(0, 1, 0), angles.x()));
152 operator*=(quaternion(vector(0, 0, 1), angles.y()));
153 operator*=(quaternion(vector(1, 0, 0), angles.z()));
154 break;
155 }
156
157 case YZY:
158 {
159 operator=(quaternion(vector(0, 1, 0), angles.x()));
160 operator*=(quaternion(vector(0, 0, 1), angles.y()));
161 operator*=(quaternion(vector(0, 1, 0), angles.z()));
162 break;
163 }
164
165 case XYZ:
166 {
167 operator=(quaternion(vector(1, 0, 0), angles.x()));
168 operator*=(quaternion(vector(0, 1, 0), angles.y()));
169 operator*=(quaternion(vector(0, 0, 1), angles.z()));
170 break;
171 }
172
173 case XYX:
174 {
175 operator=(quaternion(vector(1, 0, 0), angles.x()));
176 operator*=(quaternion(vector(0, 1, 0), angles.y()));
177 operator*=(quaternion(vector(1, 0, 0), angles.z()));
178 break;
179 }
180
181 case XZY:
182 {
183 operator=(quaternion(vector(1, 0, 0), angles.x()));
184 operator*=(quaternion(vector(0, 0, 1), angles.y()));
185 operator*=(quaternion(vector(0, 1, 0), angles.z()));
186 break;
187 }
188
189 case XZX:
190 {
191 operator=(quaternion(vector(1, 0, 0), angles.x()));
192 operator*=(quaternion(vector(0, 0, 1), angles.y()));
193 operator*=(quaternion(vector(1, 0, 0), angles.z()));
194 break;
195 }
196
197 default:
199 << "Unknown euler rotation order "
200 << int(order) << abort(FatalError);
201 break;
202 }
203}
204
205
207(
209)
210{
211 scalar trace =
214 + rotationTensor.zz();
215
216 if (trace > 0)
217 {
218 scalar s = 0.5/Foam::sqrt(trace + 1.0);
219
220 w_ = 0.25/s;
221 v_[0] = (rotationTensor.zy() - rotationTensor.yz())*s;
222 v_[1] = (rotationTensor.xz() - rotationTensor.zx())*s;
223 v_[2] = (rotationTensor.yx() - rotationTensor.xy())*s;
224 }
225 else
226 {
227 if
228 (
230 && rotationTensor.xx() > rotationTensor.zz()
231 )
232 {
233 const scalar s = 2.0*Foam::sqrt
234 (
235 1.0
236 + rotationTensor.xx()
237 - rotationTensor.yy()
238 - rotationTensor.zz()
239 );
240
241 w_ = (rotationTensor.zy() - rotationTensor.yz())/s;
242 v_[0] = 0.25*s;
243 v_[1] = (rotationTensor.xy() + rotationTensor.yx())/s;
244 v_[2] = (rotationTensor.xz() + rotationTensor.zx())/s;
245 }
246 else if
247 (
249 )
250 {
251 const scalar s = 2.0*Foam::sqrt
252 (
253 1.0
254 + rotationTensor.yy()
255 - rotationTensor.xx()
256 - rotationTensor.zz()
257 );
258
259 w_ = (rotationTensor.xz() - rotationTensor.zx())/s;
260 v_[0] = (rotationTensor.xy() + rotationTensor.yx())/s;
261 v_[1] = 0.25*s;
262 v_[2] = (rotationTensor.yz() + rotationTensor.zy())/s;
263 }
264 else
265 {
266 const scalar s = 2.0*Foam::sqrt
267 (
268 1.0
269 + rotationTensor.zz()
270 - rotationTensor.xx()
271 - rotationTensor.yy()
272 );
273
274 w_ = (rotationTensor.yx() - rotationTensor.xy())/s;
275 v_[0] = (rotationTensor.xz() + rotationTensor.zx())/s;
276 v_[1] = (rotationTensor.yz() + rotationTensor.zy())/s;
277 v_[2] = 0.25*s;
279 }
280}
281
282
283// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
285inline Foam::scalar Foam::quaternion::w() const noexcept
286{
287 return w_;
288}
289
291inline const Foam::vector& Foam::quaternion::v() const noexcept
292{
293 return v_;
294}
295
297inline Foam::scalar& Foam::quaternion::w() noexcept
298{
299 return w_;
300}
301
304{
305 return v_;
306}
307
308
309inline Foam::quaternion& Foam::quaternion::normalise(const scalar tol)
310{
311 // TBD: Use volatile to avoid aggressive branch optimization
312 const scalar s(Foam::mag(*this));
313
314 if (s < tol)
315 {
316 *this = Foam::zero{};
317 }
318 else
319 {
320 *this /= s;
321 }
322 return *this;
323}
324
326inline Foam::quaternion Foam::quaternion::mulq0v(const vector& u) const
327{
328 return quaternion(-(v() & u), w()*u + (v() ^ u));
329}
330
333{
334 return (mulq0v(u)*conjugate(*this)).v();
335}
336
339{
340 return (conjugate(*this).mulq0v(u)*(*this)).v();
341}
342
345{
346 return Foam::normalised((*this)*q);
347}
348
349
351(
352 const quaternion& q
353) const
354{
355 return Foam::normalised(conjugate(*this)*q);
356}
357
358
360{
361 const scalar w2 = sqr(w());
362 const scalar x2 = sqr(v().x());
363 const scalar y2 = sqr(v().y());
364 const scalar z2 = sqr(v().z());
365
366 const scalar txy = 2*v().x()*v().y();
367 const scalar twz = 2*w()*v().z();
368 const scalar txz = 2*v().x()*v().z();
369 const scalar twy = 2*w()*v().y();
370 const scalar tyz = 2*v().y()*v().z();
371 const scalar twx = 2*w()*v().x();
372
373 return tensor
374 (
375 w2 + x2 - y2 - z2, txy - twz, txz + twy,
376 txy + twz, w2 - x2 + y2 - z2, tyz - twx,
377 txz - twy, tyz + twx, w2 - x2 - y2 + z2
378 );
379}
380
381
382inline Foam::vector Foam::quaternion::twoAxes
383(
384 const scalar t11,
385 const scalar t12,
386 const scalar c2,
387 const scalar t31,
388 const scalar t32
389)
390{
391 return vector(atan2(t11, t12), acos(c2), atan2(t31, t32));
392}
393
394
395inline Foam::vector Foam::quaternion::threeAxes
396(
397 const scalar t11,
398 const scalar t12,
399 const scalar s2,
400 const scalar t31,
401 const scalar t32
402)
403{
404 return vector(atan2(t11, t12), asin(s2), atan2(t31, t32));
405}
406
407
409(
410 const eulerOrder order
411) const
412{
413 const scalar w2 = sqr(w());
414 const scalar x2 = sqr(v().x());
415 const scalar y2 = sqr(v().y());
416 const scalar z2 = sqr(v().z());
417
418 switch (order)
419 {
420 case ZYX:
421 {
422 return threeAxes
423 (
424 2*(v().x()*v().y() + w()*v().z()),
425 w2 + x2 - y2 - z2,
426 2*(w()*v().y() - v().x()*v().z()),
427 2*(v().y()*v().z() + w()*v().x()),
428 w2 - x2 - y2 + z2
429 );
430 break;
431 }
432
433 case ZYZ:
434 {
435 return twoAxes
436 (
437 2*(v().y()*v().z() - w()*v().x()),
438 2*(v().x()*v().z() + w()*v().y()),
439 w2 - x2 - y2 + z2,
440 2*(v().y()*v().z() + w()*v().x()),
441 2*(w()*v().y() - v().x()*v().z())
442 );
443 break;
444 }
445
446 case ZXY:
447 {
448 return threeAxes
449 (
450 2*(w()*v().z() - v().x()*v().y()),
451 w2 - x2 + y2 - z2,
452 2*(v().y()*v().z() + w()*v().x()),
453 2*(w()*v().y() - v().x()*v().z()),
454 w2 - x2 - y2 + z2
455 );
456 break;
457 }
458
459 case ZXZ:
460 {
461 return twoAxes
462 (
463 2*(v().x()*v().z() + w()*v().y()),
464 2*(w()*v().x() - v().y()*v().z()),
465 w2 - x2 - y2 + z2,
466 2*(v().x()*v().z() - w()*v().y()),
467 2*(v().y()*v().z() + w()*v().x())
468 );
469 break;
470 }
471
472 case YXZ:
473 {
474 return threeAxes
475 (
476 2*(v().x()*v().z() + w()*v().y()),
477 w2 - x2 - y2 + z2,
478 2*(w()*v().x() - v().y()*v().z()),
479 2*(v().x()*v().y() + w()*v().z()),
480 w2 - x2 + y2 - z2
481 );
482 break;
483 }
484
485 case YXY:
486 {
487 return twoAxes
488 (
489 2*(v().x()*v().y() - w()*v().z()),
490 2*(v().y()*v().z() + w()*v().x()),
491 w2 - x2 + y2 - z2,
492 2*(v().x()*v().y() + w()*v().z()),
493 2*(w()*v().x() - v().y()*v().z())
494 );
495 break;
496 }
497
498 case YZX:
499 {
500 return threeAxes
501 (
502 2*(w()*v().y() - v().x()*v().z()),
503 w2 + x2 - y2 - z2,
504 2*(v().x()*v().y() + w()*v().z()),
505 2*(w()*v().x() - v().y()*v().z()),
506 w2 - x2 + y2 - z2
507 );
508 break;
509 }
510
511 case YZY:
512 {
513 return twoAxes
514 (
515 2*(v().y()*v().z() + w()*v().x()),
516 2*(w()*v().z() - v().x()*v().y()),
517 w2 - x2 + y2 - z2,
518 2*(v().y()*v().z() - w()*v().x()),
519 2*(v().x()*v().y() + w()*v().z())
520 );
521 break;
522 }
523
524 case XYZ:
525 {
526 return threeAxes
527 (
528 2*(w()*v().x() - v().y()*v().z()),
529 w2 - x2 - y2 + z2,
530 2*(v().x()*v().z() + w()*v().y()),
531 2*(w()*v().z() - v().x()*v().y()),
532 w2 + x2 - y2 - z2
533 );
534 break;
535 }
536
537 case XYX:
538 {
539 return twoAxes
540 (
541 2*(v().x()*v().y() + w()*v().z()),
542 2*(w()*v().y() - v().x()*v().z()),
543 w2 + x2 - y2 - z2,
544 2*(v().x()*v().y() - w()*v().z()),
545 2*(v().x()*v().z() + w()*v().y())
546 );
547 break;
548 }
549
550 case XZY:
551 {
552 return threeAxes
553 (
554 2*(v().y()*v().z() + w()*v().x()),
555 w2 - x2 + y2 - z2,
556 2*(w()*v().z() - v().x()*v().y()),
557 2*(v().x()*v().z() + w()*v().y()),
558 w2 + x2 - y2 - z2
559 );
560 break;
561 }
562
563 case XZX:
564 {
565 return twoAxes
566 (
567 2*(v().x()*v().z() - w()*v().y()),
568 2*(v().x()*v().y() + w()*v().z()),
569 w2 + x2 - y2 - z2,
570 2*(v().x()*v().z() + w()*v().y()),
571 2*(w()*v().z() - v().x()*v().y())
572 );
573 break;
574 }
575
576 default:
578 << "Unknown euler rotation order "
579 << int(order) << abort(FatalError);
580 break;
581 }
583 return Zero;
584}
585
586
587// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
589inline void Foam::quaternion::operator+=(const quaternion& q)
590{
591 w_ += q.w_;
592 v_ += q.v_;
593}
595inline void Foam::quaternion::operator-=(const quaternion& q)
596{
597 w_ -= q.w_;
598 v_ -= q.v_;
599}
600
602{
603 scalar w0 = w();
604 w() = w()*q.w() - (v() & q.v());
605 v() = w0*q.v() + q.w()*v() + (v() ^ q.v());
606}
608inline void Foam::quaternion::operator/=(const quaternion& q)
609{
610 return operator*=(inv(q));
611}
612
614inline void Foam::quaternion::operator=(const scalar s)
615{
616 w_ = s;
617}
618
620inline void Foam::quaternion::operator=(const vector& v)
621{
622 v_ = v;
623}
624
625
627{
628 w_ = 0;
629 v_ = Zero;
630}
631
633inline void Foam::quaternion::operator*=(const scalar s)
634{
635 w_ *= s;
636 v_ *= s;
637}
638
639inline void Foam::quaternion::operator/=(const scalar s)
640{
641 w_ /= s;
642 v_ /= s;
643}
644
645
646// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
648inline Foam::scalar Foam::magSqr(const quaternion& q)
649{
650 return magSqr(q.w()) + magSqr(q.v());
651}
652
654inline Foam::scalar Foam::mag(const quaternion& q)
655{
656 return sqrt(magSqr(q));
657}
658
661{
662 return quaternion(q.w(), -q.v());
663}
664
665
666inline Foam::quaternion Foam::inv(const quaternion& q)
667{
668 const scalar s(Foam::magSqr(q));
669
670 if (s < VSMALL)
671 {
672 return Zero;
673 }
674 else
675 {
676 return quaternion(q.w()/s, -q.v()/s);
677 }
678}
679
680
681inline Foam::quaternion Foam::normalised(const quaternion& q)
682{
683 const scalar s(Foam::mag(q));
684
685 if (s < ROOTVSMALL)
686 {
687 return Zero;
688 }
689 else
690 {
691 return q/s;
692 }
693}
694
695
696// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
698inline bool Foam::operator==(const quaternion& q1, const quaternion& q2)
699{
700 return (equal(q1.w(), q2.w()) && equal(q1.v(), q2.v()));
701}
702
704inline bool Foam::operator!=(const quaternion& q1, const quaternion& q2)
705{
706 return !operator==(q1, q2);
707}
708
709
710inline Foam::quaternion Foam::operator+
711(
712 const quaternion& q1,
713 const quaternion& q2
714)
715{
716 return quaternion(q1.w() + q2.w(), q1.v() + q2.v());
717}
718
721{
722 return quaternion(-q.w(), -q.v());
723}
724
725
726inline Foam::quaternion Foam::operator-
727(
728 const quaternion& q1,
729 const quaternion& q2
730)
731{
732 return quaternion(q1.w() - q2.w(), q1.v() - q2.v());
733}
734
736inline Foam::scalar Foam::operator&(const quaternion& q1, const quaternion& q2)
737{
738 return q1.w()*q2.w() + (q1.v() & q2.v());
739}
740
741
742inline Foam::quaternion Foam::operator*
743(
744 const quaternion& q1,
745 const quaternion& q2
746)
747{
748 return quaternion
750 q1.w()*q2.w() - (q1.v() & q2.v()),
751 q1.w()*q2.v() + q2.w()*q1.v() + (q1.v() ^ q2.v())
752 );
753}
754
755
756inline Foam::quaternion Foam::operator/
757(
758 const quaternion& q1,
759 const quaternion& q2
760)
761{
762 return q1*inv(q2);
763}
764
766inline Foam::quaternion Foam::operator*(const scalar s, const quaternion& q)
767{
768 return quaternion(s*q.w(), s*q.v());
769}
770
772inline Foam::quaternion Foam::operator*(const quaternion& q, const scalar s)
773{
774 return quaternion(s*q.w(), s*q.v());
775}
776
777
778inline Foam::quaternion Foam::operator/(const quaternion& q, const scalar s)
779{
780 return quaternion(q.w()/s, q.v()/s);
781}
782
783
784// ************************************************************************* //
scalar y
#define w2
Definition blockCreate.C:28
#define w0
Definition blockCreate.C:26
const Cmpt & yy() const noexcept
Definition Tensor.H:197
const Cmpt & zy() const noexcept
Definition Tensor.H:200
const Cmpt & yx() const noexcept
Definition Tensor.H:196
const Cmpt & xx() const noexcept
Definition Tensor.H:193
const Cmpt & yz() const noexcept
Definition Tensor.H:198
const Cmpt & zz() const noexcept
Definition Tensor.H:201
const Cmpt & xy() const noexcept
Definition Tensor.H:194
const Cmpt & xz() const noexcept
Definition Tensor.H:195
const Cmpt & zx() const noexcept
Definition Tensor.H:199
const Cmpt & x() const noexcept
Access to the vector x component.
Definition Vector.H:135
const Cmpt & z() const noexcept
Access to the vector z component.
Definition Vector.H:145
const Cmpt & y() const noexcept
Access to the vector y component.
Definition Vector.H:140
Quaternion class used to perform rotations in 3D space.
Definition quaternion.H:54
void operator/=(const quaternion &q)
quaternion & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the quaternion by its magnitude.
vector eulerAngles(const eulerOrder order) const
Return the Euler rotation angles corresponding to the specified rotation order.
const vector & v() const noexcept
Vector part of the quaternion ( = axis of rotation).
tensor R() const
The rotation tensor corresponding to the quaternion.
void operator-=(const quaternion &q)
static quaternion unit(const vector &v)
Return the unit quaternion (versor) from the given vector (w = sqrt(1 - |sqr(v)|)).
Definition quaternionI.H:80
void operator+=(const quaternion &q)
void operator*=(const quaternion &q)
scalar w() const noexcept
Scalar part of the quaternion ( = cos(theta/2) for rotation).
quaternion & operator=(const quaternion &)=default
Copy assignment.
vector transform(const vector &v) const
Rotate the given vector.
quaternion()=default
Default construct.
eulerOrder
Euler-angle rotation order.
Definition quaternion.H:116
vector invTransform(const vector &v) const
Rotate the given vector anti-clockwise.
Tensor of scalars, i.e. Tensor<scalar>.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Namespace for OpenFOAM.
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
bool operator!=(const eddy &a, const eddy &b)
Definition eddy.H:297
dimensionedScalar asin(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
Definition transform.H:47
dimensionedScalar sin(const dimensionedScalar &ds)
bool equal(const T &a, const T &b)
Compare two values for equality.
Definition label.H:180
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
Tensor< scalar > tensor
Definition symmTensor.H:57
dimensionedScalar operator/(const scalar s1, const dimensionedScalar &ds2)
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
dimensionedScalar sqrt(const dimensionedScalar &ds)
tmp< GeometricField< Type, faPatchField, areaMesh > > operator&(const faMatrix< Type > &, const DimensionedField< Type, areaMesh > &)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition errorManip.H:139
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
quaternion conjugate(const quaternion &q)
Return the conjugate of the given quaternion.
Vector< scalar > vector
Definition vector.H:57
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)