FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

TensorI_.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include <OpenFOAM/SymmTensor_.H>
00027 
00028 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00029 
00030 namespace Foam
00031 {
00032 
00033 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00034 
00035 //- Construct null
00036 template <class Cmpt>
00037 inline Tensor<Cmpt>::Tensor()
00038 {}
00039 
00040 
00041 //- Construct given VectorSpace
00042 template <class Cmpt>
00043 inline Tensor<Cmpt>::Tensor(const VectorSpace<Tensor<Cmpt>, Cmpt, 9>& vs)
00044 :
00045     VectorSpace<Tensor<Cmpt>, Cmpt, 9>(vs)
00046 {}
00047 
00048 
00049 //- Construct given SphericalTensor
00050 template <class Cmpt>
00051 inline Tensor<Cmpt>::Tensor(const SphericalTensor<Cmpt>& st)
00052 {
00053     this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
00054     this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
00055     this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
00056 }
00057 
00058 
00059 //- Construct given SymmTensor
00060 template <class Cmpt>
00061 inline Tensor<Cmpt>::Tensor(const SymmTensor<Cmpt>& st)
00062 {
00063     this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
00064     this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
00065     this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
00066 }
00067 
00068 
00069 //- Construct given the three vector components
00070 template <class Cmpt>
00071 inline Tensor<Cmpt>::Tensor
00072 (
00073     const Vector<Cmpt>& x,
00074     const Vector<Cmpt>& y,
00075     const Vector<Cmpt>& z
00076 )
00077 {
00078     this->v_[XX] = x.x(); this->v_[XY] = x.y(); this->v_[XZ] = x.z();
00079     this->v_[YX] = y.x(); this->v_[YY] = y.y(); this->v_[YZ] = y.z();
00080     this->v_[ZX] = z.x(); this->v_[ZY] = z.y(); this->v_[ZZ] = z.z();
00081 }
00082 
00083 
00084 //- Construct from components
00085 template <class Cmpt>
00086 inline Tensor<Cmpt>::Tensor
00087 (
00088     const Cmpt txx, const Cmpt txy, const Cmpt txz,
00089     const Cmpt tyx, const Cmpt tyy, const Cmpt tyz,
00090     const Cmpt tzx, const Cmpt tzy, const Cmpt tzz
00091 )
00092 {
00093     this->v_[XX] = txx; this->v_[XY] = txy; this->v_[XZ] = txz;
00094     this->v_[YX] = tyx; this->v_[YY] = tyy; this->v_[YZ] = tyz;
00095     this->v_[ZX] = tzx; this->v_[ZY] = tzy; this->v_[ZZ] = tzz;
00096 }
00097 
00098 
00099 //- Construct from Istream
00100 template <class Cmpt>
00101 inline Tensor<Cmpt>::Tensor(Istream& is)
00102 :
00103     VectorSpace<Tensor<Cmpt>, Cmpt, 9>(is)
00104 {}
00105 
00106 
00107 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00108 
00109 template <class Cmpt>
00110 inline const Vector<Cmpt> Tensor<Cmpt>::x() const
00111 {
00112     return Vector<Cmpt>(this->v_[XX], this->v_[XY], this->v_[XZ]);
00113 }
00114 
00115 template <class Cmpt>
00116 inline const Vector<Cmpt> Tensor<Cmpt>::y() const
00117 {
00118     return Vector<Cmpt>(this->v_[YX], this->v_[YY], this->v_[YZ]);
00119 }
00120 
00121 template <class Cmpt>
00122 inline const Vector<Cmpt>  Tensor<Cmpt>::z() const
00123 {
00124     return Vector<Cmpt>(this->v_[ZX], this->v_[ZY], this->v_[ZZ]);
00125 }
00126 
00127 
00128 template <class Cmpt>
00129 inline const Cmpt&  Tensor<Cmpt>::xx() const
00130 {
00131     return this->v_[XX];
00132 }
00133 
00134 template <class Cmpt>
00135 inline const Cmpt&  Tensor<Cmpt>::xy() const
00136 {
00137     return this->v_[XY];
00138 }
00139 
00140 template <class Cmpt>
00141 inline const Cmpt&  Tensor<Cmpt>::xz() const
00142 {
00143     return this->v_[XZ];
00144 }
00145 
00146 
00147 template <class Cmpt>
00148 inline const Cmpt&  Tensor<Cmpt>::yx() const
00149 {
00150     return this->v_[YX];
00151 }
00152 
00153 template <class Cmpt>
00154 inline const Cmpt&  Tensor<Cmpt>::yy() const
00155 {
00156     return this->v_[YY];
00157 }
00158 
00159 template <class Cmpt>
00160 inline const Cmpt&  Tensor<Cmpt>::yz() const
00161 {
00162     return this->v_[YZ];
00163 }
00164 
00165 
00166 template <class Cmpt>
00167 inline const Cmpt&  Tensor<Cmpt>::zx() const
00168 {
00169     return this->v_[ZX];
00170 }
00171 
00172 template <class Cmpt>
00173 inline const Cmpt&  Tensor<Cmpt>::zy() const
00174 {
00175     return this->v_[ZY];
00176 }
00177 
00178 template <class Cmpt>
00179 inline const Cmpt&  Tensor<Cmpt>::zz() const
00180 {
00181     return this->v_[ZZ];
00182 }
00183 
00184 
00185 template <class Cmpt>
00186 inline Cmpt& Tensor<Cmpt>::xx()
00187 {
00188     return this->v_[XX];
00189 }
00190 
00191 template <class Cmpt>
00192 inline Cmpt& Tensor<Cmpt>::xy()
00193 {
00194     return this->v_[XY];
00195 }
00196 
00197 template <class Cmpt>
00198 inline Cmpt& Tensor<Cmpt>::xz()
00199 {
00200     return this->v_[XZ];
00201 }
00202 
00203 
00204 template <class Cmpt>
00205 inline Cmpt& Tensor<Cmpt>::yx()
00206 {
00207     return this->v_[YX];
00208 }
00209 
00210 template <class Cmpt>
00211 inline Cmpt& Tensor<Cmpt>::yy()
00212 {
00213     return this->v_[YY];
00214 }
00215 
00216 template <class Cmpt>
00217 inline Cmpt& Tensor<Cmpt>::yz()
00218 {
00219     return this->v_[YZ];
00220 }
00221 
00222 
00223 template <class Cmpt>
00224 inline Cmpt& Tensor<Cmpt>::zx()
00225 {
00226     return this->v_[ZX];
00227 }
00228 
00229 template <class Cmpt>
00230 inline Cmpt& Tensor<Cmpt>::zy()
00231 {
00232     return this->v_[ZY];
00233 }
00234 
00235 template <class Cmpt>
00236 inline Cmpt& Tensor<Cmpt>::zz()
00237 {
00238     return this->v_[ZZ];
00239 }
00240 
00241 
00242 //- Return tensor transpose
00243 template <class Cmpt>
00244 inline Tensor<Cmpt> Tensor<Cmpt>::T() const
00245 {
00246     return Tensor<Cmpt>
00247     (
00248         xx(), yx(), zx(),
00249         xy(), yy(), zy(),
00250         xz(), yz(), zz()
00251     );
00252 }
00253 
00254 
00255 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00256 
00257 template <class Cmpt>
00258 inline void Tensor<Cmpt>::operator=(const SphericalTensor<Cmpt>& st)
00259 {
00260     this->v_[XX] = st.ii(); this->v_[XY] = 0; this->v_[XZ] = 0;
00261     this->v_[YX] = 0; this->v_[YY] = st.ii(); this->v_[YZ] = 0;
00262     this->v_[ZX] = 0; this->v_[ZY] = 0; this->v_[ZZ] = st.ii();
00263 }
00264 
00265 
00266 template <class Cmpt>
00267 inline void Tensor<Cmpt>::operator=(const SymmTensor<Cmpt>& st)
00268 {
00269     this->v_[XX] = st.xx(); this->v_[XY] = st.xy(); this->v_[XZ] = st.xz();
00270     this->v_[YX] = st.xy(); this->v_[YY] = st.yy(); this->v_[YZ] = st.yz();
00271     this->v_[ZX] = st.xz(); this->v_[ZY] = st.yz(); this->v_[ZZ] = st.zz();
00272 }
00273 
00274 
00275 // * * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * //
00276 
00277 //- Hodge Dual operator (tensor -> vector)
00278 template <class Cmpt>
00279 inline Vector<Cmpt> operator*(const Tensor<Cmpt>& t)
00280 {
00281     return Vector<Cmpt>(t.yz(), -t.xz(), t.xy());
00282 }
00283 
00284 
00285 //- Hodge Dual operator (vector -> tensor)
00286 template <class Cmpt>
00287 inline Tensor<Cmpt> operator*(const Vector<Cmpt>& v)
00288 {
00289     return Tensor<Cmpt>
00290     (
00291              0, -v.z(),   v.y(),
00292          v.z(),      0,  -v.x(),
00293         -v.y(),  v.x(),       0
00294     );
00295 }
00296 
00297 
00298 //- Inner-product between two tensors
00299 template <class Cmpt>
00300 inline typename innerProduct<Tensor<Cmpt>, Tensor<Cmpt> >::type
00301 operator&(const Tensor<Cmpt>& t1, const Tensor<Cmpt>& t2)
00302 {
00303     return Tensor<Cmpt>
00304     (
00305         t1.xx()*t2.xx() + t1.xy()*t2.yx() + t1.xz()*t2.zx(),
00306         t1.xx()*t2.xy() + t1.xy()*t2.yy() + t1.xz()*t2.zy(),
00307         t1.xx()*t2.xz() + t1.xy()*t2.yz() + t1.xz()*t2.zz(),
00308 
00309         t1.yx()*t2.xx() + t1.yy()*t2.yx() + t1.yz()*t2.zx(),
00310         t1.yx()*t2.xy() + t1.yy()*t2.yy() + t1.yz()*t2.zy(),
00311         t1.yx()*t2.xz() + t1.yy()*t2.yz() + t1.yz()*t2.zz(),
00312 
00313         t1.zx()*t2.xx() + t1.zy()*t2.yx() + t1.zz()*t2.zx(),
00314         t1.zx()*t2.xy() + t1.zy()*t2.yy() + t1.zz()*t2.zy(),
00315         t1.zx()*t2.xz() + t1.zy()*t2.yz() + t1.zz()*t2.zz()
00316     );
00317 }
00318 
00319 
00320 //- Inner-product between a tensor and a vector
00321 template <class Cmpt>
00322 inline typename innerProduct<Tensor<Cmpt>, Vector<Cmpt> >::type
00323 operator&(const Tensor<Cmpt>& t, const Vector<Cmpt>& v)
00324 {
00325     return Vector<Cmpt>
00326     (
00327         t.xx()*v.x() + t.xy()*v.y() + t.xz()*v.z(),
00328         t.yx()*v.x() + t.yy()*v.y() + t.yz()*v.z(),
00329         t.zx()*v.x() + t.zy()*v.y() + t.zz()*v.z()
00330     );
00331 }
00332 
00333 
00334 //- Inner-product between a vector and a tensor
00335 template <class Cmpt>
00336 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
00337 operator&(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
00338 {
00339     return Vector<Cmpt>
00340     (
00341         v.x()*t.xx() + v.y()*t.yx() + v.z()*t.zx(),
00342         v.x()*t.xy() + v.y()*t.yy() + v.z()*t.zy(),
00343         v.x()*t.xz() + v.y()*t.yz() + v.z()*t.zz()
00344     );
00345 }
00346 
00347 
00348 //- Outer-product between two vectors
00349 template <class Cmpt>
00350 inline typename outerProduct<Vector<Cmpt>, Vector<Cmpt> >::type
00351 operator*(const Vector<Cmpt>& v1, const Vector<Cmpt>& v2)
00352 {
00353     return Tensor<Cmpt>
00354     (
00355         v1.x()*v2.x(), v1.x()*v2.y(), v1.x()*v2.z(),
00356         v1.y()*v2.x(), v1.y()*v2.y(), v1.y()*v2.z(),
00357         v1.z()*v2.x(), v1.z()*v2.y(), v1.z()*v2.z()
00358     );
00359 }
00360 
00361 
00362 //- Division of a vector by a tensor, i.e. dot-product with the tensor inverse
00363 template <class Cmpt>
00364 inline typename innerProduct<Vector<Cmpt>, Tensor<Cmpt> >::type
00365 operator/(const Vector<Cmpt>& v, const Tensor<Cmpt>& t)
00366 {
00367     return inv(t) & v;
00368 }
00369 
00370 
00371 // * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
00372 
00373 //- Return the trace of a tensor
00374 template <class Cmpt>
00375 inline Cmpt tr(const Tensor<Cmpt>& t)
00376 {
00377     return t.xx() + t.yy() + t.zz();
00378 }
00379 
00380 
00381 //- Return the spherical part of a tensor
00382 template <class Cmpt>
00383 inline SphericalTensor<Cmpt> sph(const Tensor<Cmpt>& t)
00384 {
00385     return (1.0/3.0)*tr(t);
00386 }
00387 
00388 
00389 //- Return the symmetric part of a tensor
00390 template <class Cmpt>
00391 inline SymmTensor<Cmpt> symm(const Tensor<Cmpt>& t)
00392 {
00393     return SymmTensor<Cmpt>
00394     (
00395         t.xx(), 0.5*(t.xy() + t.yx()), 0.5*(t.xz() + t.zx()),
00396                 t.yy(),                0.5*(t.yz() + t.zy()),
00397                                        t.zz()
00398     );
00399 }
00400 
00401 
00402 //- Return twice the symmetric part of a tensor
00403 template <class Cmpt>
00404 inline SymmTensor<Cmpt> twoSymm(const Tensor<Cmpt>& t)
00405 {
00406     return SymmTensor<Cmpt>
00407     (
00408         2*t.xx(), (t.xy() + t.yx()), (t.xz() + t.zx()),
00409                   2*t.yy(),          (t.yz() + t.zy()),
00410                                      2*t.zz()
00411     );
00412 }
00413 
00414 
00415 //- Return the skew-symmetric part of a tensor
00416 template <class Cmpt>
00417 inline Tensor<Cmpt> skew(const Tensor<Cmpt>& t)
00418 {
00419     return Tensor<Cmpt>
00420     (
00421         0.0, 0.5*(t.xy() - t.yx()), 0.5*(t.xz() - t.zx()),
00422         0.5*(t.yx() - t.xy()), 0.0, 0.5*(t.yz() - t.zy()),
00423         0.5*(t.zx() - t.xz()), 0.5*(t.zy() - t.yz()), 0.0
00424     );
00425 }
00426 
00427 
00428 //- Return the skew-symmetric part of a symmetric tensor
00429 template <class Cmpt>
00430 inline const Tensor<Cmpt>& skew(const SymmTensor<Cmpt>& st)
00431 {
00432     return Tensor<Cmpt>::zero;
00433 }
00434 
00435 
00436 //- Return the deviatoric part of a tensor
00437 template <class Cmpt>
00438 inline Tensor<Cmpt> dev(const Tensor<Cmpt>& t)
00439 {
00440     return t - SphericalTensor<Cmpt>::oneThirdI*tr(t);
00441 }
00442 
00443 
00444 //- Return the deviatoric part of a tensor
00445 template <class Cmpt>
00446 inline Tensor<Cmpt> dev2(const Tensor<Cmpt>& t)
00447 {
00448     return t - SphericalTensor<Cmpt>::twoThirdsI*tr(t);
00449 }
00450 
00451 
00452 //- Return the determinant of a tensor
00453 template <class Cmpt>
00454 inline Cmpt det(const Tensor<Cmpt>& t)
00455 {
00456     return
00457     (
00458         t.xx()*t.yy()*t.zz() + t.xy()*t.yz()*t.zx()
00459       + t.xz()*t.yx()*t.zy() - t.xx()*t.yz()*t.zy()
00460       - t.xy()*t.yx()*t.zz() - t.xz()*t.yy()*t.zx()
00461     );
00462 }
00463 
00464 
00465 //- Return the cofactor tensor of a tensor
00466 template <class Cmpt>
00467 inline Tensor<Cmpt> cof(const Tensor<Cmpt>& t)
00468 {
00469     return Tensor<Cmpt>
00470     (
00471         t.yy()*t.zz() - t.zy()*t.yz(),
00472         t.zx()*t.yz() - t.yx()*t.zz(),
00473         t.yx()*t.zy() - t.yy()*t.zx(),
00474 
00475         t.xz()*t.zy() - t.xy()*t.zz(),
00476         t.xx()*t.zz() - t.xz()*t.zx(),
00477         t.xy()*t.zx() - t.xx()*t.zy(),
00478 
00479         t.xy()*t.yz() - t.xz()*t.yy(),
00480         t.yx()*t.xz() - t.xx()*t.yz(),
00481         t.xx()*t.yy() - t.yx()*t.xy()
00482     );
00483 }
00484 
00485 
00486 //- Return the inverse of a tensor give the determinant
00487 template <class Cmpt>
00488 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t, const Cmpt dett)
00489 {
00490     return Tensor<Cmpt>
00491     (
00492         t.yy()*t.zz() - t.zy()*t.yz(),
00493         t.xz()*t.zy() - t.xy()*t.zz(),
00494         t.xy()*t.yz() - t.xz()*t.yy(),
00495 
00496         t.zx()*t.yz() - t.yx()*t.zz(),
00497         t.xx()*t.zz() - t.xz()*t.zx(),
00498         t.yx()*t.xz() - t.xx()*t.yz(),
00499 
00500         t.yx()*t.zy() - t.yy()*t.zx(),
00501         t.xy()*t.zx() - t.xx()*t.zy(),
00502         t.xx()*t.yy() - t.yx()*t.xy()
00503     )/dett;
00504 }
00505 
00506 
00507 //- Return the inverse of a tensor
00508 template <class Cmpt>
00509 inline Tensor<Cmpt> inv(const Tensor<Cmpt>& t)
00510 {
00511     return inv(t, det(t));
00512 }
00513 
00514 
00515 //- Return the 1st invariant of a tensor
00516 template <class Cmpt>
00517 inline Cmpt invariantI(const Tensor<Cmpt>& t)
00518 {
00519     return tr(t);
00520 }
00521 
00522 
00523 //- Return the 2nd invariant of a tensor
00524 template <class Cmpt>
00525 inline Cmpt invariantII(const Tensor<Cmpt>& t)
00526 {
00527     return
00528     (
00529         0.5*sqr(tr(t))
00530       - 0.5*
00531         (
00532            t.xx()*t.xx() + t.xy()*t.xy() + t.xz()*t.xz()
00533          + t.yx()*t.yx() + t.yy()*t.yy() + t.yz()*t.yz()
00534          + t.zx()*t.zx() + t.zy()*t.zy() + t.zz()*t.zz()
00535         )
00536     );
00537 }
00538 
00539 
00540 //- Return the 3rd invariant of a tensor
00541 template <class Cmpt>
00542 inline Cmpt invariantIII(const Tensor<Cmpt>& t)
00543 {
00544     return det(t);
00545 }
00546 
00547 
00548 // * * * * * * * * * Mixed Tensor SphericalTensor Operators  * * * * * * * * //
00549 
00550 template <class Cmpt>
00551 inline Tensor<Cmpt>
00552 operator+(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00553 {
00554     return Tensor<Cmpt>
00555     (
00556         st1.ii() + t2.xx(), t2.xy(),            t2.xz(),
00557         t2.yx(),            st1.ii() + t2.yy(), t2.yz(),
00558         t2.zx(),            t2.zy(),            st1.ii() + t2.zz()
00559     );
00560 }
00561 
00562 
00563 template <class Cmpt>
00564 inline Tensor<Cmpt>
00565 operator+(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
00566 {
00567     return Tensor<Cmpt>
00568     (
00569         t1.xx() + st2.ii(), t1.xy(),            t1.xz(),
00570         t1.yx(),            t1.yy() + st2.ii(), t1.yz(),
00571         t1.zx(),            t1.zy(),            t1.zz() + st2.ii()
00572     );
00573 }
00574 
00575 
00576 template <class Cmpt>
00577 inline Tensor<Cmpt>
00578 operator-(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00579 {
00580     return Tensor<Cmpt>
00581     (
00582         st1.ii() - t2.xx(), -t2.xy(),            -t2.xz(),
00583        -t2.yx(),             st1.ii() - t2.yy(), -t2.yz(),
00584        -t2.zx(),            -t2.zy(),             st1.ii() - t2.zz()
00585     );
00586 }
00587 
00588 
00589 template <class Cmpt>
00590 inline Tensor<Cmpt>
00591 operator-(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
00592 {
00593     return Tensor<Cmpt>
00594     (
00595         t1.xx() - st2.ii(), t1.xy(),            t1.xz(),
00596         t1.yx(),            t1.yy() - st2.ii(), t1.yz(),
00597         t1.zx(),            t1.zy(),            t1.zz() - st2.ii()
00598     );
00599 }
00600 
00601 
00602 //- Inner-product between a spherical tensor and a tensor
00603 template <class Cmpt>
00604 inline Tensor<Cmpt>
00605 operator&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00606 {
00607     return Tensor<Cmpt>
00608     (
00609         st1.ii()*t2.xx(), st1.ii()*t2.xy(), st1.ii()*t2.xz(),
00610         st1.ii()*t2.yx(), st1.ii()*t2.yy(), st1.ii()*t2.yz(),
00611         st1.ii()*t2.zx(), st1.ii()*t2.zy(), st1.ii()*t2.zz()
00612     );
00613 }
00614 
00615 
00616 //- Inner-product between a tensor and a spherical tensor
00617 template <class Cmpt>
00618 inline Tensor<Cmpt>
00619 operator&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
00620 {
00621     return Tensor<Cmpt>
00622     (
00623         t1.xx()*st2.ii(), t1.xy()*st2.ii(), t1.xz()*st2.ii(),
00624         t1.yx()*st2.ii(), t1.yy()*st2.ii(), t1.yz()*st2.ii(),
00625         t1.zx()*st2.ii(), t1.zy()*st2.ii(), t1.zz()*st2.ii()
00626     );
00627 }
00628 
00629 
00630 //- Double-dot-product between a spherical tensor and a tensor
00631 template <class Cmpt>
00632 inline Cmpt
00633 operator&&(const SphericalTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00634 {
00635     return(st1.ii()*t2.xx() + st1.ii()*t2.yy() + st1.ii()*t2.zz());
00636 }
00637 
00638 
00639 //- Double-dot-product between a tensor and a spherical tensor
00640 template <class Cmpt>
00641 inline Cmpt
00642 operator&&(const Tensor<Cmpt>& t1, const SphericalTensor<Cmpt>& st2)
00643 {
00644     return(t1.xx()*st2.ii() + t1.yy()*st2.ii() + t1.zz()*st2.ii());
00645 }
00646 
00647 template<class Cmpt>
00648 class typeOfSum<SphericalTensor<Cmpt>, Tensor<Cmpt> >
00649 {
00650 public:
00651 
00652     typedef Tensor<Cmpt> type;
00653 };
00654 
00655 template<class Cmpt>
00656 class typeOfSum<Tensor<Cmpt>, SphericalTensor<Cmpt> >
00657 {
00658 public:
00659 
00660     typedef Tensor<Cmpt> type;
00661 };
00662 
00663 template<class Cmpt>
00664 class innerProduct<SphericalTensor<Cmpt>, Tensor<Cmpt> >
00665 {
00666 public:
00667 
00668     typedef Tensor<Cmpt> type;
00669 };
00670 
00671 template<class Cmpt>
00672 class innerProduct<Tensor<Cmpt>, SphericalTensor<Cmpt> >
00673 {
00674 public:
00675 
00676     typedef Tensor<Cmpt> type;
00677 };
00678 
00679 
00680 // * * * * * * * * * * Mixed Tensor SymmTensor Operators * * * * * * * * * * //
00681 
00682 template <class Cmpt>
00683 inline Tensor<Cmpt>
00684 operator+(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00685 {
00686     return Tensor<Cmpt>
00687     (
00688         st1.xx() + t2.xx(), st1.xy() + t2.xy(), st1.xz() + t2.xz(),
00689         st1.xy() + t2.yx(), st1.yy() + t2.yy(), st1.yz() + t2.yz(),
00690         st1.xz() + t2.zx(), st1.yz() + t2.zy(), st1.zz() + t2.zz()
00691     );
00692 }
00693 
00694 
00695 template <class Cmpt>
00696 inline Tensor<Cmpt>
00697 operator+(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
00698 {
00699     return Tensor<Cmpt>
00700     (
00701         t1.xx() + st2.xx(), t1.xy() + st2.xy(), t1.xz() + st2.xz(),
00702         t1.yx() + st2.xy(), t1.yy() + st2.yy(), t1.yz() + st2.yz(),
00703         t1.zx() + st2.xz(), t1.zy() + st2.yz(), t1.zz() + st2.zz()
00704     );
00705 }
00706 
00707 
00708 template <class Cmpt>
00709 inline Tensor<Cmpt>
00710 operator-(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00711 {
00712     return Tensor<Cmpt>
00713     (
00714         st1.xx() - t2.xx(), st1.xy() - t2.xy(), st1.xz() - t2.xz(),
00715         st1.xy() - t2.yx(), st1.yy() - t2.yy(), st1.yz() - t2.yz(),
00716         st1.xz() - t2.zx(), st1.yz() - t2.zy(), st1.zz() - t2.zz()
00717     );
00718 }
00719 
00720 
00721 template <class Cmpt>
00722 inline Tensor<Cmpt>
00723 operator-(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
00724 {
00725     return Tensor<Cmpt>
00726     (
00727         t1.xx() - st2.xx(), t1.xy() - st2.xy(), t1.xz() - st2.xz(),
00728         t1.yx() - st2.xy(), t1.yy() - st2.yy(), t1.yz() - st2.yz(),
00729         t1.zx() - st2.xz(), t1.zy() - st2.yz(), t1.zz() - st2.zz()
00730     );
00731 }
00732 
00733 
00734 //- Inner-product between a spherical tensor and a tensor
00735 template <class Cmpt>
00736 inline Tensor<Cmpt>
00737 operator&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00738 {
00739     return Tensor<Cmpt>
00740     (
00741         st1.xx()*t2.xx() + st1.xy()*t2.yx() + st1.xz()*t2.zx(),
00742         st1.xx()*t2.xy() + st1.xy()*t2.yy() + st1.xz()*t2.zy(),
00743         st1.xx()*t2.xz() + st1.xy()*t2.yz() + st1.xz()*t2.zz(),
00744 
00745         st1.xy()*t2.xx() + st1.yy()*t2.yx() + st1.yz()*t2.zx(),
00746         st1.xy()*t2.xy() + st1.yy()*t2.yy() + st1.yz()*t2.zy(),
00747         st1.xy()*t2.xz() + st1.yy()*t2.yz() + st1.yz()*t2.zz(),
00748 
00749         st1.xz()*t2.xx() + st1.yz()*t2.yx() + st1.zz()*t2.zx(),
00750         st1.xz()*t2.xy() + st1.yz()*t2.yy() + st1.zz()*t2.zy(),
00751         st1.xz()*t2.xz() + st1.yz()*t2.yz() + st1.zz()*t2.zz()
00752     );
00753 }
00754 
00755 
00756 //- Inner-product between a tensor and a spherical tensor
00757 template <class Cmpt>
00758 inline Tensor<Cmpt>
00759 operator&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
00760 {
00761     return Tensor<Cmpt>
00762     (
00763         t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz(),
00764         t1.xx()*st2.xy() + t1.xy()*st2.yy() + t1.xz()*st2.yz(),
00765         t1.xx()*st2.xz() + t1.xy()*st2.yz() + t1.xz()*st2.zz(),
00766 
00767         t1.yx()*st2.xx() + t1.yy()*st2.xy() + t1.yz()*st2.xz(),
00768         t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz(),
00769         t1.yx()*st2.xz() + t1.yy()*st2.yz() + t1.yz()*st2.zz(),
00770 
00771         t1.zx()*st2.xx() + t1.zy()*st2.xy() + t1.zz()*st2.xz(),
00772         t1.zx()*st2.xy() + t1.zy()*st2.yy() + t1.zz()*st2.yz(),
00773         t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
00774     );
00775 }
00776 
00777 
00778 //- Double-dot-product between a spherical tensor and a tensor
00779 template <class Cmpt>
00780 inline Cmpt
00781 operator&&(const SymmTensor<Cmpt>& st1, const Tensor<Cmpt>& t2)
00782 {
00783     return
00784     (
00785         st1.xx()*t2.xx() + st1.xy()*t2.xy() + st1.xz()*t2.xz() +
00786         st1.xy()*t2.yx() + st1.yy()*t2.yy() + st1.yz()*t2.yz() +
00787         st1.xz()*t2.zx() + st1.yz()*t2.zy() + st1.zz()*t2.zz()
00788     );
00789 }
00790 
00791 
00792 //- Double-dot-product between a tensor and a spherical tensor
00793 template <class Cmpt>
00794 inline Cmpt
00795 operator&&(const Tensor<Cmpt>& t1, const SymmTensor<Cmpt>& st2)
00796 {
00797     return
00798     (
00799         t1.xx()*st2.xx() + t1.xy()*st2.xy() + t1.xz()*st2.xz() +
00800         t1.yx()*st2.xy() + t1.yy()*st2.yy() + t1.yz()*st2.yz() +
00801         t1.zx()*st2.xz() + t1.zy()*st2.yz() + t1.zz()*st2.zz()
00802     );
00803 }
00804 
00805 template<class Cmpt>
00806 class typeOfSum<SymmTensor<Cmpt>, Tensor<Cmpt> >
00807 {
00808 public:
00809 
00810     typedef Tensor<Cmpt> type;
00811 };
00812 
00813 template<class Cmpt>
00814 class typeOfSum<Tensor<Cmpt>, SymmTensor<Cmpt> >
00815 {
00816 public:
00817 
00818     typedef Tensor<Cmpt> type;
00819 };
00820 
00821 
00822 template<class Cmpt>
00823 class innerProduct<SymmTensor<Cmpt>, Tensor<Cmpt> >
00824 {
00825 public:
00826 
00827     typedef Tensor<Cmpt> type;
00828 };
00829 
00830 template<class Cmpt>
00831 class innerProduct<Tensor<Cmpt>, SymmTensor<Cmpt> >
00832 {
00833 public:
00834 
00835     typedef Tensor<Cmpt> type;
00836 };
00837 
00838 
00839 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00840 
00841 } // End namespace Foam
00842 
00843 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines