BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OpenFOAM / primitives / Tensor / TensorI.H
blobcbfe6772e154f68f9d92e226b6167fe93d8a05d0
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
28 namespace Foam
31 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
33 //- Construct null
34 template <class Cmpt>
35 inline Tensor<Cmpt>::Tensor()
39 //- Construct given VectorSpace
40 template <class Cmpt>
41 inline Tensor<Cmpt>::Tensor(const VectorSpace<Tensor<Cmpt>, Cmpt, 9>& vs)
43     VectorSpace<Tensor<Cmpt>, Cmpt, 9>(vs)
47 //- Construct given SphericalTensor
48 template <class Cmpt>
49 inline Tensor<Cmpt>::Tensor(const SphericalTensor<Cmpt>& st)
51     this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
52     this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
53     this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
57 //- Construct given SymmTensor
58 template <class Cmpt>
59 inline Tensor<Cmpt>::Tensor(const SymmTensor<Cmpt>& st)
61     this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
62     this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
63     this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
67 //- Construct given the three vector components
68 template <class Cmpt>
69 inline Tensor<Cmpt>::Tensor
71     const Vector<Cmpt>& x,
72     const Vector<Cmpt>& y,
73     const Vector<Cmpt>& z
76     this->v_[XX] = x.x(); this->v_[XY] = x.y(); this->v_[XZ] = x.z();
77     this->v_[YX] = y.x(); this->v_[YY] = y.y(); this->v_[YZ] = y.z();
78     this->v_[ZX] = z.x(); this->v_[ZY] = z.y(); this->v_[ZZ] = z.z();
82 //- Construct from components
83 template <class Cmpt>
84 inline Tensor<Cmpt>::Tensor
86     const Cmpt txx, const Cmpt txy, const Cmpt txz,
87     const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
88     const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
91     this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
92     this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
93     this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
97 //- Construct from Istream
98 template <class Cmpt>
99 inline Tensor<Cmpt>::Tensor(Istream& is)
101     VectorSpace<Tensor<Cmpt>, Cmpt, 9>(is)
105 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
107 template <class Cmpt>
108 inline const Vector<Cmpt> Tensor<Cmpt>::x() const
110     return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
113 template <class Cmpt>
114 inline const Vector<Cmpt> Tensor<Cmpt>::y() const
116     return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
119 template <class Cmpt>
120 inline const Vector<Cmpt>  Tensor<Cmpt>::z() const
122     return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
126 template <class Cmpt>
127 inline const Cmpt&  Tensor<Cmpt>::xx() const
129     return this->v_[XX];
132 template <class Cmpt>
133 inline const Cmpt&  Tensor<Cmpt>::xy() const
135     return this->v_[XY];
138 template <class Cmpt>
139 inline const Cmpt&  Tensor<Cmpt>::xz() const
141     return this->v_[XZ];
145 template <class Cmpt>
146 inline const Cmpt&  Tensor<Cmpt>::yx() const
148     return this->v_[YX];
151 template <class Cmpt>
152 inline const Cmpt&  Tensor<Cmpt>::yy() const
154     return this->v_[YY];
157 template <class Cmpt>
158 inline const Cmpt&  Tensor<Cmpt>::yz() const
160     return this->v_[YZ];
164 template <class Cmpt>
165 inline const Cmpt&  Tensor<Cmpt>::zx() const
167     return this->v_[ZX];
170 template <class Cmpt>
171 inline const Cmpt&  Tensor<Cmpt>::zy() const
173     return this->v_[ZY];
176 template <class Cmpt>
177 inline const Cmpt&  Tensor<Cmpt>::zz() const
179     return this->v_[ZZ];
183 template <class Cmpt>
184 inline Cmpt& Tensor<Cmpt>::xx()
186     return this->v_[XX];
189 template <class Cmpt>
190 inline Cmpt& Tensor<Cmpt>::xy()
192     return this->v_[XY];
195 template <class Cmpt>
196 inline Cmpt& Tensor<Cmpt>::xz()
198     return this->v_[XZ];
202 template <class Cmpt>
203 inline Cmpt& Tensor<Cmpt>::yx()
205     return this->v_[YX];
208 template <class Cmpt>
209 inline Cmpt& Tensor<Cmpt>::yy()
211     return this->v_[YY];
214 template <class Cmpt>
215 inline Cmpt& Tensor<Cmpt>::yz()
217     return this->v_[YZ];
221 template <class Cmpt>
222 inline Cmpt& Tensor<Cmpt>::zx()
224     return this->v_[ZX];
227 template <class Cmpt>
228 inline Cmpt& Tensor<Cmpt>::zy()
230     return this->v_[ZY];
233 template <class Cmpt>
234 inline Cmpt& Tensor<Cmpt>::zz()
236     return this->v_[ZZ];
240 //- Return tensor transpose
241 template <class Cmpt>
242 inline Tensor<Cmpt> Tensor<Cmpt>::T() const
244     return Tensor<Cmpt>
245     (
246         xx(), yx(), zx(),
247         xy(), yy(), zy(),
248         xz(), yz(), zz()
249     );
253 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
255 template <class Cmpt>
256 inline void Tensor<Cmpt>::operator=(const SphericalTensor<Cmpt>& st)
258     this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
259     this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
260     this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
264 template <class Cmpt>
265 inline void Tensor<Cmpt>::operator=(const SymmTensor<Cmpt>& st)
267     this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
268     this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
269     this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
273 // * * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * //
275 //- Hodge Dual operator (tensor -> vector)
276 template <class Cmpt>
277 inline Vector<Cmpt> operator*(const Tensor<Cmpt>& t)
279     return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
283 //- Hodge Dual operator (vector -> tensor)
284 template <class Cmpt>
285 inline Tensor<Cmpt> operator*(const Vector<Cmpt>& v)
287     return Tensor<Cmpt>
288     (
289              0, -v.z(),   v.y(),
290          v.z(),      0,  -v.x(),
291         -v.y(),  v.x(),       0
292     );
296 //- Inner-product between two tensors
297 template <class Cmpt>
298 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt> >::type
299 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
301     return Tensor<Cmpt>
302     (
303         t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
304         t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
305         t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
307         t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
308         t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
309         t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
311         t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
312         t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
313         t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
314     );
318 //- Inner-product between a tensor and a vector
319 template <class Cmpt>
320 inline typename innerProduct<Tensor<Cmpt>, Vector<Cmpt> >::type
321 operator&(const Tensor<Cmpt>& t, const Vector<Cmpt>& v)
323     return Vector<Cmpt>
324     (
325         t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
326         t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
327         t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
328     );
332 //- Inner-product between a vector and a tensor
333 template <class Cmpt>
334 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
335 operator&(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
337     return Vector<Cmpt>
338     (
339         v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
340         v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
341         v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
342     );
346 //- Outer-product between two vectors
347 template <class Cmpt>
348 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt> >::type
349 operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2)
351     return Tensor<Cmpt>
352     (
353         v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
354         v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
355         v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
356     );
360 //- Division of a vector by a tensor, i.e. dot-product with the tensor inverse
361 template <class Cmpt>
362 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
363 operator/(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
365     return inv(t) & v;
369 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
371 //- Return the trace of a tensor
372 template <class Cmpt>
373 inline Cmpt tr(const Tensor<Cmpt>& t)
375     return t.xx() + t.yy() + t.zz();
379 //- Return the spherical part of a tensor
380 template <class Cmpt>
381 inline SphericalTensor<Cmpt> sph(const Tensor<Cmpt>& t)
383     return (1.0/3.0)*tr(t);
387 //- Return the symmetric part of a tensor
388 template <class Cmpt>
389 inline SymmTensor<Cmpt> symm(const Tensor<Cmpt>& t)
391     return SymmTensor<Cmpt>
392     (
393         t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
394                 t.yy(),                0.5*(t.yz() + t.zy()),
395                                        t.zz()
396     );
400 //- Return twice the symmetric part of a tensor
401 template <class Cmpt>
402 inline SymmTensor<Cmpt> twoSymm(const Tensor<Cmpt>& t)
404     return SymmTensor<Cmpt>
405     (
406         2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
407                   2*t.yy(),          (t.yz() + t.zy()),
408                                      2*t.zz()
409     );
413 //- Return the skew-symmetric part of a tensor
414 template <class Cmpt>
415 inline Tensor<Cmpt> skew(const Tensor<Cmpt>& t)
417     return Tensor<Cmpt>
418     (
419         0.0, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
420         0.5*(t.yx() - t.xy()), 0.0, 0.5*(t.yz() - t.zy()),
421         0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), 0.0
422     );
426 //- Return the skew-symmetric part of a symmetric tensor
427 template <class Cmpt>
428 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
430     return Tensor<Cmpt>::zero;
434 //- Return the deviatoric part of a tensor
435 template <class Cmpt>
436 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
438     return t - SphericalTensor<Cmpt>::oneThirdI*tr(t);
442 //- Return the deviatoric part of a tensor
443 template <class Cmpt>
444 inline Tensor<Cmpt> dev2(const Tensor<Cmpt>& t)
446     return t - SphericalTensor<Cmpt>::twoThirdsI*tr(t);
450 //- Return the determinant of a tensor
451 template <class Cmpt>
452 inline Cmpt det(const Tensor<Cmpt>& t)
454     return
455     (
456         t.xx()*t.yy()*t.zz() + t.xy()*t.yz()*t.zx()
457       + t.xz()*t.yx()*t.zy() - t.xx()*t.yz()*t.zy()
458       - t.xy()*t.yx()*t.zz() - t.xz()*t.yy()*t.zx()
459     );
463 //- Return the cofactor tensor of a tensor
464 template <class Cmpt>
465 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
467     return Tensor<Cmpt>
468     (
469         t.yy()*t.zz() - t.zy()*t.yz(),
470         t.zx()*t.yz() - t.yx()*t.zz(),
471         t.yx()*t.zy() - t.yy()*t.zx(),
473         t.xz()*t.zy() - t.xy()*t.zz(),
474         t.xx()*t.zz() - t.xz()*t.zx(),
475         t.xy()*t.zx() - t.xx()*t.zy(),
477         t.xy()*t.yz() - t.xz()*t.yy(),
478         t.yx()*t.xz() - t.xx()*t.yz(),
479         t.xx()*t.yy() - t.yx()*t.xy()
480     );
484 //- Return the inverse of a tensor given the determinant
485 template <class Cmpt>
486 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett)
488     return Tensor<Cmpt>
489     (
490         t.yy()*t.zz() - t.zy()*t.yz(),
491         t.xz()*t.zy() - t.xy()*t.zz(),
492         t.xy()*t.yz() - t.xz()*t.yy(),
494         t.zx()*t.yz() - t.yx()*t.zz(),
495         t.xx()*t.zz() - t.xz()*t.zx(),
496         t.yx()*t.xz() - t.xx()*t.yz(),
498         t.yx()*t.zy() - t.yy()*t.zx(),
499         t.xy()*t.zx() - t.xx()*t.zy(),
500         t.xx()*t.yy() - t.yx()*t.xy()
501     )/dett;
505 //- Return the inverse of a tensor
506 template <class Cmpt>
507 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
509     return inv(t, det(t));
513 //- Return the 1st invariant of a tensor
514 template <class Cmpt>
515 inline Cmpt invariantI(const Tensor<Cmpt>& t)
517     return tr(t);
521 //- Return the 2nd invariant of a tensor
522 template <class Cmpt>
523 inline Cmpt invariantII(const Tensor<Cmpt>& t)
525     return
526     (
527         0.5*sqr(tr(t))
528       - 0.5*
529         (
530            t.xx()*t.xx() + t.xy()*t.xy() + t.xz()*t.xz()
531          + t.yx()*t.yx() + t.yy()*t.yy() + t.yz()*t.yz()
532          + t.zx()*t.zx() + t.zy()*t.zy() + t.zz()*t.zz()
533         )
534     );
538 //- Return the 3rd invariant of a tensor
539 template <class Cmpt>
540 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
542     return det(t);
546 // * * * * * * * * * Mixed Tensor SphericalTensor Operators  * * * * * * * * //
548 template <class Cmpt>
549 inline Tensor<Cmpt>
550 operator+(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
552     return Tensor<Cmpt>
553     (
554         st1.ii() + t2.xx(), t2.xy(),            t2.xz(),
555         t2.yx(),            st1.ii() + t2.yy(), t2.yz(),
556         t2.zx(),            t2.zy(),            st1.ii() + t2.zz()
557     );
561 template <class Cmpt>
562 inline Tensor<Cmpt>
563 operator+(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
565     return Tensor<Cmpt>
566     (
567         t1.xx() + st2.ii(), t1.xy(),            t1.xz(),
568         t1.yx(),            t1.yy() + st2.ii(), t1.yz(),
569         t1.zx(),            t1.zy(),            t1.zz() + st2.ii()
570     );
574 template <class Cmpt>
575 inline Tensor<Cmpt>
576 operator-(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
578     return Tensor<Cmpt>
579     (
580         st1.ii() - t2.xx(), -t2.xy(),            -t2.xz(),
581        -t2.yx(),             st1.ii() - t2.yy(), -t2.yz(),
582        -t2.zx(),            -t2.zy(),             st1.ii() - t2.zz()
583     );
587 template <class Cmpt>
588 inline Tensor<Cmpt>
589 operator-(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
591     return Tensor<Cmpt>
592     (
593         t1.xx() - st2.ii(), t1.xy(),            t1.xz(),
594         t1.yx(),            t1.yy() - st2.ii(), t1.yz(),
595         t1.zx(),            t1.zy(),            t1.zz() - st2.ii()
596     );
600 //- Inner-product between a spherical tensor and a tensor
601 template <class Cmpt>
602 inline Tensor<Cmpt>
603 operator&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
605     return Tensor<Cmpt>
606     (
607         st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
608         st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
609         st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
610     );
614 //- Inner-product between a tensor and a spherical tensor
615 template <class Cmpt>
616 inline Tensor<Cmpt>
617 operator&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
619     return Tensor<Cmpt>
620     (
621         t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
622         t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
623         t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
624     );
628 //- Double-dot-product between a spherical tensor and a tensor
629 template <class Cmpt>
630 inline Cmpt
631 operator&&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
633     return(st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
637 //- Double-dot-product between a tensor and a spherical tensor
638 template <class Cmpt>
639 inline Cmpt
640 operator&&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
642     return(t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
645 template<class Cmpt>
646 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt> >
648 public:
650     typedef Tensor<Cmpt> type;
653 template<class Cmpt>
654 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt> >
656 public:
658     typedef Tensor<Cmpt> type;
661 template<class Cmpt>
662 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt> >
664 public:
666     typedef Tensor<Cmpt> type;
669 template<class Cmpt>
670 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt> >
672 public:
674     typedef Tensor<Cmpt> type;
678 // * * * * * * * * * * Mixed Tensor SymmTensor Operators * * * * * * * * * * //
680 template <class Cmpt>
681 inline Tensor<Cmpt>
682 operator+(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
684     return Tensor<Cmpt>
685     (
686         st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
687         st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
688         st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
689     );
693 template <class Cmpt>
694 inline Tensor<Cmpt>
695 operator+(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
697     return Tensor<Cmpt>
698     (
699         t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
700         t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
701         t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
702     );
706 template <class Cmpt>
707 inline Tensor<Cmpt>
708 operator-(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
710     return Tensor<Cmpt>
711     (
712         st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
713         st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
714         st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
715     );
719 template <class Cmpt>
720 inline Tensor<Cmpt>
721 operator-(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
723     return Tensor<Cmpt>
724     (
725         t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
726         t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
727         t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
728     );
732 //- Inner-product between a spherical tensor and a tensor
733 template <class Cmpt>
734 inline Tensor<Cmpt>
735 operator&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
737     return Tensor<Cmpt>
738     (
739         st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
740         st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
741         st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
743         st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
744         st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
745         st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
747         st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
748         st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
749         st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
750     );
754 //- Inner-product between a tensor and a spherical tensor
755 template <class Cmpt>
756 inline Tensor<Cmpt>
757 operator&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
759     return Tensor<Cmpt>
760     (
761         t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
762         t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
763         t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
765         t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
766         t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
767         t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
769         t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
770         t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
771         t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
772     );
776 //- Double-dot-product between a spherical tensor and a tensor
777 template <class Cmpt>
778 inline Cmpt
779 operator&&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
781     return
782     (
783         st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
784         st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
785         st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
786     );
790 //- Double-dot-product between a tensor and a spherical tensor
791 template <class Cmpt>
792 inline Cmpt
793 operator&&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
795     return
796     (
797         t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
798         t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
799         t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
800     );
803 template<class Cmpt>
804 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt> >
806 public:
808     typedef Tensor<Cmpt> type;
811 template<class Cmpt>
812 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt> >
814 public:
816     typedef Tensor<Cmpt> type;
820 template<class Cmpt>
821 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt> >
823 public:
825     typedef Tensor<Cmpt> type;
828 template<class Cmpt>
829 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt> >
831 public:
833     typedef Tensor<Cmpt> type;
837 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
839 } // End namespace Foam
841 // ************************************************************************* //