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 -------------------------------------------------------------------------------
11 License
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 
38 inline Foam::quaternion::quaternion(const scalar w, const vector& v)
39 :
40  w_(w),
41  v_(v)
42 {}
43 
44 
45 inline 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 
73 inline 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 
86 
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 (
208  const tensor& rotationTensor
209 )
210 {
211  scalar trace =
212  rotationTensor.xx()
213  + rotationTensor.yy()
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  (
229  rotationTensor.xx() > rotationTensor.yy()
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  (
248  rotationTensor.yy() > rotationTensor.zz()
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;
278  }
279  }
280 }
281 
282 
283 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
285 inline Foam::scalar Foam::quaternion::w() const noexcept
286 {
287  return w_;
288 }
289 
291 inline const Foam::vector& Foam::quaternion::v() const noexcept
292 {
293  return v_;
294 }
295 
297 inline Foam::scalar& Foam::quaternion::w() noexcept
298 {
299  return w_;
300 }
301 
304 {
305  return v_;
306 }
307 
308 
309 inline 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 
326 inline Foam::quaternion Foam::quaternion::mulq0v(const vector& u) const
327 {
328  return quaternion(-(v() & u), w()*u + (v() ^ u));
329 }
330 
332 inline Foam::vector Foam::quaternion::transform(const vector& u) const
333 {
334  return (mulq0v(u)*conjugate(*this)).v();
335 }
336 
339 {
340  return (conjugate(*this).mulq0v(u)*(*this)).v();
341 }
342 
343 
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 
359 inline Foam::tensor Foam::quaternion::R() const
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 
382 inline 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 
395 inline 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 * * * * * * * * * * * * * //
589 inline void Foam::quaternion::operator+=(const quaternion& q)
590 {
591  w_ += q.w_;
592  v_ += q.v_;
593 }
595 inline 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 }
608 inline void Foam::quaternion::operator/=(const quaternion& q)
609 {
610  return operator*=(inv(q));
611 }
612 
614 inline void Foam::quaternion::operator=(const scalar s)
615 {
616  w_ = s;
617 }
618 
620 inline void Foam::quaternion::operator=(const vector& v)
621 {
622  v_ = v;
623 }
624 
625 
627 {
628  w_ = 0;
629  v_ = Zero;
630 }
631 
633 inline void Foam::quaternion::operator*=(const scalar s)
634 {
635  w_ *= s;
636  v_ *= s;
637 }
638 
639 inline void Foam::quaternion::operator/=(const scalar s)
640 {
641  w_ /= s;
642  v_ /= s;
643 }
644 
645 
646 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
648 inline Foam::scalar Foam::magSqr(const quaternion& q)
649 {
650  return magSqr(q.w()) + magSqr(q.v());
651 }
652 
654 inline 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 
666 inline 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 
681 inline 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 * * * * * * * * * * * * * //
698 inline bool Foam::operator==(const quaternion& q1, const quaternion& q2)
699 {
700  return (equal(q1.w(), q2.w()) && equal(q1.v(), q2.v()));
701 }
702 
703 
704 inline bool Foam::operator!=(const quaternion& q1, const quaternion& q2)
705 {
706  return !operator==(q1, q2);
707 }
708 
709 
710 inline 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 
719 
721 {
722  return quaternion(-q.w(), -q.v());
723 }
724 
725 
726 inline 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 
735 
736 inline Foam::scalar Foam::operator&(const quaternion& q1, const quaternion& q2)
737 {
738  return q1.w()*q2.w() + (q1.v() & q2.v());
739 }
740 
741 
742 inline Foam::quaternion Foam::operator*
743 (
744  const quaternion& q1,
745  const quaternion& q2
746 )
747 {
748  return quaternion
749  (
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 
756 inline Foam::quaternion Foam::operator/
757 (
758  const quaternion& q1,
759  const quaternion& q2
760 )
761 {
762  return q1*inv(q2);
763 }
764 
766 inline Foam::quaternion Foam::operator*(const scalar s, const quaternion& q)
767 {
768  return quaternion(s*q.w(), s*q.v());
769 }
770 
772 inline Foam::quaternion Foam::operator*(const quaternion& q, const scalar s)
773 {
774  return quaternion(s*q.w(), s*q.v());
775 }
776 
777 
778 inline Foam::quaternion Foam::operator/(const quaternion& q, const scalar s)
779 {
780  return quaternion(q.w()/s, q.v()/s);
781 }
782 
783 
784 // ************************************************************************* //
dimensionedScalar acos(const dimensionedScalar &ds)
tensor R() const
The rotation tensor corresponding to the quaternion.
Definition: quaternionI.H:352
void operator/=(const quaternion &q)
Definition: quaternionI.H:601
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vector eulerAngles(const eulerOrder order) const
Return the Euler rotation angles corresponding to the specified rotation order.
Definition: quaternionI.H:402
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
bool equal(const T &a, const T &b)
Compare two values for equality.
Definition: label.H:164
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const vector & v() const noexcept
Vector part of the quaternion ( = axis of rotation)
Definition: quaternionI.H:284
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
static quaternion unit(const vector &v)
Return the unit quaternion (versor) from the given vector (w = sqrt(1 - |sqr(v)|)) ...
Definition: quaternionI.H:80
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
dimensionedScalar sqrt(const dimensionedScalar &ds)
Tensor< scalar > tensor
Definition: symmTensor.H:57
dimensionedScalar operator/(const scalar s1, const dimensionedScalar &ds2)
#define w2
Definition: blockCreate.C:28
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
Definition: quaternionI.H:674
tensor rotationTensor(const vector &n1, const vector &n2)
Rotational transformation tensor from vector n1 to n2.
Definition: transform.H:47
dimensionedScalar asin(const dimensionedScalar &ds)
void operator*=(const quaternion &q)
Definition: quaternionI.H:594
scalar y
scalar w() const noexcept
Scalar part of the quaternion ( = cos(theta/2) for rotation)
Definition: quaternionI.H:278
quaternion conjugate(const quaternion &q)
Return the conjugate of the given quaternion.
Definition: quaternionI.H:653
dimensionedScalar cos(const dimensionedScalar &ds)
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
Quaternion class used to perform rotations in 3D space.
Definition: quaternion.H:53
#define w0
Definition: blockCreate.C:26
Vector< scalar > vector
Definition: vector.H:57
errorManip< error > abort(error &err)
Definition: errorManip.H:139
void operator-=(const quaternion &q)
Definition: quaternionI.H:588
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
const direction noexcept
Definition: Scalar.H:258
dimensionedScalar sin(const dimensionedScalar &ds)
quaternion & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the quaternion by its magnitude.
Definition: quaternionI.H:302
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
quaternion()=default
Default construct.
quaternion & operator=(const quaternion &)=default
Copy assignment.
tmp< GeometricField< Type, faPatchField, areaMesh > > operator &(const faMatrix< Type > &, const DimensionedField< Type, areaMesh > &)
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:297
vector invTransform(const vector &v) const
Rotate the given vector anti-clockwise.
Definition: quaternionI.H:331
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
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))
Tensor of scalars, i.e. Tensor<scalar>.
vector transform(const vector &v) const
Rotate the given vector.
Definition: quaternionI.H:325
void operator+=(const quaternion &q)
Definition: quaternionI.H:582
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127