Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/AppTypes/TSVMetaDot.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef TSV_META_DOT_H
00012 #define TSV_META_DOT_H
00013 
00015 //
00016 // Definition of the struct TSV_MetaDot.
00017 //
00019 
00020 template<class T1, class T2> struct TSV_MetaDot {};
00021 
00023 //
00024 // Specializations for Vektor dot Vektor
00025 //
00027 
00028 template<class T1, class T2, unsigned D>
00029 struct TSV_MetaDot< Vektor<T1,D> , Vektor<T2,D> >
00030 {
00031   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00032   inline static T0
00033   apply(const Vektor<T1,D>& lhs, const Vektor<T2,D>& rhs) {
00034     T0 dot = lhs[0]*rhs[0];
00035     for (unsigned d=1; d<D; ++d)
00036       dot += lhs[d]*rhs[d];
00037     return dot;
00038   }
00039 };
00040 
00041 template<class T1, class T2>
00042 struct TSV_MetaDot< Vektor<T1,1> , Vektor<T2,1> >
00043 {
00044   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00045   inline static T0
00046   apply(const Vektor<T1,1>& lhs, const Vektor<T2,1>& rhs) {
00047     return lhs[0]*rhs[0];
00048   }
00049 };
00050 
00051 template<class T1, class T2>
00052 struct TSV_MetaDot< Vektor<T1,2> , Vektor<T2,2> >
00053 {
00054   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00055   inline static T0
00056   apply(const Vektor<T1,2>& lhs, const Vektor<T2,2>& rhs) {
00057     return lhs[0]*rhs[0] + lhs[1]*rhs[1];
00058   }
00059 };
00060 
00061 template<class T1, class T2>
00062 struct TSV_MetaDot< Vektor<T1,3> , Vektor<T2,3> >
00063 {
00064   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00065   inline static T0
00066   apply(const Vektor<T1,3>& lhs, const Vektor<T2,3>& rhs) {
00067     return lhs[0]*rhs[0] + lhs[1]*rhs[1] + lhs[2]*rhs[2];
00068   }
00069 };
00070 
00072 //
00073 // Specializations for Tenzor dot Tenzor
00074 //
00076 
00077 template<class T1, class T2, unsigned D>
00078 struct TSV_MetaDot< Tenzor<T1,D> , Tenzor<T2,D> >
00079 {
00080   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00081   inline static Tenzor<T0,D>
00082   apply(const Tenzor<T1,D>& lhs, const Tenzor<T2,D>& rhs) {
00083     Tenzor<T0,D> dot = typename Tenzor<T0,D>::DontInitialize();
00084     for (unsigned int i=0; i<D; ++i)
00085       for (unsigned int j=0; j<D; ++j) {
00086         T0 sum = lhs(i,0) * rhs(0,j);
00087         for (unsigned int k=1; k<D; ++k)
00088           sum += lhs(i,k) * rhs(k,j);
00089         dot(i,j) = sum;
00090       }
00091     return dot;
00092   }
00093 };
00094 
00095 template<class T1, class T2>
00096 struct TSV_MetaDot< Tenzor<T1,1> , Tenzor<T2,1> >
00097 {
00098   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00099   inline static Tenzor<T0,1>
00100   apply(const Tenzor<T1,1>& lhs, const Tenzor<T2,1>& rhs) {
00101     return Tenzor<T0,1>(lhs[0]*rhs[0]);
00102   }
00103 };
00104 
00105 template<class T1, class T2>
00106 struct TSV_MetaDot< Tenzor<T1,2> , Tenzor<T2,2> >
00107 {
00108   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00109   inline static Tenzor<T0,2>
00110   apply(const Tenzor<T1,2>& lhs, const Tenzor<T2,2>& rhs) {
00111     return Tenzor<T0,2>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0),
00112                         lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1),
00113                         lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0),
00114                         lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1));
00115   }
00116 };
00117 
00118 template<class T1, class T2>
00119 struct TSV_MetaDot< Tenzor<T1,3> , Tenzor<T2,3> >
00120 {
00121   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00122   inline static Tenzor<T0,3>
00123   apply(const Tenzor<T1,3>& lhs, const Tenzor<T2,3>& rhs) {
00124     return Tenzor<T0,3>( lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0) ,
00125                          lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1) ,
00126                          lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2) ,
00127                          lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0) ,
00128                          lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1) ,
00129                          lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2) ,
00130                          lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0) ,
00131                          lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1) ,
00132                          lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2) );
00133                         
00134   }
00135 };
00136 
00138 //
00139 // Specializations for SymTenzor dot SymTenzor
00140 //
00142 
00143 template<class T1, class T2, unsigned D>
00144 struct TSV_MetaDot< SymTenzor<T1,D> , SymTenzor<T2,D> >
00145 {
00146   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00147   inline static Tenzor<T0,D>
00148   apply(const SymTenzor<T1,D>& lhs, const SymTenzor<T2,D>& rhs) {
00149     Tenzor<T0,D> dot = typename Tenzor<T0,D>::DontInitialize();
00150     for (unsigned int i=0; i<D; ++i)
00151       for (unsigned int j=i; j<D; ++j) {
00152         T0 sum = lhs.HL(i,0) * rhs.HL(j,0);
00153         int k=1;
00154         for ( ; k<i; ++k )
00155           sum += lhs.HL(i,k) * rhs.HL(j,k);
00156         for ( ; k<j; ++k )
00157           sum += lhs.HL(k,i) * rhs.HL(j,k);
00158         for ( ; k<D; ++k )
00159           sum += lhs.HL(k,i) * rhs.HL(k,j);
00160         dot(i,j) = sum;
00161       }
00162     return dot;
00163   }
00164 };
00165 
00166 template<class T1, class T2>
00167 struct TSV_MetaDot< SymTenzor<T1,1> , SymTenzor<T2,1> >
00168 {
00169   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00170   inline static Tenzor<T0,1>
00171   apply(const SymTenzor<T1,1>& lhs, const SymTenzor<T2,1>& rhs) {
00172     return Tenzor<T0,1>(lhs[0]*rhs[0]);
00173   }
00174 };
00175 
00176 template<class T1, class T2>
00177 struct TSV_MetaDot< SymTenzor<T1,2> , SymTenzor<T2,2> >
00178 {
00179   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00180   inline static Tenzor<T0,2>
00181   apply(const SymTenzor<T1,2>& lhs, const SymTenzor<T2,2>& rhs) {
00182     return Tenzor<T0,2>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0),
00183                         lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1),
00184                         lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0),
00185                         lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1));
00186   }
00187 };
00188 
00189 template<class T1, class T2>
00190 struct TSV_MetaDot< SymTenzor<T1,3> , SymTenzor<T2,3> >
00191 {
00192   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00193   inline static Tenzor<T0,3>
00194   apply(const SymTenzor<T1,3>& lhs, const SymTenzor<T2,3>& rhs) {
00195     return 
00196       Tenzor<T0,3>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0) ,
00197                    lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1) ,
00198                    lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2) ,
00199                    lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0) ,
00200                    lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1) ,
00201                    lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2) ,
00202                    lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0) ,
00203                    lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1) ,
00204                    lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2));
00205                         
00206   }
00207 };
00208 
00210 //
00211 // Specializations for Tenzor dot Vektor
00212 //
00214 
00215 template<class T1, class T2, unsigned D>
00216 struct TSV_MetaDot< Tenzor<T1,D> , Vektor<T2,D> >
00217 {
00218   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00219   inline static Vektor<T0,D>
00220   apply(const Tenzor<T1,D>& lhs, const Vektor<T2,D>& rhs) {
00221     Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00222     for (unsigned int i=0; i<D; ++i) {
00223       T0 sum = lhs(i,0)*rhs[0];
00224       for (unsigned int j=1; j<D; ++j)
00225         sum += lhs(i,j)*rhs[j];
00226       ret[i] = sum;
00227     }
00228     return ret;
00229   }
00230 };
00231 
00232 
00233 template<class T1, class T2>
00234 struct TSV_MetaDot< Tenzor<T1,1> , Vektor<T2,1> >
00235 {
00236   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00237   inline static Vektor<T0,1>
00238   apply(const Tenzor<T1,1>& lhs, const Vektor<T2,1>& rhs) {
00239     return Vektor<T0,1>( lhs[0]*rhs[0] );
00240   }
00241 };
00242 
00243 template<class T1, class T2>
00244 struct TSV_MetaDot< Tenzor<T1,2> , Vektor<T2,2> >
00245 {
00246   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00247   inline static Vektor<T0,2>
00248   apply(const Tenzor<T1,2>& lhs, const Vektor<T2,2>& rhs) {
00249     return Vektor<T0,2>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] ,
00250                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] );
00251   }
00252 };
00253 
00254 template<class T1, class T2>
00255 struct TSV_MetaDot< Tenzor<T1,3> , Vektor<T2,3> >
00256 {
00257   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00258   inline static Vektor<T0,3>
00259   apply(const Tenzor<T1,3>& lhs, const Vektor<T2,3>& rhs) {
00260     return Vektor<T0,3>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] + lhs(0,2)*rhs[2],
00261                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] + lhs(1,2)*rhs[2],
00262                          lhs(2,0)*rhs[0] + lhs(2,1)*rhs[1] + lhs(2,2)*rhs[2] );
00263   }
00264 };
00265 
00267 //
00268 // Specializations for Vektor dot Tenzor
00269 //
00271 
00272 template<class T1, class T2, unsigned D>
00273 struct TSV_MetaDot< Vektor<T1,D> , Tenzor<T2,D> >
00274 {
00275   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00276   inline static Vektor<T0,D>
00277   apply(const Vektor<T2,D>& lhs, const Tenzor<T1,D>& rhs) {
00278     Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00279     for (unsigned int i=0; i<D; ++i) {
00280       T0 sum = lhs[0]*rhs(0,i);
00281       for (unsigned int j=1; j<D; ++j)
00282         sum += lhs[j]*rhs(j,i);
00283       ret[i] = sum;
00284     }
00285     return ret;
00286   }
00287 };
00288 
00289 
00290 template<class T1, class T2>
00291 struct TSV_MetaDot< Vektor<T1,1> , Tenzor<T2,1> >
00292 {
00293   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00294   inline static Vektor<T0,1>
00295   apply(const Vektor<T1,1>& lhs, const Tenzor<T2,1>& rhs) {
00296     return Vektor<T0,1>( lhs[0]*rhs[0] );
00297   }
00298 };
00299 
00300 template<class T1, class T2>
00301 struct TSV_MetaDot< Vektor<T1,2> , Tenzor<T2,2> >
00302 {
00303   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00304   inline static Vektor<T0,2>
00305   apply(const Vektor<T1,2>& lhs, const Tenzor<T2,2>& rhs) {
00306     return Vektor<T0,2>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) ,
00307                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) );
00308   }
00309 };
00310 
00311 template<class T1, class T2>
00312 struct TSV_MetaDot< Vektor<T1,3> , Tenzor<T2,3> >
00313 {
00314   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00315   inline static Vektor<T0,3>
00316   apply(const Vektor<T1,3>& lhs, const Tenzor<T2,3>& rhs) {
00317     return Vektor<T0,3>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) + lhs[2]*rhs(2,0),
00318                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) + lhs[2]*rhs(2,1),
00319                          lhs[0]*rhs(0,2) + lhs[1]*rhs(1,2) + lhs[2]*rhs(2,2) );
00320   }
00321 };
00322 
00324 //
00325 // Specializations for SymTenzor dot Vektor
00326 //
00328 
00329 template<class T1, class T2, unsigned D>
00330 struct TSV_MetaDot< SymTenzor<T1,D> , Vektor<T2,D> >
00331 {
00332   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00333   inline static Vektor<T0,D>
00334   apply(const SymTenzor<T1,D>& lhs, const Vektor<T2,D>& rhs) {
00335     Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00336     for (unsigned int i=0; i<D; ++i) {
00337       T0 sum = lhs.HL(i,0)*rhs[0];
00338       unsigned int j=1;
00339       for ( ; j<i; ++j)
00340         sum += lhs.HL(i,j)*rhs[j];
00341       for ( ; j<D; ++j)
00342         sum += lhs.HL(j,i)*rhs[j];
00343       ret[i] = sum;
00344     }
00345     return ret;
00346   }
00347 };
00348 
00349 
00350 template<class T1, class T2>
00351 struct TSV_MetaDot< SymTenzor<T1,1> , Vektor<T2,1> >
00352 {
00353   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00354   inline static Vektor<T0,1>
00355   apply(const SymTenzor<T1,1>& lhs, const Vektor<T2,1>& rhs) {
00356     return Vektor<T0,1>( lhs[0]*rhs[0] );
00357   }
00358 };
00359 
00360 template<class T1, class T2>
00361 struct TSV_MetaDot< SymTenzor<T1,2> , Vektor<T2,2> >
00362 {
00363   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00364   inline static Vektor<T0,2>
00365   apply(const SymTenzor<T1,2>& lhs, const Vektor<T2,2>& rhs) {
00366     return Vektor<T0,2>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] ,
00367                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] );
00368   }
00369 };
00370 
00371 template<class T1, class T2>
00372 struct TSV_MetaDot< SymTenzor<T1,3> , Vektor<T2,3> >
00373 {
00374   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00375   inline static Vektor<T0,3>
00376   apply(const SymTenzor<T1,3>& lhs, const Vektor<T2,3>& rhs) {
00377     return Vektor<T0,3>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] + lhs(0,2)*rhs[2],
00378                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] + lhs(1,2)*rhs[2],
00379                          lhs(2,0)*rhs[0] + lhs(2,1)*rhs[1] + lhs(2,2)*rhs[2] );
00380   }
00381 };
00382 
00384 //
00385 // Specializations for Vektor dot SymTenzor
00386 //
00388 
00389 template<class T1, class T2, unsigned D>
00390 struct TSV_MetaDot< Vektor<T1,D> , SymTenzor<T2,D> >
00391 {
00392   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00393   inline static Vektor<T0,D>
00394   apply(const Vektor<T2,D>& lhs, const SymTenzor<T1,D>& rhs) {
00395     Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00396     for (unsigned int i=0; i<D; ++i) {
00397       T0 sum = lhs[0]*rhs[i*(i+1)/2];
00398       unsigned int j=1;
00399       for ( ; j<i; ++j)
00400         sum += lhs[j]*rhs[i*(i+1)/2+j];
00401       for ( ; j<D; ++j)
00402         sum += lhs[j]*rhs[j*(j+1)/2+i];
00403       ret[i] = sum;
00404     }
00405     return ret;
00406   }
00407 };
00408 
00409 
00410 template<class T1, class T2>
00411 struct TSV_MetaDot< Vektor<T1,1> , SymTenzor<T2,1> >
00412 {
00413   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00414   inline static Vektor<T0,1>
00415   apply(const Vektor<T1,1>& lhs, const SymTenzor<T2,1>& rhs) {
00416     return Vektor<T0,1>( lhs[0]*rhs[0] );
00417   }
00418 };
00419 
00420 template<class T1, class T2>
00421 struct TSV_MetaDot< Vektor<T1,2> , SymTenzor<T2,2> >
00422 {
00423   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00424   inline static Vektor<T0,2>
00425   apply(const Vektor<T1,2>& lhs, const SymTenzor<T2,2>& rhs) {
00426     return Vektor<T0,2>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) ,
00427                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) );
00428   }
00429 };
00430 
00431 template<class T1, class T2>
00432 struct TSV_MetaDot< Vektor<T1,3> , SymTenzor<T2,3> >
00433 {
00434   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00435   inline static Vektor<T0,3>
00436   apply(const Vektor<T1,3>& lhs, const SymTenzor<T2,3>& rhs) {
00437     return Vektor<T0,3>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) + lhs[2]*rhs(2,0),
00438                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) + lhs[2]*rhs(2,1),
00439                          lhs[0]*rhs(0,2) + lhs[1]*rhs(1,2) + lhs[2]*rhs(2,2) );
00440   }
00441 };
00442 
00444 //
00445 // Specializations for SymTenzor dot Tenzor
00446 //
00448 
00449 template<class T1, class T2, unsigned D>
00450 struct TSV_MetaDot< SymTenzor<T1,D> , Tenzor<T2,D> >
00451 {
00452   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00453   inline static Tenzor<T0,D>
00454   apply(const SymTenzor<T1,D>& lhs, const Tenzor<T2,D>& rhs) {
00455     Tenzor<T0,D> dot = typename Tenzor<T0,D>::DontInitialize();
00456     for (unsigned int i=0; i<D; ++i)
00457       for (unsigned int j=0; j<D; ++j) {
00458         T0 sum = lhs.HL(i,0) * rhs(0,j);
00459         unsigned int k = 1;
00460         for (; k<i; ++k)
00461           sum += lhs.HL(i,k) * rhs(k,j);
00462         for (; k<D; ++k)
00463           sum += lhs.HL(k,i) * rhs(k,j);
00464         dot(i,j) = sum;
00465       }
00466     return dot;
00467   }
00468 };
00469 
00470 template<class T1, class T2>
00471 struct TSV_MetaDot< SymTenzor<T1,1> , Tenzor<T2,1> >
00472 {
00473   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00474   inline static Tenzor<T0,1>
00475   apply(const SymTenzor<T1,1>& lhs, const Tenzor<T2,1>& rhs) {
00476     return Tenzor<T0,1>(lhs[0]*rhs[0]);
00477   }
00478 };
00479 
00480 template<class T1, class T2>
00481 struct TSV_MetaDot< SymTenzor<T1,2> , Tenzor<T2,2> >
00482 {
00483   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00484   inline static Tenzor<T0,2>
00485   apply(const SymTenzor<T1,2>& lhs, const Tenzor<T2,2>& rhs) {
00486     return Tenzor<T0,2>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0),
00487                         lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1),
00488                         lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0),
00489                         lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1));
00490   }
00491 };
00492 
00493 template<class T1, class T2>
00494 struct TSV_MetaDot< SymTenzor<T1,3> , Tenzor<T2,3> >
00495 {
00496   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00497   inline static Tenzor<T0,3>
00498   apply(const SymTenzor<T1,3>& lhs, const Tenzor<T2,3>& rhs) {
00499     return 
00500       Tenzor<T0,3>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0) ,
00501                    lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1) ,
00502                    lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2) ,
00503                    lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0) ,
00504                    lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1) ,
00505                    lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2) ,
00506                    lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0) ,
00507                    lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1) ,
00508                    lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2));
00509   }
00510 };
00511 
00513 //
00514 // Specializations for Tenzor dot SymTenzor
00515 //
00517 
00518 template<class T1, class T2, unsigned D>
00519 struct TSV_MetaDot< Tenzor<T1,D> , SymTenzor<T2,D> >
00520 {
00521   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00522   inline static Tenzor<T0,D>
00523   apply(const Tenzor<T1,D>& lhs, const SymTenzor<T2,D>& rhs) {
00524     Tenzor<T0,D> dot = typename Tenzor<T0,D>::DontInitialize();
00525     for (unsigned int i=0; i<D; ++i)
00526       for (unsigned int j=0; j<D; ++j) {
00527         T0 sum = lhs(i,0) * rhs.HL(j,0);
00528         unsigned int k=1;
00529         for (; k<j; ++k)
00530           sum += lhs(i,k) * rhs.HL(j,k);
00531         for (; k<D; ++k)
00532           sum += lhs(i,k) * rhs.HL(k,j);
00533         dot[i*D+j] = sum;
00534       }
00535     return dot;
00536   }
00537 };
00538 
00539 template<class T1, class T2>
00540 struct TSV_MetaDot< Tenzor<T1,1> , SymTenzor<T2,1> >
00541 {
00542   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00543   inline static Tenzor<T0,1>
00544   apply(const Tenzor<T1,1>& lhs, const SymTenzor<T2,1>& rhs) {
00545     return Tenzor<T0,1>(lhs[0]*rhs[0]);
00546   }
00547 };
00548 
00549 template<class T1, class T2>
00550 struct TSV_MetaDot< Tenzor<T1,2> , SymTenzor<T2,2> >
00551 {
00552   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00553   inline static Tenzor<T0,2>
00554   apply(const Tenzor<T1,2>& lhs, const SymTenzor<T2,2>& rhs) {
00555     return Tenzor<T0,2>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0),
00556                         lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1),
00557                         lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0),
00558                         lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1));
00559   }
00560 };
00561 
00562 template<class T1, class T2>
00563 struct TSV_MetaDot< Tenzor<T1,3> , SymTenzor<T2,3> >
00564 {
00565   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00566   inline static Tenzor<T0,3>
00567   apply(const Tenzor<T1,3>& lhs, const SymTenzor<T2,3>& rhs) {
00568     return 
00569       Tenzor<T0,3>(lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0) ,
00570                    lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1) ,
00571                    lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2) ,
00572                    lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0) ,
00573                    lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1) ,
00574                    lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2) ,
00575                    lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0) ,
00576                    lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1) ,
00577                    lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2));
00578   }
00579 };
00580 
00582 //
00583 // Specializations for Vektor dot AntiSymTenzor
00584 //
00586 
00587 template<class T1, class T2, unsigned D>
00588 struct TSV_MetaDot< Vektor<T1,D> , AntiSymTenzor<T2,D> >
00589 {
00590     typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00591     inline static Vektor<T0,D>
00592     apply(const Vektor<T2,D>& lhs, const AntiSymTenzor<T1,D>& rhs) {
00593         Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00594         for (unsigned int j=0; j<D; ++j) {
00595             double sum = 0;
00596             for (unsigned int i=0; i<j; i++)
00597                 sum -= lhs[i]*rhs[((j-1)*j/2)+i];
00598             for (unsigned int i=j+1; i<D; ++i)
00599                 sum += lhs[i]*rhs[((i-1)*i/2)+j];
00600             ret[j] = sum;
00601         }
00602         return ret;
00603     }
00604 };
00605 
00606 template<class T1, class T2>
00607 struct TSV_MetaDot< Vektor<T1,2> , AntiSymTenzor<T2,2> >
00608 {
00609   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00610   inline static Vektor<T0,2>
00611   apply(const Vektor<T1,2>& lhs, const AntiSymTenzor<T2,2>& rhs) {
00612     return Vektor<T0,2>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) ,
00613                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) );
00614   }
00615 };
00616 
00617 template<class T1, class T2>
00618 struct TSV_MetaDot< Vektor<T1,3> , AntiSymTenzor<T2,3> >
00619 {
00620   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00621   inline static Vektor<T0,3>
00622   apply(const Vektor<T1,3>& lhs, const AntiSymTenzor<T2,3>& rhs) {
00623     return Vektor<T0,3>( lhs[0]*rhs(0,0) + lhs[1]*rhs(1,0) + lhs[2]*rhs(2,0),
00624                          lhs[0]*rhs(0,1) + lhs[1]*rhs(1,1) + lhs[2]*rhs(2,1),
00625                          lhs[0]*rhs(0,2) + lhs[1]*rhs(1,2) + lhs[2]*rhs(2,2) );
00626   }
00627 };
00628 
00630 //
00631 // Specializations for AntiSymTenzor dot Vektor
00632 //
00634 
00635 template<class T1, class T2, unsigned D>
00636 struct TSV_MetaDot< AntiSymTenzor<T1,D> , Vektor<T2,D> >
00637 {
00638   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00639   inline static Vektor<T0,D>
00640   apply(const AntiSymTenzor<T1,D>& lhs, const Vektor<T2,D>& rhs) {
00641     Vektor<T0,D> ret = typename Vektor<T0,D>::DontInitialize();
00642     for (unsigned int i=0; i<D; ++i) {
00643       T0 sum = 0;
00644       for (unsigned int j=0; j<i; ++j)
00645         sum += lhs[((i-1)*i/2)+j]*rhs[j];
00646       for (unsigned int j=i+1; j<D; ++j)
00647         sum -= lhs[((j-1)*j/2)+i]*rhs[j];
00648       ret[i] = sum;
00649     }
00650     return ret;
00651   }
00652 };
00653 
00654 
00655 template<class T1, class T2>
00656 struct TSV_MetaDot< AntiSymTenzor<T1,1> , Vektor<T2,1> >
00657 {
00658   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00659   inline static Vektor<T0,1>
00660   apply(const AntiSymTenzor<T1,1>& lhs, const Vektor<T2,1>& rhs) {
00661     return Vektor<T0,1>( lhs[0]*rhs[0] );
00662   }
00663 };
00664 
00665 template<class T1, class T2>
00666 struct TSV_MetaDot< AntiSymTenzor<T1,2> , Vektor<T2,2> >
00667 {
00668   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00669   inline static Vektor<T0,2>
00670   apply(const AntiSymTenzor<T1,2>& lhs, const Vektor<T2,2>& rhs) {
00671     return Vektor<T0,2>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] ,
00672                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] );
00673   }
00674 };
00675 
00676 template<class T1, class T2>
00677 struct TSV_MetaDot< AntiSymTenzor<T1,3> , Vektor<T2,3> >
00678 {
00679   typedef typename PETEBinaryReturn<T1,T2,OpMultipply>::type T0;
00680   inline static Vektor<T0,3>
00681   apply(const AntiSymTenzor<T1,3>& lhs, const Vektor<T2,3>& rhs) {
00682     return Vektor<T0,3>( lhs(0,0)*rhs[0] + lhs(0,1)*rhs[1] + lhs(0,2)*rhs[2],
00683                          lhs(1,0)*rhs[0] + lhs(1,1)*rhs[1] + lhs(1,2)*rhs[2],
00684                          lhs(2,0)*rhs[0] + lhs(2,1)*rhs[1] + lhs(2,2)*rhs[2] );
00685   }
00686 };
00687 
00689 
00690 #endif // TSV_META_DOT_H
00691 
00692 /***************************************************************************
00693  * $RCSfile: TSVMetaDot.h,v $   $Author: adelmann $
00694  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:24 $
00695  * IPPL_VERSION_ID: $Id: TSVMetaDot.h,v 1.1.1.1 2003/01/23 07:40:24 adelmann Exp $ 
00696  ***************************************************************************/
00697 

Generated on Fri Nov 2 01:25:55 2007 for IPPL by doxygen 1.3.5