FreeFOAM The Cross-Platform CFD Toolkit
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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/SymmTensor_.H>
27 
28 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
29 
30 namespace Foam
31 {
32 
33 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34 
35 //- Construct null
36 template <class Cmpt>
38 {}
39 
40 
41 //- Construct given VectorSpace
42 template <class Cmpt>
43 inline Tensor<Cmpt>::Tensor(const VectorSpace<Tensor<Cmpt>, Cmpt, 9>& vs)
44 :
45  VectorSpace<Tensor<Cmpt>, Cmpt, 9>(vs)
46 {}
47 
48 
49 //- Construct given SphericalTensor
50 template <class Cmpt>
52 {
53  this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
54  this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
55  this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
56 }
57 
58 
59 //- Construct given SymmTensor
60 template <class Cmpt>
62 {
63  this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
64  this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
65  this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
66 }
67 
68 
69 //- Construct given the three vector components
70 template <class Cmpt>
72 (
73  const Vector<Cmpt>& x,
74  const Vector<Cmpt>& y,
75  const Vector<Cmpt>& z
76 )
77 {
78  this->v_[XX] = x.x(); this->v_[XY] = x.y(); this->v_[XZ] = x.z();
79  this->v_[YX] = y.x(); this->v_[YY] = y.y(); this->v_[YZ] = y.z();
80  this->v_[ZX] = z.x(); this->v_[ZY] = z.y(); this->v_[ZZ] = z.z();
81 }
82 
83 
84 //- Construct from components
85 template <class Cmpt>
87 (
88  const Cmpt txx, const Cmpt txy, const Cmpt txz,
89  const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
90  const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
91 )
92 {
93  this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
94  this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
95  this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
96 }
97 
98 
99 //- Construct from Istream
100 template <class Cmpt>
102 :
103  VectorSpace<Tensor<Cmpt>, Cmpt, 9>(is)
104 {}
105 
106 
107 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
108 
109 template <class Cmpt>
110 inline const Vector<Cmpt> Tensor<Cmpt>::x() const
111 {
112  return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
113 }
114 
115 template <class Cmpt>
116 inline const Vector<Cmpt> Tensor<Cmpt>::y() const
117 {
118  return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
119 }
120 
121 template <class Cmpt>
122 inline const Vector<Cmpt> Tensor<Cmpt>::z() const
123 {
124  return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
125 }
126 
127 
128 template <class Cmpt>
129 inline const Cmpt& Tensor<Cmpt>::xx() const
130 {
131  return this->v_[XX];
132 }
133 
134 template <class Cmpt>
135 inline const Cmpt& Tensor<Cmpt>::xy() const
136 {
137  return this->v_[XY];
138 }
139 
140 template <class Cmpt>
141 inline const Cmpt& Tensor<Cmpt>::xz() const
142 {
143  return this->v_[XZ];
144 }
145 
146 
147 template <class Cmpt>
148 inline const Cmpt& Tensor<Cmpt>::yx() const
149 {
150  return this->v_[YX];
151 }
152 
153 template <class Cmpt>
154 inline const Cmpt& Tensor<Cmpt>::yy() const
155 {
156  return this->v_[YY];
157 }
158 
159 template <class Cmpt>
160 inline const Cmpt& Tensor<Cmpt>::yz() const
161 {
162  return this->v_[YZ];
163 }
164 
165 
166 template <class Cmpt>
167 inline const Cmpt& Tensor<Cmpt>::zx() const
168 {
169  return this->v_[ZX];
170 }
171 
172 template <class Cmpt>
173 inline const Cmpt& Tensor<Cmpt>::zy() const
174 {
175  return this->v_[ZY];
176 }
177 
178 template <class Cmpt>
179 inline const Cmpt& Tensor<Cmpt>::zz() const
180 {
181  return this->v_[ZZ];
182 }
183 
184 
185 template <class Cmpt>
186 inline Cmpt& Tensor<Cmpt>::xx()
187 {
188  return this->v_[XX];
189 }
190 
191 template <class Cmpt>
192 inline Cmpt& Tensor<Cmpt>::xy()
193 {
194  return this->v_[XY];
195 }
196 
197 template <class Cmpt>
198 inline Cmpt& Tensor<Cmpt>::xz()
199 {
200  return this->v_[XZ];
201 }
202 
203 
204 template <class Cmpt>
205 inline Cmpt& Tensor<Cmpt>::yx()
206 {
207  return this->v_[YX];
208 }
209 
210 template <class Cmpt>
211 inline Cmpt& Tensor<Cmpt>::yy()
212 {
213  return this->v_[YY];
214 }
215 
216 template <class Cmpt>
217 inline Cmpt& Tensor<Cmpt>::yz()
218 {
219  return this->v_[YZ];
220 }
221 
222 
223 template <class Cmpt>
224 inline Cmpt& Tensor<Cmpt>::zx()
225 {
226  return this->v_[ZX];
227 }
228 
229 template <class Cmpt>
230 inline Cmpt& Tensor<Cmpt>::zy()
231 {
232  return this->v_[ZY];
233 }
234 
235 template <class Cmpt>
236 inline Cmpt& Tensor<Cmpt>::zz()
237 {
238  return this->v_[ZZ];
239 }
240 
241 
242 //- Return tensor transpose
243 template <class Cmpt>
245 {
246  return Tensor<Cmpt>
247  (
248  xx(), yx(), zx(),
249  xy(), yy(), zy(),
250  xz(), yz(), zz()
251  );
252 }
253 
254 
255 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
256 
257 template <class Cmpt>
259 {
260  this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
261  this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
262  this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
263 }
264 
265 
266 template <class Cmpt>
268 {
269  this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
270  this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
271  this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
272 }
273 
274 
275 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
276 
277 //- Hodge Dual operator (tensor -> vector)
278 template <class Cmpt>
280 {
281  return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
282 }
283 
284 
285 //- Hodge Dual operator (vector -> tensor)
286 template <class Cmpt>
288 {
289  return Tensor<Cmpt>
290  (
291  0, -v.z(), v.y(),
292  v.z(), 0, -v.x(),
293  -v.y(), v.x(), 0
294  );
295 }
296 
297 
298 //- Inner-product between two tensors
299 template <class Cmpt>
300 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt> >::type
301 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
302 {
303  return Tensor<Cmpt>
304  (
305  t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
306  t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
307  t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
308 
309  t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
310  t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
311  t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
312 
313  t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
314  t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
315  t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
316  );
317 }
318 
319 
320 //- Inner-product between a tensor and a vector
321 template <class Cmpt>
322 inline typename innerProduct<Tensor<Cmpt>, Vector<Cmpt> >::type
324 {
325  return Vector<Cmpt>
326  (
327  t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
328  t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
329  t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
330  );
331 }
332 
333 
334 //- Inner-product between a vector and a tensor
335 template <class Cmpt>
336 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
338 {
339  return Vector<Cmpt>
340  (
341  v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
342  v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
343  v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
344  );
345 }
346 
347 
348 //- Outer-product between two vectors
349 template <class Cmpt>
350 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt> >::type
352 {
353  return Tensor<Cmpt>
354  (
355  v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
356  v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
357  v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
358  );
359 }
360 
361 
362 //- Division of a vector by a tensor, i.e. dot-product with the tensor inverse
363 template <class Cmpt>
364 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
366 {
367  return inv(t) & v;
368 }
369 
370 
371 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
372 
373 //- Return the trace of a tensor
374 template <class Cmpt>
375 inline Cmpt tr(const Tensor<Cmpt>& t)
376 {
377  return t.xx() + t.yy() + t.zz();
378 }
379 
380 
381 //- Return the spherical part of a tensor
382 template <class Cmpt>
384 {
385  return (1.0/3.0)*tr(t);
386 }
387 
388 
389 //- Return the symmetric part of a tensor
390 template <class Cmpt>
392 {
393  return SymmTensor<Cmpt>
394  (
395  t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
396  t.yy(), 0.5*(t.yz() + t.zy()),
397  t.zz()
398  );
399 }
400 
401 
402 //- Return twice the symmetric part of a tensor
403 template <class Cmpt>
405 {
406  return SymmTensor<Cmpt>
407  (
408  2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
409  2*t.yy(), (t.yz() + t.zy()),
410  2*t.zz()
411  );
412 }
413 
414 
415 //- Return the skew-symmetric part of a tensor
416 template <class Cmpt>
418 {
419  return Tensor<Cmpt>
420  (
421  0.0, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
422  0.5*(t.yx() - t.xy()), 0.0, 0.5*(t.yz() - t.zy()),
423  0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), 0.0
424  );
425 }
426 
427 
428 //- Return the skew-symmetric part of a symmetric tensor
429 template <class Cmpt>
430 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
431 {
432  return Tensor<Cmpt>::zero;
433 }
434 
435 
436 //- Return the deviatoric part of a tensor
437 template <class Cmpt>
438 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
439 {
440  return t - SphericalTensor<Cmpt>::oneThirdI*tr(t);
441 }
442 
443 
444 //- Return the deviatoric part of a tensor
445 template <class Cmpt>
447 {
449 }
450 
451 
452 //- Return the determinant of a tensor
453 template <class Cmpt>
454 inline Cmpt det(const Tensor<Cmpt>& t)
455 {
456  return
457  (
458  t.xx()*t.yy()*t.zz() + t.xy()*t.yz()*t.zx()
459  + t.xz()*t.yx()*t.zy() - t.xx()*t.yz()*t.zy()
460  - t.xy()*t.yx()*t.zz() - t.xz()*t.yy()*t.zx()
461  );
462 }
463 
464 
465 //- Return the cofactor tensor of a tensor
466 template <class Cmpt>
467 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
468 {
469  return Tensor<Cmpt>
470  (
471  t.yy()*t.zz() - t.zy()*t.yz(),
472  t.zx()*t.yz() - t.yx()*t.zz(),
473  t.yx()*t.zy() - t.yy()*t.zx(),
474 
475  t.xz()*t.zy() - t.xy()*t.zz(),
476  t.xx()*t.zz() - t.xz()*t.zx(),
477  t.xy()*t.zx() - t.xx()*t.zy(),
478 
479  t.xy()*t.yz() - t.xz()*t.yy(),
480  t.yx()*t.xz() - t.xx()*t.yz(),
481  t.xx()*t.yy() - t.yx()*t.xy()
482  );
483 }
484 
485 
486 //- Return the inverse of a tensor give the determinant
487 template <class Cmpt>
488 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett)
489 {
490  return Tensor<Cmpt>
491  (
492  t.yy()*t.zz() - t.zy()*t.yz(),
493  t.xz()*t.zy() - t.xy()*t.zz(),
494  t.xy()*t.yz() - t.xz()*t.yy(),
495 
496  t.zx()*t.yz() - t.yx()*t.zz(),
497  t.xx()*t.zz() - t.xz()*t.zx(),
498  t.yx()*t.xz() - t.xx()*t.yz(),
499 
500  t.yx()*t.zy() - t.yy()*t.zx(),
501  t.xy()*t.zx() - t.xx()*t.zy(),
502  t.xx()*t.yy() - t.yx()*t.xy()
503  )/dett;
504 }
505 
506 
507 //- Return the inverse of a tensor
508 template <class Cmpt>
509 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
510 {
511  return inv(t, det(t));
512 }
513 
514 
515 //- Return the 1st invariant of a tensor
516 template <class Cmpt>
517 inline Cmpt invariantI(const Tensor<Cmpt>& t)
518 {
519  return tr(t);
520 }
521 
522 
523 //- Return the 2nd invariant of a tensor
524 template <class Cmpt>
525 inline Cmpt invariantII(const Tensor<Cmpt>& t)
526 {
527  return
528  (
529  0.5*sqr(tr(t))
530  - 0.5*
531  (
532  t.xx()*t.xx() + t.xy()*t.xy() + t.xz()*t.xz()
533  + t.yx()*t.yx() + t.yy()*t.yy() + t.yz()*t.yz()
534  + t.zx()*t.zx() + t.zy()*t.zy() + t.zz()*t.zz()
535  )
536  );
537 }
538 
539 
540 //- Return the 3rd invariant of a tensor
541 template <class Cmpt>
542 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
543 {
544  return det(t);
545 }
546 
547 
548 // * * * * * * * * * Mixed Tensor SphericalTensor Operators * * * * * * * * //
549 
550 template <class Cmpt>
551 inline Tensor<Cmpt>
553 {
554  return Tensor<Cmpt>
555  (
556  st1.ii() + t2.xx(), t2.xy(), t2.xz(),
557  t2.yx(), st1.ii() + t2.yy(), t2.yz(),
558  t2.zx(), t2.zy(), st1.ii() + t2.zz()
559  );
560 }
561 
562 
563 template <class Cmpt>
564 inline Tensor<Cmpt>
566 {
567  return Tensor<Cmpt>
568  (
569  t1.xx() + st2.ii(), t1.xy(), t1.xz(),
570  t1.yx(), t1.yy() + st2.ii(), t1.yz(),
571  t1.zx(), t1.zy(), t1.zz() + st2.ii()
572  );
573 }
574 
575 
576 template <class Cmpt>
577 inline Tensor<Cmpt>
579 {
580  return Tensor<Cmpt>
581  (
582  st1.ii() - t2.xx(), -t2.xy(), -t2.xz(),
583  -t2.yx(), st1.ii() - t2.yy(), -t2.yz(),
584  -t2.zx(), -t2.zy(), st1.ii() - t2.zz()
585  );
586 }
587 
588 
589 template <class Cmpt>
590 inline Tensor<Cmpt>
592 {
593  return Tensor<Cmpt>
594  (
595  t1.xx() - st2.ii(), t1.xy(), t1.xz(),
596  t1.yx(), t1.yy() - st2.ii(), t1.yz(),
597  t1.zx(), t1.zy(), t1.zz() - st2.ii()
598  );
599 }
600 
601 
602 //- Inner-product between a spherical tensor and a tensor
603 template <class Cmpt>
604 inline Tensor<Cmpt>
606 {
607  return Tensor<Cmpt>
608  (
609  st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
610  st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
611  st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
612  );
613 }
614 
615 
616 //- Inner-product between a tensor and a spherical tensor
617 template <class Cmpt>
618 inline Tensor<Cmpt>
620 {
621  return Tensor<Cmpt>
622  (
623  t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
624  t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
625  t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
626  );
627 }
628 
629 
630 //- Double-dot-product between a spherical tensor and a tensor
631 template <class Cmpt>
632 inline Cmpt
634 {
635  return(st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
636 }
637 
638 
639 //- Double-dot-product between a tensor and a spherical tensor
640 template <class Cmpt>
641 inline Cmpt
643 {
644  return(t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
645 }
646 
647 template<class Cmpt>
648 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt> >
649 {
650 public:
651 
653 };
654 
655 template<class Cmpt>
656 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt> >
657 {
658 public:
659 
661 };
662 
663 template<class Cmpt>
664 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt> >
665 {
666 public:
667 
669 };
670 
671 template<class Cmpt>
672 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt> >
673 {
674 public:
675 
677 };
678 
679 
680 // * * * * * * * * * * Mixed Tensor SymmTensor Operators * * * * * * * * * * //
681 
682 template <class Cmpt>
683 inline Tensor<Cmpt>
685 {
686  return Tensor<Cmpt>
687  (
688  st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
689  st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
690  st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
691  );
692 }
693 
694 
695 template <class Cmpt>
696 inline Tensor<Cmpt>
698 {
699  return Tensor<Cmpt>
700  (
701  t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
702  t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
703  t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
704  );
705 }
706 
707 
708 template <class Cmpt>
709 inline Tensor<Cmpt>
711 {
712  return Tensor<Cmpt>
713  (
714  st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
715  st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
716  st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
717  );
718 }
719 
720 
721 template <class Cmpt>
722 inline Tensor<Cmpt>
724 {
725  return Tensor<Cmpt>
726  (
727  t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
728  t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
729  t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
730  );
731 }
732 
733 
734 //- Inner-product between a spherical tensor and a tensor
735 template <class Cmpt>
736 inline Tensor<Cmpt>
738 {
739  return Tensor<Cmpt>
740  (
741  st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
742  st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
743  st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
744 
745  st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
746  st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
747  st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
748 
749  st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
750  st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
751  st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
752  );
753 }
754 
755 
756 //- Inner-product between a tensor and a spherical tensor
757 template <class Cmpt>
758 inline Tensor<Cmpt>
760 {
761  return Tensor<Cmpt>
762  (
763  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
764  t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
765  t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
766 
767  t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
768  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
769  t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
770 
771  t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
772  t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
773  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
774  );
775 }
776 
777 
778 //- Double-dot-product between a spherical tensor and a tensor
779 template <class Cmpt>
780 inline Cmpt
782 {
783  return
784  (
785  st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
786  st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
787  st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
788  );
789 }
790 
791 
792 //- Double-dot-product between a tensor and a spherical tensor
793 template <class Cmpt>
794 inline Cmpt
796 {
797  return
798  (
799  t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
800  t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
801  t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
802  );
803 }
804 
805 template<class Cmpt>
806 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt> >
807 {
808 public:
809 
811 };
812 
813 template<class Cmpt>
814 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt> >
815 {
816 public:
817 
819 };
820 
821 
822 template<class Cmpt>
823 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt> >
824 {
825 public:
826 
828 };
829 
830 template<class Cmpt>
831 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt> >
832 {
833 public:
834 
836 };
837 
838 
839 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
840 
841 } // End namespace Foam
842 
843 // ************************ vim: set sw=4 sts=4 et: ************************ //