1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36 inline Tensor<Cmpt>::Tensor()
40 //- Construct given VectorSpace
42 inline Tensor<Cmpt>::Tensor(const VectorSpace<Tensor<Cmpt>, Cmpt, 9>& vs)
44 VectorSpace<Tensor<Cmpt>, Cmpt, 9>(vs)
48 //- Construct given SphericalTensor
50 inline Tensor<Cmpt>::Tensor(const SphericalTensor<Cmpt>& st)
52 this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
53 this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
54 this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
58 //- Construct given SymmTensor
60 inline Tensor<Cmpt>::Tensor(const SymmTensor<Cmpt>& st)
62 this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
63 this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
64 this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
68 //- Construct from components
70 inline Tensor<Cmpt>::Tensor
72 const Cmpt txx, const Cmpt txy, const Cmpt txz,
73 const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
74 const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
77 this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
78 this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
79 this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
83 //- Construct from Istream
85 inline Tensor<Cmpt>::Tensor(Istream& is)
87 VectorSpace<Tensor<Cmpt>, Cmpt, 9>(is)
91 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
94 inline const Vector<Cmpt>& Tensor<Cmpt>::x() const
96 return reinterpret_cast<const Vector<Cmpt>&>(this->v_[XX]);
100 inline const Vector<Cmpt>& Tensor<Cmpt>::y() const
102 return reinterpret_cast<const Vector<Cmpt>&>(this->v_[YX]);
105 template <class Cmpt>
106 inline const Vector<Cmpt>& Tensor<Cmpt>::z() const
108 return reinterpret_cast<const Vector<Cmpt>&>(this->v_[ZX]);
112 template <class Cmpt>
113 inline Vector<Cmpt>& Tensor<Cmpt>::x()
115 return reinterpret_cast<Vector<Cmpt>&>(this->v_[XX]);
118 template <class Cmpt>
119 inline Vector<Cmpt>& Tensor<Cmpt>::y()
121 return reinterpret_cast<Vector<Cmpt>&>(this->v_[YX]);
124 template <class Cmpt>
125 inline Vector<Cmpt>& Tensor<Cmpt>::z()
127 return reinterpret_cast<Vector<Cmpt>&>(this->v_[ZX]);
131 template <class Cmpt>
132 inline const Cmpt& Tensor<Cmpt>::xx() const
137 template <class Cmpt>
138 inline const Cmpt& Tensor<Cmpt>::xy() const
143 template <class Cmpt>
144 inline const Cmpt& Tensor<Cmpt>::xz() const
150 template <class Cmpt>
151 inline const Cmpt& Tensor<Cmpt>::yx() const
156 template <class Cmpt>
157 inline const Cmpt& Tensor<Cmpt>::yy() const
162 template <class Cmpt>
163 inline const Cmpt& Tensor<Cmpt>::yz() const
169 template <class Cmpt>
170 inline const Cmpt& Tensor<Cmpt>::zx() const
175 template <class Cmpt>
176 inline const Cmpt& Tensor<Cmpt>::zy() const
181 template <class Cmpt>
182 inline const Cmpt& Tensor<Cmpt>::zz() const
188 template <class Cmpt>
189 inline Cmpt& Tensor<Cmpt>::xx()
194 template <class Cmpt>
195 inline Cmpt& Tensor<Cmpt>::xy()
200 template <class Cmpt>
201 inline Cmpt& Tensor<Cmpt>::xz()
207 template <class Cmpt>
208 inline Cmpt& Tensor<Cmpt>::yx()
213 template <class Cmpt>
214 inline Cmpt& Tensor<Cmpt>::yy()
219 template <class Cmpt>
220 inline Cmpt& Tensor<Cmpt>::yz()
226 template <class Cmpt>
227 inline Cmpt& Tensor<Cmpt>::zx()
232 template <class Cmpt>
233 inline Cmpt& Tensor<Cmpt>::zy()
238 template <class Cmpt>
239 inline Cmpt& Tensor<Cmpt>::zz()
245 //- Return tensor transpose
246 template <class Cmpt>
247 inline Tensor<Cmpt> Tensor<Cmpt>::T() const
258 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
260 template <class Cmpt>
261 inline void Tensor<Cmpt>::operator=(const SphericalTensor<Cmpt>& st)
263 this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
264 this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
265 this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
269 template <class Cmpt>
270 inline void Tensor<Cmpt>::operator=(const SymmTensor<Cmpt>& st)
272 this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
273 this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
274 this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
278 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
280 //- Hodge Dual operator (tensor -> vector)
281 template <class Cmpt>
282 inline Vector<Cmpt> operator*(const Tensor<Cmpt>& t)
284 return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
288 //- Hodge Dual operator (vector -> tensor)
289 template <class Cmpt>
290 inline Tensor<Cmpt> operator*(const Vector<Cmpt>& v)
301 //- Inner-product between two tensors
302 template <class Cmpt>
303 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt> >::type
304 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
308 t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
309 t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
310 t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
312 t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
313 t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
314 t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
316 t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
317 t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
318 t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
323 //- Inner-product between a tensor and a vector
324 template <class Cmpt>
325 inline typename innerProduct<Tensor<Cmpt>, Vector<Cmpt> >::type
326 operator&(const Tensor<Cmpt>& t, const Vector<Cmpt>& v)
330 t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
331 t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
332 t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
337 //- Inner-product between a vector and a tensor
338 template <class Cmpt>
339 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
340 operator&(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
344 v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
345 v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
346 v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
351 //- Outer-product between two vectors
352 template <class Cmpt>
353 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt> >::type
354 operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2)
358 v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
359 v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
360 v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
365 //- Division of a vector by a tensor, i.e. dot-product with the tensor inverse
366 template <class Cmpt>
367 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
368 operator/(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
374 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
376 //- Return the trace of a tensor
377 template <class Cmpt>
378 inline Cmpt tr(const Tensor<Cmpt>& t)
380 return t.xx() + t.yy() + t.zz();
384 //- Return the spherical part of a tensor
385 template <class Cmpt>
386 inline SphericalTensor<Cmpt> sph(const Tensor<Cmpt>& t)
388 return (1.0/3.0)*tr(t);
392 //- Return the symmetric part of a tensor
393 template <class Cmpt>
394 inline SymmTensor<Cmpt> symm(const Tensor<Cmpt>& t)
396 return SymmTensor<Cmpt>
398 t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
399 t.yy(), 0.5*(t.yz() + t.zy()),
405 //- Return twice the symmetric part of a tensor
406 template <class Cmpt>
407 inline SymmTensor<Cmpt> twoSymm(const Tensor<Cmpt>& t)
409 return SymmTensor<Cmpt>
411 2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
412 2*t.yy(), (t.yz() + t.zy()),
418 //- Return the skew-symmetric part of a tensor
419 template <class Cmpt>
420 inline Tensor<Cmpt> skew(const Tensor<Cmpt>& t)
424 0.0, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
425 0.5*(t.yx() - t.xy()), 0.0, 0.5*(t.yz() - t.zy()),
426 0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), 0.0
431 //- Return the skew-symmetric part of a symmetric tensor
432 template <class Cmpt>
433 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
435 return Tensor<Cmpt>::zero;
439 //- Return the deviatoric part of a tensor
440 template <class Cmpt>
441 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
443 return t - SphericalTensor<Cmpt>::oneThirdI*tr(t);
447 //- Return the deviatoric part of a tensor
448 template <class Cmpt>
449 inline Tensor<Cmpt> dev2(const Tensor<Cmpt>& t)
451 return t - SphericalTensor<Cmpt>::twoThirdsI*tr(t);
455 //- Return the determinant of a tensor
456 template <class Cmpt>
457 inline Cmpt det(const Tensor<Cmpt>& t)
461 t.xx()*t.yy()*t.zz() + t.xy()*t.yz()*t.zx()
462 + t.xz()*t.yx()*t.zy() - t.xx()*t.yz()*t.zy()
463 - t.xy()*t.yx()*t.zz() - t.xz()*t.yy()*t.zx()
468 //- Return the cofactor tensor of a tensor
469 template <class Cmpt>
470 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
474 t.yy()*t.zz() - t.zy()*t.yz(),
475 t.zx()*t.yz() - t.yx()*t.zz(),
476 t.yx()*t.zy() - t.yy()*t.zx(),
478 t.xz()*t.zy() - t.xy()*t.zz(),
479 t.xx()*t.zz() - t.xz()*t.zx(),
480 t.xy()*t.zx() - t.xx()*t.zy(),
482 t.xy()*t.yz() - t.xz()*t.yy(),
483 t.yx()*t.xz() - t.xx()*t.yz(),
484 t.xx()*t.yy() - t.yx()*t.xy()
489 //- Return the inverse of a tensor give the determinant
490 template <class Cmpt>
491 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett)
495 t.yy()*t.zz() - t.zy()*t.yz(),
496 t.xz()*t.zy() - t.xy()*t.zz(),
497 t.xy()*t.yz() - t.xz()*t.yy(),
499 t.zx()*t.yz() - t.yx()*t.zz(),
500 t.xx()*t.zz() - t.xz()*t.zx(),
501 t.yx()*t.xz() - t.xx()*t.yz(),
503 t.yx()*t.zy() - t.yy()*t.zx(),
504 t.xy()*t.zx() - t.xx()*t.zy(),
505 t.xx()*t.yy() - t.yx()*t.xy()
510 //- Return the inverse of a tensor
511 template <class Cmpt>
512 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
514 return inv(t, det(t));
518 //- Return the 1st invariant of a tensor
519 template <class Cmpt>
520 inline Cmpt invariantI(const Tensor<Cmpt>& t)
526 //- Return the 2nd invariant of a tensor
527 template <class Cmpt>
528 inline Cmpt invariantII(const Tensor<Cmpt>& t)
535 t.xx()*t.xx() + t.xy()*t.xy() + t.xz()*t.xz()
536 + t.yx()*t.yx() + t.yy()*t.yy() + t.yz()*t.yz()
537 + t.zx()*t.zx() + t.zy()*t.zy() + t.zz()*t.zz()
543 //- Return the 3rd invariant of a tensor
544 template <class Cmpt>
545 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
551 // * * * * * * * * * Mixed Tensor SphericalTensor Operators * * * * * * * * //
553 template <class Cmpt>
555 operator+(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
559 st1.ii() + t2.xx(), t2.xy(), t2.xz(),
560 t2.yx(), st1.ii() + t2.yy(), t2.yz(),
561 t2.zx(), t2.zy(), st1.ii() + t2.zz()
566 template <class Cmpt>
568 operator+(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
572 t1.xx() + st2.ii(), t1.xy(), t1.xz(),
573 t1.yx(), t1.yy() + st2.ii(), t1.yz(),
574 t1.zx(), t1.zy(), t1.zz() + st2.ii()
579 template <class Cmpt>
581 operator-(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
585 st1.ii() - t2.xx(), -t2.xy(), -t2.xz(),
586 -t2.yx(), st1.ii() - t2.yy(), -t2.yz(),
587 -t2.zx(), -t2.zy(), st1.ii() - t2.zz()
592 template <class Cmpt>
594 operator-(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
598 t1.xx() - st2.ii(), t1.xy(), t1.xz(),
599 t1.yx(), t1.yy() - st2.ii(), t1.yz(),
600 t1.zx(), t1.zy(), t1.zz() - st2.ii()
605 //- Inner-product between a spherical tensor and a tensor
606 template <class Cmpt>
608 operator&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
612 st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
613 st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
614 st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
619 //- Inner-product between a tensor and a spherical tensor
620 template <class Cmpt>
622 operator&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
626 t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
627 t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
628 t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
633 //- Double-dot-product between a spherical tensor and a tensor
634 template <class Cmpt>
636 operator&&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
638 return(st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
642 //- Double-dot-product between a tensor and a spherical tensor
643 template <class Cmpt>
645 operator&&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
647 return(t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
651 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt> >
655 typedef Tensor<Cmpt> type;
659 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt> >
663 typedef Tensor<Cmpt> type;
667 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt> >
671 typedef Tensor<Cmpt> type;
675 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt> >
679 typedef Tensor<Cmpt> type;
683 // * * * * * * * * * * Mixed Tensor SymmTensor Operators * * * * * * * * * * //
685 template <class Cmpt>
687 operator+(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
691 st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
692 st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
693 st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
698 template <class Cmpt>
700 operator+(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
704 t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
705 t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
706 t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
711 template <class Cmpt>
713 operator-(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
717 st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
718 st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
719 st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
724 template <class Cmpt>
726 operator-(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
730 t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
731 t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
732 t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
737 //- Inner-product between a spherical tensor and a tensor
738 template <class Cmpt>
740 operator&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
744 st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
745 st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
746 st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
748 st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
749 st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
750 st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
752 st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
753 st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
754 st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
759 //- Inner-product between a tensor and a spherical tensor
760 template <class Cmpt>
762 operator&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
766 t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
767 t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
768 t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
770 t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
771 t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
772 t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
774 t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
775 t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
776 t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
781 //- Double-dot-product between a spherical tensor and a tensor
782 template <class Cmpt>
784 operator&&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
788 st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
789 st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
790 st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
795 //- Double-dot-product between a tensor and a spherical tensor
796 template <class Cmpt>
798 operator&&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
802 t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
803 t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
804 t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
809 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt> >
813 typedef Tensor<Cmpt> type;
817 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt> >
821 typedef Tensor<Cmpt> type;
826 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt> >
830 typedef Tensor<Cmpt> type;
834 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt> >
838 typedef Tensor<Cmpt> type;
842 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
844 } // End namespace Foam
846 // ************************************************************************* //