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);
535 
536  return this->adjunct2D(excludeCmpt)/detval;
537 }
538 
540 template<class Cmpt>
541 #if defined(__GNUC__) && !defined(__clang__)
542 // Workaround for gcc (11+) that fails to handle tensor dot vector
543 __attribute__((optimize("no-tree-vectorize")))
544 #endif
545 inline Foam::Tensor<Cmpt>
547 {
548  const Tensor<Cmpt>& t1 = *this;
549 
550  return Tensor<Cmpt>
551  (
552  t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
553  t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
554  t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
555 
556  t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
557  t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
558  t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
559 
560  t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
561  t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
562  t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
563  );
564 }
565 
567 template<class Cmpt>
568 #if defined(__GNUC__) && !defined(__clang__)
569 // Workaround for gcc (11+) that fails to handle tensor dot vector
570 __attribute__((optimize("no-tree-vectorize")))
571 #endif
572 inline Foam::Tensor<Cmpt>
574 {
575  const Tensor<Cmpt>& t1 = *this;
576 
577  return Tensor<Cmpt>
578  (
579  t1.xx()*t2.xx(), t1.xy()*t2.xy(), t1.xz()*t2.xz(),
580  t1.yx()*t2.yx(), t1.yy()*t2.yy(), t1.yz()*t2.yz(),
581  t1.zx()*t2.zx(), t1.zy()*t2.zy(), t1.zz()*t2.zz()
582  );
583 }
584 
585 
586 // Invert without much error handling
587 template<class Cmpt>
589 {
590  const Cmpt detval = this->det();
591 
592  #ifdef FULLDEBUG
593  if (mag(detval) < VSMALL)
594  {
596  << "Tensor not properly invertible, determinant:"
597  << detval << " tensor:" << *this << nl
598  << abort(FatalError);
599  }
600  #endif
602  return this->adjunct()/detval;
603 }
604 
605 
606 // Invert with some error handling
607 template<class Cmpt>
609 {
610  {
611  // Attempt to identify and handle 2-D cases
612  // - use diagSqr instead of magSqr for fewer operations
613 
614  const scalar magSqr_xx = Foam::magSqr(xx());
615  const scalar magSqr_yy = Foam::magSqr(yy());
616  const scalar magSqr_zz = Foam::magSqr(zz());
617 
618  // SMALL: 1e-15 (double), 1e-6 (float), but 1e-6 may be adequate
619 
620  const scalar threshold = SMALL * (magSqr_xx + magSqr_yy + magSqr_zz);
621 
622  const bool small_xx = (magSqr_xx < threshold);
623  const bool small_yy = (magSqr_yy < threshold);
624  const bool small_zz = (magSqr_zz < threshold);
625 
626  if (small_xx || small_yy || small_zz)
627  {
628  Tensor<Cmpt> work(*this);
629 
630  if (small_xx) { work.xx() += pTraits<Cmpt>::one; }
631  if (small_yy) { work.yy() += pTraits<Cmpt>::one; }
632  if (small_zz) { work.zz() += pTraits<Cmpt>::one; }
633 
634  const Cmpt detval = work.det();
635 
636  if (mag(detval) < ROOTVSMALL)
637  {
638  // Appears to be nearly zero - leave untouched?
639  return Tensor<Cmpt>(Zero);
640  }
641 
642  work = work.adjunct()/detval;
643 
644  if (small_xx) { work.xx() -= pTraits<Cmpt>::one; }
645  if (small_yy) { work.yy() -= pTraits<Cmpt>::one; }
646  if (small_zz) { work.zz() -= pTraits<Cmpt>::one; }
647 
648  return work;
649  }
650  }
651 
652  const Cmpt detval = this->det();
653 
654  if (mag(detval) < ROOTVSMALL)
655  {
656  // Appears to be nearly zero - leave untouched?
657  return Tensor<Cmpt>(Zero);
658  }
659 
660  return this->adjunct()/detval;
661 }
662 
663 
664 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
665 
666 template<class Cmpt>
667 inline void Foam::Tensor<Cmpt>::operator&=(const Tensor<Cmpt>& t)
668 {
669  *this = this->inner(t);
670 }
671 
672 
673 template<class Cmpt>
674 template<class Cmpt2>
675 inline void Foam::Tensor<Cmpt>::operator=
676 (
677  const VectorSpace<Tensor<Cmpt2>, Cmpt2, 9>& vs
678 )
679 {
680  VectorSpace<Tensor<Cmpt>, Cmpt, 9>::operator=(vs);
681 }
682 
683 
684 template<class Cmpt>
686 {
687  this->v_[XX] = st.ii(); this->v_[XY] = Zero; this->v_[XZ] = Zero;
688  this->v_[YX] = Zero; this->v_[YY] = st.ii(); this->v_[YZ] = Zero;
689  this->v_[ZX] = Zero; this->v_[ZY] = Zero; this->v_[ZZ] = st.ii();
690 }
691 
692 
693 template<class Cmpt>
694 inline void Foam::Tensor<Cmpt>::operator=(const SymmTensor<Cmpt>& st)
695 {
696  this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
697  this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
698  this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
699 }
700 
701 
702 template<class Cmpt>
704 {
705  this->v_[XX] = tr.x().x();
706  this->v_[XY] = tr.x().y();
707  this->v_[XZ] = tr.x().z();
708 
709  this->v_[YX] = tr.y().x();
710  this->v_[YY] = tr.y().y();
711  this->v_[YZ] = tr.y().z();
712 
713  this->v_[ZX] = tr.z().x();
714  this->v_[ZY] = tr.z().y();
715  this->v_[ZZ] = tr.z().z();
716 }
717 
718 
719 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
720 
721 namespace Foam
722 {
724 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
725 
726 //- Return the trace of a Tensor
727 template<class Cmpt>
728 inline Cmpt tr(const Tensor<Cmpt>& t)
729 {
730  return t.xx() + t.yy() + t.zz();
731 }
732 
734 //- Return the spherical part of a Tensor
735 template<class Cmpt>
736 inline SphericalTensor<Cmpt> sph(const Tensor<Cmpt>& t)
737 {
738  return SphericalTensor<Cmpt>
739  (
740  (1.0/3.0)*tr(t)
741  );
742 }
743 
744 
745 //- Return the symmetric part of a Tensor
746 template<class Cmpt>
747 inline SymmTensor<Cmpt> symm(const Tensor<Cmpt>& t)
748 {
749  return SymmTensor<Cmpt>
750  (
751  t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
752  t.yy(), 0.5*(t.yz() + t.zy()),
753  t.zz()
754  );
755 }
756 
757 
758 //- Return twice the symmetric part of a Tensor
759 template<class Cmpt>
760 inline SymmTensor<Cmpt> twoSymm(const Tensor<Cmpt>& t)
761 {
762  return SymmTensor<Cmpt>
763  (
764  2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
765  2*t.yy(), (t.yz() + t.zy()),
766  2*t.zz()
767  );
768 }
769 
770 
771 //- Return the deviatoric part of the symmetric part of a Tensor
772 template<class Cmpt>
773 inline SymmTensor<Cmpt> devSymm(const Tensor<Cmpt>& t)
774 {
775  const Cmpt sph(tr(t)/3.0);
777  return SymmTensor<Cmpt>
778  (
779  t.xx() - sph, 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
780  t.yy() - sph, 0.5*(t.yz() + t.zy()),
781  t.zz() - sph
782  );
783 }
784 
785 
786 //- Return the deviatoric part of twice the symmetric part of a Tensor
787 template<class Cmpt>
788 inline SymmTensor<Cmpt> devTwoSymm(const Tensor<Cmpt>& t)
789 {
790  const Cmpt sph((2.0/3.0)*tr(t));
791 
792  return SymmTensor<Cmpt>
793  (
794  2*t.xx() - sph, (t.xy() + t.yx()), (t.xz() + t.zx()),
795  2*t.yy() - sph, (t.yz() + t.zy()),
796  2*t.zz() - sph
797  );
798 }
799 
800 
801 //- Return the skew-symmetric part of a Tensor
802 template<class Cmpt>
803 inline Tensor<Cmpt> skew(const Tensor<Cmpt>& t)
804 {
805  return Tensor<Cmpt>
806  (
807  Zero, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
808  0.5*(t.yx() - t.xy()), Zero, 0.5*(t.yz() - t.zy()),
809  0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), Zero
810  );
811 }
812 
813 
814 //- Return the skew-symmetric part of a SymmTensor as a Tensor
815 template<class Cmpt>
816 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
817 {
818  return Tensor<Cmpt>::zero;
819 }
820 
821 
822 //- Return the deviatoric part of a Tensor
823 template<class Cmpt>
824 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
825 {
826  return t - sph(t);
827 }
828 
829 
830 //- Return the two-third deviatoric part of a Tensor
831 template<class Cmpt>
832 inline Tensor<Cmpt> dev2(const Tensor<Cmpt>& t)
833 {
834  return t - 2*sph(t);
835 }
836 
837 
838 //- Return the determinant of a Tensor
839 template<class Cmpt>
840 inline Cmpt det(const Tensor<Cmpt>& t)
841 {
842  return t.det();
843 }
844 
846 //- Return the cofactor Tensor of a Tensor
847 template<class Cmpt>
848 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
849 {
850  return t.cof();
851 }
852 
853 
854 //- Return the inverse of a Tensor, using the given determinant value
855 template<class Cmpt>
856 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt detval)
857 {
858  #ifdef FULLDEBUG
859  if (mag(detval) < VSMALL)
860  {
862  << "Tensor not properly invertible, determinant:"
863  << detval << " tensor:" << t << nl
864  << abort(FatalError);
865  }
866  #endif
867 
868  return t.adjunct()/detval;
869 }
870 
871 
872 //- Return the inverse of a Tensor
873 template<class Cmpt>
874 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
875 {
876  return t.inv();
877 }
878 
879 
880 //- Return the 1st invariant of a Tensor
881 template<class Cmpt>
882 inline Cmpt invariantI(const Tensor<Cmpt>& t)
883 {
884  return tr(t);
885 }
886 
887 
888 //- Return the 2nd invariant of a Tensor
889 template<class Cmpt>
890 inline Cmpt invariantII(const Tensor<Cmpt>& t)
891 {
892  return
893  (
894  t.xx()*t.yy() + t.yy()*t.zz() + t.xx()*t.zz()
895  - t.xy()*t.yx() - t.yz()*t.zy() - t.xz()*t.zx()
896  );
897 }
898 
899 
900 //- Return the 3rd invariant of a Tensor
901 template<class Cmpt>
902 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
903 {
904  return det(t);
905 }
906 
907 
908 //- Linear interpolation of tensors a and b by factor t
909 template<class Cmpt>
910 inline Tensor<Cmpt> lerp
911 (
912  const Tensor<Cmpt>& a,
913  const Tensor<Cmpt>& b,
914  const scalar t
915 )
916 {
917  const scalar onet = (1-t);
918 
919  return Tensor<Cmpt>
920  (
921  onet*a.xx() + t*b.xx(),
922  onet*a.xy() + t*b.xy(),
923  onet*a.xz() + t*b.xz(),
924  onet*a.yx() + t*b.yx(),
925  onet*a.yy() + t*b.yy(),
926  onet*a.yz() + t*b.yz(),
927  onet*a.zx() + t*b.zx(),
928  onet*a.zy() + t*b.zy(),
929  onet*a.zz() + t*b.zz()
930  );
931 }
932 
933 
934 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
935 
936 //- Sum of a SphericalTensor and a Tensor
937 template<class Cmpt>
938 inline Tensor<Cmpt>
939 operator+(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
940 {
941  return Tensor<Cmpt>
942  (
943  st1.ii() + t2.xx(), t2.xy(), t2.xz(),
944  t2.yx(), st1.ii() + t2.yy(), t2.yz(),
945  t2.zx(), t2.zy(), st1.ii() + t2.zz()
946  );
947 }
948 
949 
950 //- Sum of a Tensor and a SphericalTensor
951 template<class Cmpt>
952 inline Tensor<Cmpt>
953 operator+(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
954 {
955  return Tensor<Cmpt>
956  (
957  t1.xx() + st2.ii(), t1.xy(), t1.xz(),
958  t1.yx(), t1.yy() + st2.ii(), t1.yz(),
959  t1.zx(), t1.zy(), t1.zz() + st2.ii()
960  );
961 }
962 
963 
964 //- Sum of a SymmTensor and a Tensor
965 template<class Cmpt>
966 inline Tensor<Cmpt>
967 operator+(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
968 {
969  return Tensor<Cmpt>
970  (
971  st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
972  st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
973  st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
974  );
975 }
976 
977 
978 //- Sum of a Tensor and a SymmTensor
979 template<class Cmpt>
980 inline Tensor<Cmpt>
981 operator+(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
982 {
983  return Tensor<Cmpt>
984  (
985  t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
986  t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
987  t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
988  );
989 }
990 
991 
992 //- Subtract a Tensor from a SphericalTensor
993 template<class Cmpt>
994 inline Tensor<Cmpt>
995 operator-(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
996 {
997  return Tensor<Cmpt>
998  (
999  st1.ii() - t2.xx(), -t2.xy(), -t2.xz(),
1000  -t2.yx(), st1.ii() - t2.yy(), -t2.yz(),
1001  -t2.zx(), -t2.zy(), st1.ii() - t2.zz()
1002  );
1003 }
1004 
1005 
1006 //- Subtract a SphericalTensor from a Tensor
1007 template<class Cmpt>
1008 inline Tensor<Cmpt>
1009 operator-(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
1010 {
1011  return Tensor<Cmpt>
1012  (
1013  t1.xx() - st2.ii(), t1.xy(), t1.xz(),
1014  t1.yx(), t1.yy() - st2.ii(), t1.yz(),
1015  t1.zx(), t1.zy(), t1.zz() - st2.ii()
1016  );
1017 }
1019 
1020 //- Subtract a Tensor from a SymmTensor
1021 template<class Cmpt>
1022 inline Tensor<Cmpt>
1023 operator-(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1024 {
1025  return Tensor<Cmpt>
1026  (
1027  st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
1028  st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
1029  st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
1030  );
1031 }
1032 
1033 
1034 //- Subtract a SymmTensor from a Tensor
1035 template<class Cmpt>
1036 inline Tensor<Cmpt>
1037 operator-(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1038 {
1039  return Tensor<Cmpt>
1040  (
1041  t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
1042  t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
1043  t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
1044  );
1045 }
1046 
1047 
1048 //- Return the Hodge dual of a Tensor as a Vector
1049 template<class Cmpt>
1051 {
1052  return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
1053 }
1054 
1055 
1056 //- Return the Hodge dual of a Vector as a Tensor
1057 template<class Cmpt>
1058 inline Tensor<Cmpt> operator*(const Vector<Cmpt>& v)
1059 {
1060  return Tensor<Cmpt>
1061  (
1062  Zero, -v.z(), v.y(),
1063  v.z(), Zero, -v.x(),
1064  -v.y(), v.x(), Zero
1065  );
1067 
1068 
1069 //- Division of a Vector by a Tensor
1070 template<class Cmpt>
1071 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt>>::type
1072 operator/(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
1073 {
1074  return inv(t) & v;
1075 }
1076 
1077 
1078 //- Division of a Tensor by a Cmpt
1079 template<class Cmpt>
1080 inline Tensor<Cmpt>
1081 operator/(const Tensor<Cmpt>& t, const Cmpt s)
1083  #ifdef FULLDEBUG
1084  if (mag(s) < VSMALL)
1085  {
1087  << "Tensor = " << t
1088  << " is not divisible due to a zero value in Cmpt:"
1089  << "Cmpt = " << s
1090  << abort(FatalError);
1091  }
1092  #endif
1093 
1094  return Tensor<Cmpt>
1095  (
1096  t.xx()/s, t.xy()/s, t.xz()/s,
1097  t.yx()/s, t.yy()/s, t.yz()/s,
1098  t.zx()/s, t.zy()/s, t.zz()/s
1099  );
1100 }
1101 
1102 
1103 //- Inner-product of a Tensor and a Tensor
1104 template<class Cmpt>
1105 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt>>::type
1106 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
1108  return t1.inner(t2);
1109 }
1110 
1111 
1112 //- Inner-product of a SphericalTensor and a Tensor
1113 template<class Cmpt>
1114 #if defined(__GNUC__) && !defined(__clang__)
1115 // Workaround for gcc (11+) that fails to handle tensor dot vector
1116 __attribute__((optimize("no-tree-vectorize")))
1117 #endif
1118 inline Tensor<Cmpt>
1119 operator&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1120 {
1121  return Tensor<Cmpt>
1122  (
1123  st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
1124  st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
1125  st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
1126  );
1127 }
1128 
1129 
1130 //- Inner-product of a Tensor and a SphericalTensor
1131 template<class Cmpt>
1132 #if defined(__GNUC__) && !defined(__clang__)
1133 // Workaround for gcc (11+) that fails to handle tensor dot vector
1134 __attribute__((optimize("no-tree-vectorize")))
1135 #endif
1136 inline Tensor<Cmpt>
1137 operator&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
1138 {
1139  return Tensor<Cmpt>
1140  (
1141  t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
1142  t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
1143  t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
1144  );
1145 }
1146 
1147 
1148 //- Inner-product of a SymmTensor and a Tensor
1149 template<class Cmpt>
1150 #if defined(__GNUC__) && !defined(__clang__)
1151 // Workaround for gcc (11+) that fails to handle tensor dot vector
1152 __attribute__((optimize("no-tree-vectorize")))
1153 #endif
1154 inline Tensor<Cmpt>
1155 operator&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1156 {
1157  return Tensor<Cmpt>
1158  (
1159  st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
1160  st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
1161  st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
1162 
1163  st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
1164  st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
1165  st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
1166 
1167  st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
1168  st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
1169  st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
1170  );
1171 }
1172 
1173 
1174 //- Inner-product of a Tensor and a SymmTensor
1175 template<class Cmpt>
1176 #if defined(__GNUC__) && !defined(__clang__)
1177 // Workaround for gcc (11+) that fails to handle tensor dot vector
1178 __attribute__((optimize("no-tree-vectorize")))
1179 #endif
1180 inline Tensor<Cmpt>
1181 operator&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1182 {
1183  return Tensor<Cmpt>
1184  (
1185  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
1186  t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
1187  t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
1188 
1189  t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
1190  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
1191  t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
1192 
1193  t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
1194  t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
1195  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1196  );
1197 }
1198 
1199 
1200 //- Inner-product of a Tensor and a Vector
1201 template<class Cmpt>
1202 #if defined(__GNUC__) && !defined(__clang__)
1203 // Workaround for gcc (11+) that fails to handle tensor dot vector
1204 __attribute__((optimize("no-tree-vectorize")))
1205 #endif
1206 inline Vector<Cmpt>
1207 operator&(const Tensor<Cmpt>& t, const Vector<Cmpt>& v)
1208 {
1209  return Vector<Cmpt>
1210  (
1211  t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
1212  t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
1213  t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
1214  );
1215 }
1217 
1218 //- Inner-product of a Vector and a Tensor
1219 template<class Cmpt>
1220 #if defined(__GNUC__) && !defined(__clang__)
1221 // Workaround for gcc (11+) that fails to handle tensor dot vector
1222 __attribute__((optimize("no-tree-vectorize")))
1223 #endif
1224 inline Vector<Cmpt>
1225 operator&(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
1226 {
1227  return Vector<Cmpt>
1228  (
1229  v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
1230  v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
1231  v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
1232  );
1233 }
1234 
1235 
1236 //- Double-inner-product of a SphericalTensor and a Tensor
1237 template<class Cmpt>
1238 inline Cmpt
1239 operator&&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1240 {
1241  return (st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
1242 }
1243 
1245 //- Double-inner-product of a Tensor and a SphericalTensor
1246 template<class Cmpt>
1247 inline Cmpt
1248 operator&&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
1249 {
1250  return (t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
1251 }
1252 
1253 
1254 //- Double-inner-product of a SymmTensor and a Tensor
1255 template<class Cmpt>
1256 inline Cmpt
1257 operator&&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
1258 {
1259  return
1260  (
1261  st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
1262  st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
1263  st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
1264  );
1265 }
1266 
1267 
1268 //- Double-inner-product of a Tensor and a SymmTensor
1269 template<class Cmpt>
1270 inline Cmpt
1271 operator&&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
1273  return
1274  (
1275  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
1276  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
1277  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
1278  );
1279 }
1280 
1281 
1282 //- Outer-product of a Vector and a Vector
1283 template<class Cmpt>
1284 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt>>::type
1285 operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2)
1286 {
1287  return Tensor<Cmpt>
1288  (
1289  v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
1290  v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
1291  v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
1292  );
1293 }
1294 
1295 
1296 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1297 
1298 template<class Cmpt>
1299 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt>>
1300 {
1301 public:
1302 
1303  typedef Tensor<Cmpt> type;
1304 };
1305 
1306 
1307 template<class Cmpt>
1308 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt>>
1309 {
1310 public:
1311 
1312  typedef Tensor<Cmpt> type;
1313 };
1314 
1315 
1316 template<class Cmpt>
1317 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt>>
1318 {
1319 public:
1320 
1321  typedef Tensor<Cmpt> type;
1322 };
1323 
1324 
1325 template<class Cmpt>
1326 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt>>
1327 {
1328 public:
1329 
1331 };
1332 
1333 
1334 template<class Cmpt>
1335 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt>>
1336 {
1337 public:
1338 
1339  typedef Tensor<Cmpt> type;
1340 };
1341 
1342 
1343 template<class Cmpt>
1344 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt>>
1345 {
1346 public:
1347 
1348  typedef Tensor<Cmpt> type;
1349 };
1350 
1351 
1352 template<class Cmpt>
1353 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt>>
1354 {
1355 public:
1356 
1357  typedef Tensor<Cmpt> type;
1358 };
1359 
1360 
1361 template<class Cmpt>
1362 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt>>
1363 {
1364 public:
1365 
1366  typedef Tensor<Cmpt> type;
1367 };
1368 
1369 
1370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1371 
1372 } // End namespace Foam
1373 
1374 // ************************************************************************* //
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:723
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:608
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:855
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:581
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:566
Tensor< Cmpt > safeInv() const
Return inverse, with (ad hoc) failsafe handling of 2D tensors.
Definition: TensorI.H:601
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:539
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