TensorI.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) 2016-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 #include <type_traits>
30 
31 #include "SymmTensor.H"
32 
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 
35 template<class Cmpt>
37 :
39 {}
40 
41 
42 template<class Cmpt>
43 template<class Cmpt2>
45 (
46  const MatrixSpace<Tensor<Cmpt2>, Cmpt2, 3, 3>& vs
47 )
48 :
50 {}
51 
52 
53 template<class Cmpt>
54 template<class Cmpt2>
56 (
57  const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
58 )
59 :
60  Tensor::msType(vs)
61 {}
62 
63 
64 template<class Cmpt>
66 {
67  this->v_[XX] = st.ii(); this->v_[XY] = Zero; this->v_[XZ] = Zero;
68  this->v_[YX] = Zero; this->v_[YY] = st.ii(); this->v_[YZ] = Zero;
69  this->v_[ZX] = Zero; this->v_[ZY] = Zero; this->v_[ZZ] = st.ii();
70 }
71 
72 
73 template<class Cmpt>
75 {
76  this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
77  this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
78  this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
79 }
80 
81 
82 template<class Cmpt>
84 (
85  const Vector<Vector<Cmpt>>& vecs,
86  const bool transposed
87 )
88 :
89  Tensor<Cmpt>(vecs.x(), vecs.y(), vecs.z(), transposed)
90 {}
91 
92 
93 template<class Cmpt>
95 (
96  const Vector<Cmpt>& x,
97  const Vector<Cmpt>& y,
98  const Vector<Cmpt>& z,
99  const bool transposed
100 )
101 {
102  if (transposed)
103  {
104  this->cols(x, y, z);
105  }
106  else
107  {
108  this->rows(x, y, z);
109  }
110 }
111 
112 
113 template<class Cmpt>
115 (
116  const Cmpt txx, const Cmpt txy, const Cmpt txz,
117  const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
118  const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
119 )
120 {
121  this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
122  this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
123  this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
124 }
125 
126 
127 template<class Cmpt>
128 template
129 <
130  template<class, Foam::direction, Foam::direction> class Block2,
131  Foam::direction BRowStart,
132  Foam::direction BColStart
133 >
135 (
136  const Block2<Tensor<Cmpt>, BRowStart, BColStart>& block
137 )
138 :
140 {}
141 
142 
143 template<class Cmpt>
145 :
147 {}
148 
149 
150 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151 
152 template<class Cmpt>
154 {
155  return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
156 }
157 
158 
159 template<class Cmpt>
161 {
162  return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
163 }
164 
165 
166 template<class Cmpt>
168 {
169  return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
170 }
171 
172 
173 template<class Cmpt>
175 {
176  return Vector<Cmpt>(this->v_[XX], this->v_[YX], this->v_[ZX]);
177 }
178 
179 
180 template<class Cmpt>
182 {
183  return Vector<Cmpt>(this->v_[XY], this->v_[YY], this->v_[ZY]);
184 }
185 
186 
187 template<class Cmpt>
189 {
190  return Vector<Cmpt>(this->v_[XZ], this->v_[YZ], this->v_[ZZ]);
191 }
192 
193 
194 template<class Cmpt>
195 template<Foam::direction Idx>
197 {
198  if (Idx == 0) return cx();
199  else if (Idx == 1) return cy();
200  else if (Idx == 2) return cz();
202  static_assert(Idx < 3, "Invalid column access");
203  return Zero;
204 }
205 
206 
207 template<class Cmpt>
209 {
210  switch (c)
211  {
212  case 0: return cx(); break;
213  case 1: return cy(); break;
214  case 2: return cz(); break;
215  default:
217  << "Invalid column access " << c << abort(FatalError);
218  }
220  return Zero;
221 }
222 
223 
224 template<class Cmpt>
225 template<Foam::direction Idx>
227 {
228  if (Idx == 0) return x();
229  else if (Idx == 1) return y();
230  else if (Idx == 2) return z();
232  static_assert(Idx < 3, "Invalid row access");
233  return Zero;
234 }
235 
236 
237 template<class Cmpt>
239 {
240  switch (r)
241  {
242  case 0: return x(); break;
243  case 1: return y(); break;
244  case 2: return z(); break;
245  default:
247  << "Invalid row access " << r << abort(FatalError);
248  }
250  return Zero;
251 }
252 
253 
254 template<class Cmpt>
255 template<Foam::direction Idx>
256 inline void Foam::Tensor<Cmpt>::col(const Vector<Cmpt>& v)
257 {
258  if (Idx == 0)
259  {
260  this->v_[XX] = v.x();
261  this->v_[YX] = v.y();
262  this->v_[ZX] = v.z();
263  }
264  else if (Idx == 1)
265  {
266  this->v_[XY] = v.x();
267  this->v_[YY] = v.y();
268  this->v_[ZY] = v.z();
269  }
270  else if (Idx == 2)
271  {
272  this->v_[XZ] = v.x();
273  this->v_[YZ] = v.y();
274  this->v_[ZZ] = v.z();
275  }
277  static_assert(Idx < 3, "Invalid column access");
278 }
279 
280 
281 template<class Cmpt>
282 template<Foam::direction Idx>
283 inline void Foam::Tensor<Cmpt>::row(const Vector<Cmpt>& v)
284 {
285  if (Idx == 0)
286  {
287  this->v_[XX] = v.x(); this->v_[XY] = v.y(); this->v_[XZ] = v.z();
288  }
289  else if (Idx == 1)
290  {
291  this->v_[YX] = v.x(); this->v_[YY] = v.y(); this->v_[YZ] = v.z();
292  }
293  else if (Idx == 2)
294  {
295  this->v_[ZX] = v.x(); this->v_[ZY] = v.y(); this->v_[ZZ] = v.z();
296  }
298  static_assert(Idx < 3, "Invalid row access");
299 }
300 
301 
302 template<class Cmpt>
303 inline void Foam::Tensor<Cmpt>::cols
304 (
305  const Vector<Cmpt>& x,
306  const Vector<Cmpt>& y,
307  const Vector<Cmpt>& z
308 )
309 {
310  this->v_[XX] = x.x(); this->v_[XY] = y.x(); this->v_[XZ] = z.x();
311  this->v_[YX] = x.y(); this->v_[YY] = y.y(); this->v_[YZ] = z.y();
312  this->v_[ZX] = x.z(); this->v_[ZY] = y.z(); this->v_[ZZ] = z.z();
313 }
314 
315 
316 template<class Cmpt>
317 inline void Foam::Tensor<Cmpt>::rows
318 (
319  const Vector<Cmpt>& x,
320  const Vector<Cmpt>& y,
321  const Vector<Cmpt>& z
322 )
323 {
324  this->v_[XX] = x.x(); this->v_[XY] = x.y(); this->v_[XZ] = x.z();
325  this->v_[YX] = y.x(); this->v_[YY] = y.y(); this->v_[YZ] = y.z();
326  this->v_[ZX] = z.x(); this->v_[ZY] = z.y(); this->v_[ZZ] = z.z();
327 }
328 
329 
330 template<class Cmpt>
331 inline void Foam::Tensor<Cmpt>::col
332 (
333  const direction c,
334  const Vector<Cmpt>& v
335 )
336 {
337  switch (c)
338  {
339  case 0: col<0>(v); break;
340  case 1: col<1>(v); break;
341  case 2: col<2>(v); break;
342  default:
344  << "Invalid column access " << c << abort(FatalError);
345  }
346 }
347 
348 
349 template<class Cmpt>
350 inline void Foam::Tensor<Cmpt>::row
351 (
352  const direction r,
353  const Vector<Cmpt>& v
354 )
355 {
356  switch (r)
357  {
358  case 0: row<0>(v); break;
359  case 1: row<1>(v); break;
360  case 2: row<2>(v); break;
361  default:
363  << "Invalid row access " << r << abort(FatalError);
364  }
365 }
366 
367 
368 template<class Cmpt>
370 {
371  return Vector<Cmpt>(this->v_[XX], this->v_[YY], this->v_[ZZ]);
372 }
373 
374 
375 template<class Cmpt>
377 {
378  this->v_[XX] = v.x(); this->v_[YY] = v.y(); this->v_[ZZ] = v.z();
379 }
380 
381 
382 template<class Cmpt>
384 {
385  this->v_[XX] += v.x(); this->v_[YY] += v.y(); this->v_[ZZ] += v.z();
386 }
387 
388 
389 template<class Cmpt>
391 {
392  this->v_[XX] -= v.x(); this->v_[YY] -= v.y(); this->v_[ZZ] -= v.z();
393 }
394 
395 
396 template<class Cmpt>
397 inline Foam::scalar Foam::Tensor<Cmpt>::diagSqr() const
398 {
399  return
400  (
401  Foam::magSqr(this->xx())
402  + Foam::magSqr(this->yy())
403  + Foam::magSqr(this->zz())
404  );
405 }
406 
407 
408 template<class Cmpt>
409 inline bool Foam::Tensor<Cmpt>::is_identity(const scalar tol) const
410 {
411  return
412  (
413  mag(xx() - pTraits<Cmpt>::one) < tol
414  && mag(yy() - pTraits<Cmpt>::one) < tol
415  && mag(zz() - pTraits<Cmpt>::one) < tol
416  && mag(xy()) < tol && mag(xz()) < tol
417  && mag(yx()) < tol && mag(yz()) < tol
418  && mag(zx()) < tol && mag(zy()) < tol
419  );
420 }
421 
422 
423 // * * * * * * * * * * * * * * * Member Operations * * * * * * * * * * * * * //
424 
425 template<class Cmpt>
427 {
428  return Tensor<Cmpt>
429  (
430  xx(), yx(), zx(),
431  xy(), yy(), zy(),
432  xz(), yz(), zz()
433  );
434 }
435 
436 
437 template<class Cmpt>
438 inline Cmpt Foam::Tensor<Cmpt>::det() const
439 {
440  return
441  (
442  xx()*yy()*zz() + xy()*yz()*zx()
443  + xz()*yx()*zy() - xx()*yz()*zy()
444  - xy()*yx()*zz() - xz()*yy()*zx()
445  );
446 }
447 
448 
449 template<class Cmpt>
450 inline Cmpt Foam::Tensor<Cmpt>::det2D(const direction excludeCmpt) const
451 {
452  switch (excludeCmpt)
453  {
454  case 0: // Eliminate x
455  {
456  return (yy()*zz() - yz()*zy());
457  }
458 
459  case 1: // Eliminate y
460  {
461  return (xx()*zz() - xz()*zx());
462  }
463  }
465  // Fall-through: Eliminate z
466  return (xx()*yy() - xy()*yx());
467 }
468 
469 
470 template<class Cmpt>
472 {
473  return Tensor<Cmpt>
474  (
475  yy()*zz() - zy()*yz(), xz()*zy() - xy()*zz(), xy()*yz() - xz()*yy(),
476  zx()*yz() - yx()*zz(), xx()*zz() - xz()*zx(), yx()*xz() - xx()*yz(),
477  yx()*zy() - yy()*zx(), xy()*zx() - xx()*zy(), xx()*yy() - yx()*xy()
478  );
479 }
480 
481 
482 template<class Cmpt>
484 {
485  return this->adjunct().T();
486 }
487 
488 
489 template<class Cmpt>
491 (
492  const direction excludeCmpt
493 ) const
494 {
495  switch (excludeCmpt)
496  {
497  case 0: // Eliminate x
498  {
499  return Tensor<Cmpt>
500  (
501  Zero, Zero, Zero,
502  Zero, zz(), -yz(),
503  Zero, -zy(), yy()
504  );
505  }
506 
507  case 1: // Eliminate y
508  {
509  return Tensor<Cmpt>
510  (
511  zz(), Zero, -xz(),
512  Zero, Zero, Zero,
513  -zx(), Zero, xx()
514  );
515  }
516  }
517 
518  // Fall-through: Eliminate z
519  return Tensor<Cmpt>
520  (
521  yy(), -xy(), Zero,
522  -yx(), xx(), Zero,
524  );
525 }
526 
527 
528 template<class Cmpt>
530 (
531  const direction excludeCmpt
532 ) const
533 {
534  const Cmpt detval = this->det2D(excludeCmpt);
536  return this->adjunct2D(excludeCmpt)/detval;
537 }
538 
539 
540 template<class Cmpt>
541 inline Foam::Tensor<Cmpt>
543 {
544  const Tensor<Cmpt>& t1 = *this;
545 
546  return Tensor<Cmpt>
547  (
548  t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
549  t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
550  t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
551 
552  t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
553  t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
554  t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
555 
556  t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
557  t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
558  t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
559  );
560 }
561 
562 
563 template<class Cmpt>
564 inline Foam::Tensor<Cmpt>
566 {
567  const Tensor<Cmpt>& t1 = *this;
568 
569  return Tensor<Cmpt>
570  (
571  t1.xx()*t2.xx(), t1.xy()*t2.xy(), t1.xz()*t2.xz(),
572  t1.yx()*t2.yx(), t1.yy()*t2.yy(), t1.yz()*t2.yz(),
573  t1.zx()*t2.zx(), t1.zy()*t2.zy(), t1.zz()*t2.zz()
574  );
575 }
576 
577 
578 // Invert without much error handling
579 template<class Cmpt>
581 {
582  const Cmpt detval = this->det();
583 
584  #ifdef FULLDEBUG
585  if (mag(detval) < VSMALL)
586  {
588  << "Tensor not properly invertible, determinant:"
589  << detval << " tensor:" << *this << nl
590  << abort(FatalError);
591  }
592  #endif
594  return this->adjunct()/detval;
595 }
596 
597 
598 // Invert with some error handling
599 template<class Cmpt>
601 {
602  {
603  // Attempt to identify and handle 2-D cases
604  // - use diagSqr instead of magSqr for fewer operations
605 
606  const scalar magSqr_xx = Foam::magSqr(xx());
607  const scalar magSqr_yy = Foam::magSqr(yy());
608  const scalar magSqr_zz = Foam::magSqr(zz());
609 
610  // SMALL: 1e-15 (double), 1e-6 (float), but 1e-6 may be adequate
611 
612  const scalar threshold = SMALL * (magSqr_xx + magSqr_yy + magSqr_zz);
613 
614  const bool small_xx = (magSqr_xx < threshold);
615  const bool small_yy = (magSqr_yy < threshold);
616  const bool small_zz = (magSqr_zz < threshold);
617 
618  if (small_xx || small_yy || small_zz)
619  {
620  Tensor<Cmpt> work(*this);
621 
622  if (small_xx) { work.xx() += pTraits<Cmpt>::one; }
623  if (small_yy) { work.yy() += pTraits<Cmpt>::one; }
624  if (small_zz) { work.zz() += pTraits<Cmpt>::one; }
625 
626  const Cmpt detval = work.det();
627 
628  if (mag(detval) < ROOTVSMALL)
629  {
630  // Appears to be nearly zero - leave untouched?
631  return Tensor<Cmpt>(Zero);
632  }
633 
634  work = work.adjunct()/detval;
635 
636  if (small_xx) { work.xx() -= pTraits<Cmpt>::one; }
637  if (small_yy) { work.yy() -= pTraits<Cmpt>::one; }
638  if (small_zz) { work.zz() -= pTraits<Cmpt>::one; }
639 
640  return work;
641  }
642  }
643 
644  const Cmpt detval = this->det();
645 
646  if (mag(detval) < ROOTVSMALL)
647  {
648  // Appears to be nearly zero - leave untouched?
649  return Tensor<Cmpt>(Zero);
650  }
651 
652  return this->adjunct()/detval;
653 }
654 
655 
656 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
657 
658 template<class Cmpt>
659 inline void Foam::Tensor<Cmpt>::operator&=(const Tensor<Cmpt>& t)
660 {
661  *this = this->inner(t);
662 }
663 
664 
665 template<class Cmpt>
666 template<class Cmpt2>
667 inline void Foam::Tensor<Cmpt>::operator=
668 (
669  const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
670 )
671 {
672  VectorSpace<Tensor<Cmpt>, Cmpt, 9>::operator=(vs);
673 }
674 
675 
676 template<class Cmpt>
678 {
679  this->v_[XX] = st.ii(); this->v_[XY] = Zero; this->v_[XZ] = Zero;
680  this->v_[YX] = Zero; this->v_[YY] = st.ii(); this->v_[YZ] = Zero;
681  this->v_[ZX] = Zero; this->v_[ZY] = Zero; this->v_[ZZ] = st.ii();
682 }
683 
684 
685 template<class Cmpt>
686 inline void Foam::Tensor<Cmpt>::operator=(const SymmTensor<Cmpt>& st)
687 {
688  this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
689  this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
690  this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
691 }
692 
693 
694 template<class Cmpt>
696 {
697  this->v_[XX] = tr.x().x();
698  this->v_[XY] = tr.x().y();
699  this->v_[XZ] = tr.x().z();
700 
701  this->v_[YX] = tr.y().x();
702  this->v_[YY] = tr.y().y();
703  this->v_[YZ] = tr.y().z();
704 
705  this->v_[ZX] = tr.z().x();
706  this->v_[ZY] = tr.z().y();
707  this->v_[ZZ] = tr.z().z();
708 }
709 
710 
711 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
712 
713 namespace Foam
714 {
716 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
717 
718 //- Return the trace of a Tensor
719 template<class Cmpt>
720 inline Cmpt tr(const Tensor<Cmpt>& t)
721 {
722  return t.xx() + t.yy() + t.zz();
723 }
724 
726 //- Return the spherical part of a Tensor
727 template<class Cmpt>
728 inline SphericalTensor<Cmpt> sph(const Tensor<Cmpt>& t)
729 {
730  return SphericalTensor<Cmpt>
731  (
732  (1.0/3.0)*tr(t)
733  );
734 }
735 
736 
737 //- Return the symmetric part of a Tensor
738 template<class Cmpt>
739 inline SymmTensor<Cmpt> symm(const Tensor<Cmpt>& t)
740 {
741  return SymmTensor<Cmpt>
742  (
743  t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
744  t.yy(), 0.5*(t.yz() + t.zy()),
745  t.zz()
746  );
747 }
748 
749 
750 //- Return twice the symmetric part of a Tensor
751 template<class Cmpt>
752 inline SymmTensor<Cmpt> twoSymm(const Tensor<Cmpt>& t)
753 {
754  return SymmTensor<Cmpt>
755  (
756  2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
757  2*t.yy(), (t.yz() + t.zy()),
758  2*t.zz()
759  );
760 }
761 
762 
763 //- Return the deviatoric part of the symmetric part of a Tensor
764 template<class Cmpt>
765 inline SymmTensor<Cmpt> devSymm(const Tensor<Cmpt>& t)
766 {
767  const Cmpt sph(tr(t)/3.0);
769  return SymmTensor<Cmpt>
770  (
771  t.xx() - sph, 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
772  t.yy() - sph, 0.5*(t.yz() + t.zy()),
773  t.zz() - sph
774  );
775 }
776 
777 
778 //- Return the deviatoric part of twice the symmetric part of a Tensor
779 template<class Cmpt>
780 inline SymmTensor<Cmpt> devTwoSymm(const Tensor<Cmpt>& t)
781 {
782  const Cmpt sph((2.0/3.0)*tr(t));
783 
784  return SymmTensor<Cmpt>
785  (
786  2*t.xx() - sph, (t.xy() + t.yx()), (t.xz() + t.zx()),
787  2*t.yy() - sph, (t.yz() + t.zy()),
788  2*t.zz() - sph
789  );
790 }
791 
792 
793 //- Return the skew-symmetric part of a Tensor
794 template<class Cmpt>
795 inline Tensor<Cmpt> skew(const Tensor<Cmpt>& t)
796 {
797  return Tensor<Cmpt>
798  (
799  Zero, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
800  0.5*(t.yx() - t.xy()), Zero, 0.5*(t.yz() - t.zy()),
801  0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), Zero
802  );
803 }
804 
805 
806 //- Return the skew-symmetric part of a SymmTensor as a Tensor
807 template<class Cmpt>
808 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
809 {
810  return Tensor<Cmpt>::zero;
811 }
812 
813 
814 //- Return the deviatoric part of a Tensor
815 template<class Cmpt>
816 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
817 {
818  return t - sph(t);
819 }
820 
821 
822 //- Return the two-third deviatoric part of a Tensor
823 template<class Cmpt>
824 inline Tensor<Cmpt> dev2(const Tensor<Cmpt>& t)
825 {
826  return t - 2*sph(t);
827 }
828 
829 
830 //- Return the determinant of a Tensor
831 template<class Cmpt>
832 inline Cmpt det(const Tensor<Cmpt>& t)
833 {
834  return t.det();
835 }
836 
838 //- Return the cofactor Tensor of a Tensor
839 template<class Cmpt>
840 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
841 {
842  return t.cof();
843 }
844 
845 
846 //- Return the inverse of a Tensor, using the given determinant value
847 template<class Cmpt>
848 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt detval)
849 {
850  #ifdef FULLDEBUG
851  if (mag(detval) < VSMALL)
852  {
854  << "Tensor not properly invertible, determinant:"
855  << detval << " tensor:" << t << nl
856  << abort(FatalError);
857  }
858  #endif
859 
860  return t.adjunct()/detval;
861 }
862 
863 
864 //- Return the inverse of a Tensor
865 template<class Cmpt>
866 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
867 {
868  return t.inv();
869 }
870 
871 
872 //- Return the 1st invariant of a Tensor
873 template<class Cmpt>
874 inline Cmpt invariantI(const Tensor<Cmpt>& t)
875 {
876  return tr(t);
877 }
878 
879 
880 //- Return the 2nd invariant of a Tensor
881 template<class Cmpt>
882 inline Cmpt invariantII(const Tensor<Cmpt>& t)
883 {
884  return
885  (
886  t.xx()*t.yy() + t.yy()*t.zz() + t.xx()*t.zz()
887  - t.xy()*t.yx() - t.yz()*t.zy() - t.xz()*t.zx()
888  );
889 }
890 
891 
892 //- Return the 3rd invariant of a Tensor
893 template<class Cmpt>
894 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
895 {
896  return det(t);
897 }
898 
899 
900 //- Linear interpolation of tensors a and b by factor t
901 template<class Cmpt>
902 inline Tensor<Cmpt> lerp
903 (
904  const Tensor<Cmpt>& a,
905  const Tensor<Cmpt>& b,
906  const scalar t
907 )
908 {
909  const scalar onet = (1-t);
910 
911  return Tensor<Cmpt>
912  (
913  onet*a.xx() + t*b.xx(),
914  onet*a.xy() + t*b.xy(),
915  onet*a.xz() + t*b.xz(),
916  onet*a.yx() + t*b.yx(),
917  onet*a.yy() + t*b.yy(),
918  onet*a.yz() + t*b.yz(),
919  onet*a.zx() + t*b.zx(),
920  onet*a.zy() + t*b.zy(),
921  onet*a.zz() + t*b.zz()
922  );
923 }
924 
925 
926 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
927 
928 //- Sum of a SphericalTensor and a Tensor
929 template<class Cmpt>
930 inline Tensor<Cmpt>
931 operator+(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
932 {
933  return Tensor<Cmpt>
934  (
935  st1.ii() + t2.xx(), t2.xy(), t2.xz(),
936  t2.yx(), st1.ii() + t2.yy(), t2.yz(),
937  t2.zx(), t2.zy(), st1.ii() + t2.zz()
938  );
939 }
940 
941 
942 //- Sum of a Tensor and a SphericalTensor
943 template<class Cmpt>
944 inline Tensor<Cmpt>
945 operator+(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
946 {
947  return Tensor<Cmpt>
948  (
949  t1.xx() + st2.ii(), t1.xy(), t1.xz(),
950  t1.yx(), t1.yy() + st2.ii(), t1.yz(),
951  t1.zx(), t1.zy(), t1.zz() + st2.ii()
952  );
953 }
954 
955 
956 //- Sum of a SymmTensor and a Tensor
957 template<class Cmpt>
958 inline Tensor<Cmpt>
959 operator+(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
960 {
961  return Tensor<Cmpt>
962  (
963  st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
964  st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
965  st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
966  );
967 }
968 
969 
970 //- Sum of a Tensor and a SymmTensor
971 template<class Cmpt>
972 inline Tensor<Cmpt>
973 operator+(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
974 {
975  return Tensor<Cmpt>
976  (
977  t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
978  t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
979  t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
980  );
981 }
982 
983 
984 //- Subtract a Tensor from a SphericalTensor
985 template<class Cmpt>
986 inline Tensor<Cmpt>
987 operator-(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
988 {
989  return Tensor<Cmpt>
990  (
991  st1.ii() - t2.xx(), -t2.xy(), -t2.xz(),
992  -t2.yx(), st1.ii() - t2.yy(), -t2.yz(),
993  -t2.zx(), -t2.zy(), st1.ii() - t2.zz()
994  );
995 }
996 
997 
998 //- Subtract a SphericalTensor from a Tensor
999 template<class Cmpt>
1000 inline Tensor<Cmpt>
1001 operator-(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
1002 {
1003  return Tensor<Cmpt>
1004  (
1005  t1.xx() - st2.ii(), t1.xy(), t1.xz(),
1006  t1.yx(), t1.yy() - st2.ii(), t1.yz(),
1007  t1.zx(), t1.zy(), t1.zz() - st2.ii()
1008  );
1009 }
1011 
1012 //- Subtract a Tensor from a SymmTensor
1013 template<class Cmpt>
1014 inline Tensor<Cmpt>
1015 operator-(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1016 {
1017  return Tensor<Cmpt>
1018  (
1019  st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
1020  st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
1021  st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
1022  );
1023 }
1024 
1025 
1026 //- Subtract a SymmTensor from a Tensor
1027 template<class Cmpt>
1028 inline Tensor<Cmpt>
1029 operator-(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1030 {
1031  return Tensor<Cmpt>
1032  (
1033  t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
1034  t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
1035  t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
1036  );
1037 }
1038 
1039 
1040 //- Return the Hodge dual of a Tensor as a Vector
1041 template<class Cmpt>
1043 {
1044  return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
1045 }
1046 
1047 
1048 //- Return the Hodge dual of a Vector as a Tensor
1049 template<class Cmpt>
1050 inline Tensor<Cmpt> operator*(const Vector<Cmpt>& v)
1051 {
1052  return Tensor<Cmpt>
1053  (
1054  Zero, -v.z(), v.y(),
1055  v.z(), Zero, -v.x(),
1056  -v.y(), v.x(), Zero
1057  );
1059 
1060 
1061 //- Division of a Vector by a Tensor
1062 template<class Cmpt>
1063 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt>>::type
1064 operator/(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
1065 {
1066  return inv(t) & v;
1067 }
1068 
1069 
1070 //- Division of a Tensor by a Cmpt
1071 template<class Cmpt>
1072 inline Tensor<Cmpt>
1073 operator/(const Tensor<Cmpt>& t, const Cmpt s)
1075  #ifdef FULLDEBUG
1076  if (mag(s) < VSMALL)
1077  {
1079  << "Tensor = " << t
1080  << " is not divisible due to a zero value in Cmpt:"
1081  << "Cmpt = " << s
1082  << abort(FatalError);
1083  }
1084  #endif
1085 
1086  return Tensor<Cmpt>
1087  (
1088  t.xx()/s, t.xy()/s, t.xz()/s,
1089  t.yx()/s, t.yy()/s, t.yz()/s,
1090  t.zx()/s, t.zy()/s, t.zz()/s
1091  );
1092 }
1093 
1094 
1095 //- Inner-product of a Tensor and a Tensor
1096 template<class Cmpt>
1097 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt>>::type
1098 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
1100  return t1.inner(t2);
1101 }
1102 
1103 
1104 //- Inner-product of a SphericalTensor and a Tensor
1105 template<class Cmpt>
1106 inline Tensor<Cmpt>
1107 operator&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1108 {
1109  return Tensor<Cmpt>
1110  (
1111  st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
1112  st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
1113  st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
1114  );
1116 
1117 
1118 //- Inner-product of a Tensor and a SphericalTensor
1119 template<class Cmpt>
1120 inline Tensor<Cmpt>
1121 operator&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
1122 {
1123  return Tensor<Cmpt>
1124  (
1125  t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
1126  t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
1127  t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
1128  );
1129 }
1130 
1131 
1132 //- Inner-product of a SymmTensor and a Tensor
1133 template<class Cmpt>
1134 inline Tensor<Cmpt>
1135 operator&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1136 {
1137  return Tensor<Cmpt>
1138  (
1139  st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
1140  st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
1141  st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
1142 
1143  st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
1144  st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
1145  st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
1146 
1147  st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
1148  st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
1149  st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
1150  );
1151 }
1152 
1154 //- Inner-product of a Tensor and a SymmTensor
1155 template<class Cmpt>
1156 inline Tensor<Cmpt>
1157 operator&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1158 {
1159  return Tensor<Cmpt>
1160  (
1161  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
1162  t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
1163  t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
1165  t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
1166  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
1167  t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
1168 
1169  t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
1170  t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
1171  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1172  );
1173 }
1174 
1175 
1176 //- Inner-product of a Tensor and a Vector
1177 template<class Cmpt>
1178 #if defined(__GNUC__) && !defined(__clang__)
1179 // Workaround for gcc (11+) that fails to handle tensor dot vector
1180 __attribute__((optimize("no-tree-vectorize")))
1181 #endif
1182 inline Vector<Cmpt>
1183 operator&(const Tensor<Cmpt>& t, const Vector<Cmpt>& v)
1184 {
1185  return Vector<Cmpt>
1186  (
1187  t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
1188  t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
1189  t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
1190  );
1191 }
1192 
1193 
1194 //- Inner-product of a Vector and a Tensor
1195 template<class Cmpt>
1197 operator&(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
1198 {
1199  return Vector<Cmpt>
1200  (
1201  v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
1202  v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
1203  v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
1204  );
1205 }
1206 
1207 
1208 //- Double-inner-product of a SphericalTensor and a Tensor
1209 template<class Cmpt>
1210 inline Cmpt
1211 operator&&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1212 {
1213  return (st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
1214 }
1215 
1216 
1217 //- Double-inner-product of a Tensor and a SphericalTensor
1218 template<class Cmpt>
1219 inline Cmpt
1221 {
1222  return (t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
1223 }
1224 
1225 
1226 //- Double-inner-product of a SymmTensor and a Tensor
1227 template<class Cmpt>
1228 inline Cmpt
1229 operator&&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1230 {
1231  return
1232  (
1233  st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
1234  st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
1235  st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
1236  );
1237 }
1238 
1239 
1240 //- Double-inner-product of a Tensor and a SymmTensor
1241 template<class Cmpt>
1242 inline Cmpt
1243 operator&&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1244 {
1245  return
1246  (
1247  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
1248  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
1249  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1250  );
1251 }
1252 
1253 
1254 //- Outer-product of a Vector and a Vector
1255 template<class Cmpt>
1256 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt>>::type
1257 operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2)
1258 {
1259  return Tensor<Cmpt>
1260  (
1261  v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
1262  v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
1263  v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
1264  );
1265 }
1266 
1267 
1268 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1269 
1270 template<class Cmpt>
1271 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt>>
1272 {
1273 public:
1274 
1275  typedef Tensor<Cmpt> type;
1276 };
1277 
1278 
1279 template<class Cmpt>
1280 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt>>
1281 {
1282 public:
1283 
1284  typedef Tensor<Cmpt> type;
1285 };
1286 
1287 
1288 template<class Cmpt>
1289 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt>>
1290 {
1291 public:
1292 
1293  typedef Tensor<Cmpt> type;
1294 };
1295 
1296 
1297 template<class Cmpt>
1298 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt>>
1299 {
1300 public:
1301 
1303 };
1304 
1305 
1306 template<class Cmpt>
1307 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt>>
1308 {
1309 public:
1310 
1311  typedef Tensor<Cmpt> type;
1312 };
1313 
1314 
1315 template<class Cmpt>
1316 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt>>
1317 {
1318 public:
1319 
1320  typedef Tensor<Cmpt> type;
1321 };
1322 
1323 
1324 template<class Cmpt>
1325 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt>>
1326 {
1327 public:
1328 
1329  typedef Tensor<Cmpt> type;
1330 };
1331 
1332 
1333 template<class Cmpt>
1334 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt>>
1335 {
1336 public:
1337 
1338  typedef Tensor<Cmpt> type;
1339 };
1340 
1341 
1342 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1343 
1344 } // End namespace Foam
1345 
1346 // ************************************************************************* //
Cmpt invariantII(const SymmTensor< Cmpt > &st)
Return the 2nd invariant of a SymmTensor.
Definition: SymmTensorI.H:581
Tensor< Cmpt > adjunct2D(const direction excludeCmpt) const
Return 2D adjunct matrix by excluding given direction.
Definition: TensorI.H:484
Cmpt tr(const Tensor< Cmpt > &t)
Return the trace of a Tensor.
Definition: TensorI.H:715
const Cmpt & xz() const noexcept
Definition: SymmTensor.H:152
uint8_t direction
Definition: direction.H:46
Vector< Cmpt > cx() const
Extract vector for column 0.
Definition: TensorI.H:167
A templated (3 x 3) symmetric tensor of objects of <T>, effectively containing 6 elements, derived from VectorSpace.
Definition: SymmTensor.H:50
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const Cmpt & yx() const noexcept
Definition: Tensor.H:196
dimensionedTensor skew(const dimensionedTensor &dt)
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Vector< Cmpt > cz() const
Extract vector for column 2.
Definition: TensorI.H:181
Tensor< Cmpt > T() const
Return non-Hermitian transpose.
Definition: TensorI.H:419
Vector< Cmpt > x() const
Extract vector for row 0.
Definition: TensorI.H:146
void subtractDiag(const Vector< Cmpt > &v)
Subtract from the diagonal.
Definition: TensorI.H:383
Cmpt det() const
The determinate.
Definition: TensorI.H:431
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:75
const Cmpt & xy() const noexcept
Definition: Tensor.H:194
Templated vector space.
Definition: VectorSpace.H:52
dimensionSet operator &&(const dimensionSet &ds1, const dimensionSet &ds2)
SymmTensor< Cmpt > devSymm(const SymmTensor< Cmpt > &st)
Return the deviatoric part of the symmetric part of a SymmTensor.
Definition: SymmTensorI.H:481
dimensionedScalar operator/(const scalar s1, const dimensionedScalar &ds2)
Vector< Cmpt > y() const
Extract vector for row 1.
Definition: TensorI.H:153
const Cmpt & y() const noexcept
Access to the vector y component.
Definition: Vector.H:140
dimensionedScalar det(const dimensionedSphericalTensor &dt)
SphericalTensor< Cmpt > sph(const DiagTensor< Cmpt > &dt)
Return the spherical part of a DiagTensor as a SphericalTensor.
Definition: DiagTensorI.H:110
Templated matrix space.
Definition: MatrixSpace.H:54
tmp< faMatrix< Type > > operator+(const faMatrix< Type > &, const faMatrix< Type > &)
Tensor()=default
Default construct.
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
const Cmpt & zz() const noexcept
Definition: SymmTensor.H:158
Cmpt det(const Tensor< Cmpt > &t)
Return the determinant of a Tensor.
Definition: TensorI.H:847
A templated (3 x 3) diagonal tensor of objects of <T>, effectively containing 1 element, derived from VectorSpace.
Tensor< Cmpt > inv2D(const direction excludeCmpt) const
Return inverse of 2D tensor (by excluding given direction)
Definition: TensorI.H:523
Vector< Cmpt > z() const
Extract vector for row 2.
Definition: TensorI.H:160
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
scalar y
const Cmpt & yz() const noexcept
Definition: Tensor.H:198
const Cmpt & xx() const noexcept
Definition: Tensor.H:193
const Cmpt & yy() const noexcept
Definition: Tensor.H:197
void cols(const Vector< Cmpt > &x, const Vector< Cmpt > &y, const Vector< Cmpt > &z)
Set column values.
Definition: TensorI.H:297
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
Vector< Cmpt > col() const
Extract vector for given column: compile-time check of index.
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
bool is_identity(const scalar tol=ROOTVSMALL) const
Is identity tensor?
Definition: TensorI.H:402
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Cmpt invariantIII(const SymmTensor< Cmpt > &st)
Return the 3rd invariant of a SymmTensor.
Definition: SymmTensorI.H:595
const Cmpt & zx() const noexcept
Definition: Tensor.H:199
const Cmpt & ii() const noexcept
const Cmpt & xx() const noexcept
Definition: SymmTensor.H:150
void rows(const Vector< Cmpt > &x, const Vector< Cmpt > &y, const Vector< Cmpt > &z)
Set row values.
Definition: TensorI.H:311
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
errorManip< error > abort(error &err)
Definition: errorManip.H:139
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
void addDiag(const Vector< Cmpt > &v)
Add to the diagonal.
Definition: TensorI.H:376
Creates a single block of cells from point coordinates, numbers of cells in each direction and an exp...
Definition: block.H:54
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross-product operators.
Definition: Vector.H:58
Tensor< Cmpt > adjunct() const
Return adjunct matrix (transpose of cofactor matrix)
Definition: TensorI.H:464
const Cmpt & x() const noexcept
Access to the vector x component.
Definition: Vector.H:135
dimensioned< Type > lerp(const dimensioned< Type > &a, const dimensioned< Type > &b, const scalar t)
Tensor< Cmpt > inv() const
Return inverse.
Definition: TensorI.H:573
const Cmpt & zy() const noexcept
Definition: Tensor.H:200
Tensor< Cmpt > schur(const Tensor< Cmpt > &t2) const
Schur-product of this with another Tensor.
Definition: TensorI.H:558
Tensor< Cmpt > safeInv() const
Return inverse, with (ad hoc) failsafe handling of 2D tensors.
Definition: TensorI.H:593
Tensor & operator=(const Tensor &)=default
Copy assignment.
const Cmpt & z() const noexcept
Access to the vector z component.
Definition: Vector.H:145
dimensionedSymmTensor dev2(const dimensionedSymmTensor &dt)
Vector< Cmpt > diag() const
Extract the diagonal as a vector.
Definition: TensorI.H:362
const Cmpt & yy() const noexcept
Definition: SymmTensor.H:154
const Cmpt & zz() const noexcept
Definition: Tensor.H:201
dimensionedSymmTensor symm(const dimensionedSymmTensor &dt)
tmp< GeometricField< Type, faPatchField, areaMesh > > operator &(const faMatrix< Type > &, const DimensionedField< Type, areaMesh > &)
const dimensionedScalar c
Speed of light in a vacuum.
Cmpt invariantI(const SymmTensor< Cmpt > &st)
Return the 1st invariant of a SymmTensor.
Definition: SymmTensorI.H:571
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
void operator &=(const Tensor< Cmpt > &t)
Assign inner-product of this with another Tensor.
Tensor< Cmpt > cof() const
Return cofactor matrix (transpose of adjunct matrix)
Definition: TensorI.H:476
A templated (3 x 3) tensor of objects of <T> derived from MatrixSpace.
Definition: complexI.H:266
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))
Cmpt det2D(const direction excludeCmpt) const
The 2D determinant by excluding given direction.
Definition: TensorI.H:443
const Cmpt & xz() const noexcept
Definition: Tensor.H:195
Tensor< Cmpt > inner(const Tensor< Cmpt > &t2) const
Inner-product of this with another Tensor.
Definition: TensorI.H:535
scalar diagSqr() const
The L2-norm squared of the diagonal.
Definition: TensorI.H:390
typeOfRank< typename pTraits< arg1 >::cmptType, direction(pTraits< arg1 >::rank)+direction(pTraits< arg2 >::rank) - 2 >::type type
Definition: products.H:155
dimensionedSymmTensor cof(const dimensionedSymmTensor &dt)
Vector< Cmpt > cy() const
Extract vector for column 1.
Definition: TensorI.H:174
const Cmpt & xy() const noexcept
Definition: SymmTensor.H:151
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Namespace for OpenFOAM.
SymmTensor< Cmpt > devTwoSymm(const SymmTensor< Cmpt > &st)
Return the deviatoric part of twice the symmetric part of a SymmTensor.
Definition: SymmTensorI.H:491
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
Vector< Cmpt > row() const
Extract vector for given row: compile-time check of index.
const Cmpt & yz() const noexcept
Definition: SymmTensor.H:155