00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef TSV_META_DOT_H
00012 #define TSV_META_DOT_H
00013
00015
00016
00017
00019
00020 template<class T1, class T2> struct TSV_MetaDot {};
00021
00023
00024
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
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
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
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
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
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
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
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
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
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
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
00694
00695
00696
00697