$treeview $search $mathjax
|
Palabos
Version 1.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /* This file is part of the Palabos library. 00002 * 00003 * Copyright (C) 2011 FlowKit Sarl 00004 * Avenue de Chailly 23 00005 * 1012 Lausanne, Switzerland 00006 * E-mail contact: contact@flowkit.com 00007 * 00008 * The most recent release of Palabos can be downloaded at 00009 * <http://www.palabos.org/> 00010 * 00011 * The library Palabos is free software: you can redistribute it and/or 00012 * modify it under the terms of the GNU Affero General Public License as 00013 * published by the Free Software Foundation, either version 3 of the 00014 * License, or (at your option) any later version. 00015 * 00016 * The library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Affero General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Affero General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00030 #ifndef GEOMETRIC_OPERATION_TEMPLATES_H 00031 #define GEOMETRIC_OPERATION_TEMPLATES_H 00032 00033 #include "io/parallelIO.h" 00034 #include "core/globalDefs.h" 00035 #include "core/array.h" 00036 #include "core/util.h" 00037 #include <algorithm> 00038 #include <vector> 00039 #include <cmath> 00040 #include <limits> 00041 00042 namespace plb { 00043 00044 template <typename T, int d> struct VectorTemplateImpl; 00045 template <typename T, template<typename U> class Descriptor> struct SymmetricTensor; 00046 template <typename T, template<typename U> class Descriptor> struct SymmetricRankThreeTensor; 00047 template <typename T, int d> struct SymmetricTensorImpl; 00048 template <typename T, int d> struct SymmetricRankThreeTensorImpl; 00049 00050 template <typename T, template<typename U> class Descriptor> 00051 struct VectorTemplate { 00053 static const int d = Descriptor<T>::d; 00055 static T scalarProduct(Array<T,d> const& u1, Array<T,d> const& u2) { 00056 return VectorTemplateImpl<T,d>::scalarProduct(u1,u2); 00057 } 00059 static T scalarProduct(const T u1[d], Array<T,d> const& u2) { 00060 return VectorTemplateImpl<T,d>::scalarProduct(u1,u2); 00061 } 00063 static T normSqr(Array<T,d> const& u) { 00064 return VectorTemplateImpl<T,d>::normSqr(u); 00065 } 00067 static void multiplyByScalar(Array<T,d>& u, T scalar) { 00068 VectorTemplateImpl<T,d>::multiplyByScalar(u,scalar); 00069 } 00071 static void multiplyByScalar(Array<T,d> const& u, T scalar, Array<T,d>& result) { 00072 VectorTemplateImpl<T,d>::multiplyByScalar(u,scalar,result); 00073 } 00075 static void symTensorProduct( Array<T,d> const &u, Array<T,d> const &v, 00076 Array<T,SymmetricTensor<T,Descriptor>::n> &result) 00077 { 00078 VectorTemplateImpl<T,d>::symTensorProduct(u,v,result); 00079 } 00081 static void symTensorProduct(Array<T,d> const &u, Array<T,d> const &v, Array<T,d> const &w, 00082 Array<T,SymmetricRankThreeTensor<T,Descriptor>::n> &result) 00083 { 00084 VectorTemplateImpl<T,d>::symTensorProduct(u,v,w,result); 00085 } 00086 }; 00087 00088 template <typename T, int d> 00089 struct VectorTemplateImpl { 00090 static T scalarProduct(Array<T,d> const& u1, Array<T,d> const& u2) { 00091 T result = T(); 00092 for (int iD=0; iD<d; ++iD) { 00093 result += u1[iD]*u2[iD]; 00094 } 00095 return result; 00096 } 00097 static T scalarProduct(const T u1[d], Array<T,d> const& u2) { 00098 T result = T(); 00099 for (int iD=0; iD<d; ++iD) { 00100 result += u1[iD]*u2[iD]; 00101 } 00102 return result; 00103 } 00104 static T normSqr(Array<T,d> const& u) { 00105 return scalarProduct(u,u); 00106 } 00107 static void multiplyByScalar(Array<T,d>& u, T scalar) { 00108 for (int iD=0; iD<d; ++iD) { 00109 u[iD] *= scalar; 00110 } 00111 } 00112 00113 static void multiplyByScalar(Array<T,d> const& u, T scalar, Array<T,d>& result) { 00114 for (int iD=0; iD<d; ++iD) { 00115 result[iD] = u[iD]*scalar; 00116 } 00117 } 00118 00119 static void symTensorProduct(Array<T,d> const &u, Array<T,d> const &v, Array<T,SymmetricTensorImpl<T,d>::n> &result) { 00120 int iPi = 0; 00121 for (int iA = 0; iA < d; ++iA) { 00122 for (int iB = iA; iB < d; ++iB) { 00123 result[iPi] = u[iA]*v[iB]; 00124 ++iPi; 00125 } 00126 } 00127 } 00128 00129 static void symTensorProduct(Array<T,d> const &u, Array<T,d> const &v, Array<T,d> const &w, 00130 Array<T,SymmetricRankThreeTensorImpl<T,d>::n> &result) { 00131 int iPi = 0; 00132 for (int iA = 0; iA < d; ++iA) { 00133 for (int iB = iA; iB < d; ++iB) { 00134 for (int iC = iB; iC < d; ++iC) { 00135 result[iPi] = u[iA]*v[iB]*w[iC]; 00136 ++iPi; 00137 } 00138 } 00139 } 00140 } 00141 }; 00142 00143 00144 template <typename T> 00145 struct VectorTemplateImpl<T,2> { 00146 static T scalarProduct(Array<T,2> const& u1, Array<T,2> const& u2) { 00147 return u1[0]*u2[0] + u1[1]*u2[1]; 00148 } 00149 static T scalarProduct(const T u1[2], Array<T,2> const& u2) { 00150 return u1[0]*u2[0] + u1[1]*u2[1]; 00151 } 00152 static T normSqr(Array<T,2> const& u) { 00153 return u[0]*u[0] + u[1]*u[1]; 00154 } 00155 static void multiplyByScalar(Array<T,2>& u, T scalar) { 00156 u[0] *= scalar; 00157 u[1] *= scalar; 00158 } 00159 static void multiplyByScalar(Array<T,2> const& u, T scalar, Array<T,2>& result) { 00160 result[0] = u[0]*scalar; 00161 result[1] = u[1]*scalar; 00162 } 00163 static void symTensorProduct(Array<T,2> const &u, Array<T,2> const &v, Array<T,3> &result) { 00164 result[0] = u[0]*v[0]; 00165 result[1] = u[0]*v[1]; 00166 result[2] = u[1]*v[1]; 00167 } 00168 static void symTensorProduct(Array<T,2> const &u, Array<T,2> const &v, Array<T,2> const &w, 00169 Array<T,4> &result) { 00170 result[0] = u[0]*v[0]*w[0]; 00171 result[1] = u[0]*v[0]*w[1]; 00172 result[2] = u[0]*v[1]*w[1]; 00173 result[3] = u[1]*v[1]*w[1]; 00174 } 00175 }; 00176 00177 00178 template <typename T> 00179 struct VectorTemplateImpl<T,3> { 00180 static T scalarProduct(Array<T,3> const& u1, Array<T,3> const& u2) { 00181 return u1[0]*u2[0] + u1[1]*u2[1] + u1[2]*u2[2]; 00182 } 00183 static T scalarProduct(const T u1[3], Array<T,3> const& u2) { 00184 return u1[0]*u2[0] + u1[1]*u2[1] + u1[2]*u2[2]; 00185 } 00186 static T normSqr(Array<T,3> const& u) { 00187 return u[0]*u[0] + u[1]*u[1] + u[2]*u[2]; 00188 } 00189 static void multiplyByScalar(Array<T,3>& u, T scalar) { 00190 u[0] *= scalar; 00191 u[1] *= scalar; 00192 u[2] *= scalar; 00193 } 00194 static void multiplyByScalar(Array<T,3> const& u, T scalar, Array<T,3>& result) { 00195 result[0] = u[0]*scalar; 00196 result[1] = u[1]*scalar; 00197 result[2] = u[2]*scalar; 00198 } 00199 static void symTensorProduct(Array<T,3> const &u, Array<T,3> const &v, Array<T,6> &result) { 00200 result[0] = u[0]*v[0]; 00201 result[1] = u[0]*v[1]; 00202 result[2] = u[0]*v[2]; 00203 result[3] = u[1]*v[1]; 00204 result[4] = u[1]*v[2]; 00205 result[5] = u[2]*v[2]; 00206 } 00207 static void symTensorProduct(Array<T,3> const &u, Array<T,3> const &v, Array<T,3> const &w, 00208 Array<T,10> &result) { 00209 result[0] = u[0]*v[0]*w[0]; 00210 result[1] = u[0]*v[0]*w[1]; 00211 result[2] = u[0]*v[0]*w[2]; 00212 result[3] = u[0]*v[1]*w[1]; 00213 result[4] = u[0]*v[1]*w[2]; 00214 result[5] = u[0]*v[2]*w[2]; 00215 result[6] = u[1]*v[1]*w[1]; 00216 result[7] = u[1]*v[1]*w[2]; 00217 result[8] = u[1]*v[2]*w[2]; 00218 result[9] = u[2]*v[2]*w[2]; 00219 } 00220 }; 00221 00222 00223 template <typename T, int d> struct SymmetricTensorImpl { }; 00224 00225 template<typename T> struct SymmetricTensorImpl<T,2> { 00226 static const int n = 3; 00227 enum Indices { xx=0, xy=1, yy=2 }; 00228 static void matVectMult(Array<T,n> const& mat, Array<T,2> const& vect, Array<T,2>& result) { 00229 result[0] = mat[xx]*vect[0] + mat[xy]*vect[1]; 00230 result[1] = mat[xy]*vect[0] + mat[yy]*vect[1]; 00231 } 00232 static T tensorNormSqr(Array<T,n> const& mat) { 00233 return mat[xx]*mat[xx]+mat[yy]*mat[yy] + (T)2*mat[xy]*mat[xy]; 00234 } 00235 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00236 return A[xx]*B[xx]+A[yy]*B[yy]+ (T)2*A[xy]*B[xy]; 00237 } 00238 static T trace(Array<T,n> const &A) { 00239 return A[xx] + A[yy]; 00240 } 00241 static Array<T,n> id() { 00242 return Array<T,n>((T)1,T(),(T)1); 00243 } 00244 }; 00245 00246 template<typename T> struct SymmetricTensorImpl<T,3> { 00247 static const int n = 6; 00248 enum Indices { xx=0, xy=1, xz=2, yy=3, yz=4, zz=5 }; 00249 static void matVectMult(Array<T,n> const& mat, Array<T,3> const& vect, Array<T,3>& result) { 00250 result[0] = mat[xx]*vect[0] + mat[xy]*vect[1] + mat[xz]*vect[2]; 00251 result[1] = mat[xy]*vect[0] + mat[yy]*vect[1] + mat[yz]*vect[2]; 00252 result[2] = mat[xz]*vect[0] + mat[yz]*vect[1] + mat[zz]*vect[2]; 00253 } 00254 static T tensorNormSqr(Array<T,n> const& mat) { 00255 return mat[xx]*mat[xx]+mat[yy]*mat[yy]+mat[zz]*mat[zz] 00256 + (T)2*mat[xy]*mat[xy] + (T)2*mat[xz]*mat[xz] + (T)2*mat[yz]*mat[yz]; 00257 } 00258 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00259 return A[xx]*B[xx]+A[yy]*B[yy]+A[zz]*B[zz] 00260 + (T)2*(A[xy]*B[xy] + A[xz]*B[xz] + A[yz]*B[yz]); 00261 } 00262 static T trace(Array<T,n> const &A) { 00263 return A[xx] + A[yy] + A[zz]; 00264 } 00265 static Array<T,n> id() { 00266 Array<T,n> I; 00267 00268 I[0] = (T)1; 00269 I[1] = T(); 00270 I[2] = T(); 00271 I[3] = (T)1; 00272 I[4] = T(); 00273 I[5] = (T)1; 00274 00275 return I; 00276 } 00277 }; 00278 00280 template <typename T, template<typename U> class Descriptor> 00281 struct SymmetricTensor { 00283 static const int d = Descriptor<T>::d; 00285 static const int n = SymmetricTensorImpl<T,d>::n; 00286 static void matVectMult(Array<T,n> const& mat, Array<T,d> const& vect, Array<T,d>& result) { 00287 SymmetricTensorImpl<T,d>::matVectMult(mat, vect, result); 00288 } 00289 static T tensorNormSqr(Array<T,n> const& mat) { 00290 return SymmetricTensorImpl<T,d>::tensorNormSqr(mat); 00291 } 00292 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00293 return SymmetricTensorImpl<T,d>::contractIndexes(A,B); 00294 } 00295 static T trace(Array<T,n> const &A) { 00296 return SymmetricTensorImpl<T,d>::trace(A); 00297 } 00298 static Array<T,n> id() { 00299 return SymmetricTensorImpl<T,d>::id(); 00300 } 00301 }; 00302 00303 template <typename T, int d> struct SymmetricRankThreeTensorImpl { }; 00304 00305 template<typename T> struct SymmetricRankThreeTensorImpl<T,2> { 00306 static const int n = 4; 00307 enum Indices { xxx=0, xxy=1, xyy=2, yyy = 3 }; 00308 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,2> & res) { 00309 res[0] = tens[xxx] + tens[xyy]; 00310 res[1] = tens[xxy] + tens[yyy]; 00311 } 00312 00313 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00314 return A[xxx]*B[xxx] + A[yyy]*B[yyy] + (T)3*(A[xxy]*B[xxy] + A[xyy]*B[xyy]); 00315 } 00316 00317 static void multWithRankTwoSymTensor(Array<T,n> const&A, Array<T,SymmetricTensorImpl<T,2>::n> const &B, 00318 Array<T,2> &x) { 00319 x[0] = A[xxx]*B[SymmetricTensorImpl<T,2>::xx] + (T)2*A[xxy]*B[SymmetricTensorImpl<T,2>::xy] + A[xyy]*B[SymmetricTensorImpl<T,2>::yy]; 00320 x[1] = A[xxy]*B[SymmetricTensorImpl<T,2>::xx] + (T)2*A[xyy]*B[SymmetricTensorImpl<T,2>::xy] + A[yyy]*B[SymmetricTensorImpl<T,2>::yy]; 00321 } 00322 }; 00323 00324 template<typename T> struct SymmetricRankThreeTensorImpl<T,3> { 00325 static const int n = 10; 00326 enum Indices { xxx=0, xxy=1, xxz=2, xyy=3, xyz=4, xzz=5, yyy=6, yyz=7, yzz=8, zzz=9 }; 00327 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,3> & res) { 00328 res[0] = tens[xxx] + tens[xyy] + tens[xzz]; 00329 res[1] = tens[xxy] + tens[yyy] + tens[yzz]; 00330 res[2] = tens[xxz] + tens[yyz] + tens[zzz]; 00331 } 00332 00333 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00334 return A[xxx]*B[xxx] + A[yyy]*B[yyy] + A[zzz]*B[zzz] 00335 + (T)3*(A[xxy]*B[xxy] + A[xxz]*B[xxz] + A[xyy]*B[xyy] + A[xzz]*B[xzz] + A[yzz]*B[yzz] + A[yyz]*B[yyz]) 00336 + (T)6*A[xyz]*B[xyz]; 00337 } 00338 00339 static void multWithRankTwoSymTensor(Array<T,n> const&A, Array<T,SymmetricTensorImpl<T,3>::n> const &B, 00340 Array<T,3> &x) { 00341 x[0] = A[xxx]*B[SymmetricTensorImpl<T,3>::xx] + A[xyy]*B[SymmetricTensorImpl<T,3>::yy] + A[xzz]*B[SymmetricTensorImpl<T,3>::zz] 00342 + (T)2*(A[xxy]*B[SymmetricTensorImpl<T,3>::xy] + A[xxz]*B[SymmetricTensorImpl<T,3>::xz] + A[xyz]*B[SymmetricTensorImpl<T,3>::yz]); 00343 x[1] = A[yyy]*B[SymmetricTensorImpl<T,3>::yy] + A[xxy]*B[SymmetricTensorImpl<T,3>::xx] + A[yzz]*B[SymmetricTensorImpl<T,3>::zz] 00344 + (T)2*(A[xyy]*B[SymmetricTensorImpl<T,3>::xy] + A[yyz]*B[SymmetricTensorImpl<T,3>::yz] + A[xyz]*B[SymmetricTensorImpl<T,3>::xz]); 00345 x[2] = A[zzz]*B[SymmetricTensorImpl<T,3>::zz] + A[xxz]*B[SymmetricTensorImpl<T,3>::xx] + A[yyz]*B[SymmetricTensorImpl<T,3>::yy] 00346 + (T)2*(A[xzz]*B[SymmetricTensorImpl<T,3>::xz] + A[yzz]*B[SymmetricTensorImpl<T,3>::yz] + A[xyz]*B[SymmetricTensorImpl<T,3>::xy]); 00347 } 00348 }; 00349 00351 template <typename T, template<typename U> class Descriptor> 00352 struct SymmetricRankThreeTensor { 00354 static const int d = Descriptor<T>::d; 00356 static const int n = SymmetricRankThreeTensorImpl<T,d>::n; 00358 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,d> &res) { 00359 SymmetricRankThreeTensorImpl<T,d>::contractLastTwoIndexes(tens, res); 00360 } 00362 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00363 return SymmetricRankThreeTensorImpl<T,d>::contractIndexes(A, B); 00364 } 00365 static void multWithRankTwoSymTensor(Array<T,n> const&A, Array<T,SymmetricTensor<T,Descriptor>::n> const &B, 00366 Array<T,d> &x) { 00367 SymmetricRankThreeTensorImpl<T,d>::multWithRankTwoSymTensor(A, B, x); 00368 } 00369 }; 00370 00371 template <typename T, int d> struct SymmetricRankFourTensorImpl { }; 00372 00373 template<typename T> struct SymmetricRankFourTensorImpl<T,2> { 00374 static const int n = 5; 00375 enum Indices { xxxx=0, xxxy=1, xxyy=2, xyyy = 3, yyyy = 4 }; 00376 00377 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00378 return A[xxxx]*B[xxxx] + A[yyyy]*B[yyyy] + (T)4*(A[xxxy]*B[xxxy] + A[xyyy]*B[xyyy]) + (T)6*A[xxyy]*B[xxyy]; 00379 } 00381 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,3> &res) { 00382 res[SymmetricTensorImpl<T,2>::xx] = tens[xxxx]+tens[xxyy]; 00383 res[SymmetricTensorImpl<T,2>::xy] = tens[xxxy]+tens[xyyy]; 00384 res[SymmetricTensorImpl<T,2>::yy] = tens[xxyy]+tens[yyyy]; 00385 } 00387 static void multWithRankThreeSymTensor(Array<T,n> const&A, 00388 Array<T,SymmetricRankThreeTensorImpl<T,2>::n> const &B, 00389 Array<T,2> &x) { 00390 typedef SymmetricRankThreeTensorImpl<T,2> SRT; 00391 00392 x[0] = A[xxxx]*B[SRT::xxx]+(T)3*(A[xxxy]*B[SRT::xxy]+A[xxyy]*B[SRT::xyy])+A[xyyy]*B[SRT::yyy]; 00393 x[1] = A[xxxy]*B[SRT::xxx]+(T)3*(A[xxyy]*B[SRT::xxy]+A[xyyy]*B[SRT::xyy])+A[yyyy]*B[SRT::yyy]; 00394 } 00395 }; 00396 00397 template<typename T> struct SymmetricRankFourTensorImpl<T,3> { 00398 static const int n = 15; 00399 enum Indices { xxxx=0, xxxy=1, xxxz=2, xxyy=3, xxyz=4, xxzz=5, xyyy=6, xyyz=7, xyzz=8, xzzz=9, 00400 yyyy=10, yyyz=11, yyzz=12, yzzz=13, zzzz=14 }; 00401 00402 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00403 return A[xxxx]*B[xxxx] + A[yyyy]*B[yyyy] + A[zzzz]*B[zzzz] 00404 + (T)4*(A[xxxy]*B[xxxy] + A[xxxz]*B[xxxz] + A[xyyy]*B[xyyy] + A[xzzz]*B[xzzz] + A[yyyz]*B[yyyz] + A[yzzz]*B[yzzz]) 00405 + (T)6*(A[xxyy]*B[xxyy] + A[xxzz]*B[xxzz] + A[yyzz]*B[yyzz]) 00406 + (T)12*(A[xxyz]*B[xxyz] + A[xyyz]*B[xyyz] + A[xyzz]*B[xyzz]); 00407 } 00409 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,6> &res) { 00410 res[SymmetricTensorImpl<T,3>::xx] = tens[xxxx]+tens[xxyy]+tens[xxzz]; 00411 res[SymmetricTensorImpl<T,3>::xy] = tens[xxxy]+tens[xyyy]+tens[xyzz]; 00412 res[SymmetricTensorImpl<T,3>::xz] = tens[xxxz]+tens[xyyz]+tens[xzzz]; 00413 res[SymmetricTensorImpl<T,3>::yy] = tens[xxyy]+tens[yyyy]+tens[yyzz]; 00414 res[SymmetricTensorImpl<T,3>::yz] = tens[xxyz]+tens[yyyz]+tens[yzzz]; 00415 res[SymmetricTensorImpl<T,3>::zz] = tens[xxzz]+tens[yyzz]+tens[zzzz]; 00416 } 00417 static void multWithRankThreeSymTensor(Array<T,n> const&A, 00418 Array<T,SymmetricRankThreeTensorImpl<T,3>::n> const &B, 00419 Array<T,3> &x) { 00420 typedef SymmetricRankThreeTensorImpl<T,3> SRT; 00421 00422 x[0] = A[xxxx]*B[SRT::xxx]+A[xyyy]*B[SRT::yyy]+A[xzzz]*B[SRT::zzz] 00423 +(T)3*(A[xxxy]*B[SRT::xxy]+A[xxyy]*B[SRT::xyy]+A[xxxz]*B[SRT::xxz]+A[xyyz]*B[SRT::yyz]+A[xxzz]*B[SRT::xzz]+A[xyzz]*B[SRT::yzz]) 00424 +(T)6*A [xxyz]*B[SRT::xyz]; 00425 00426 x[1] = A[yyyy]*B[SRT::yyy]+A[xxxy]*B[SRT::xxx]+A[yzzz]*B[SRT::zzz] 00427 +(T)3*(A[xxyy]*B[SRT::xxy]+A[xyyy]*B[SRT::xyy]+A[yyyz]*B[SRT::yyz]+A[yyzz]*B[SRT::yzz]+A[xyzz]*B[SRT::xzz]+A[xxyz]*B[SRT::xxz]) 00428 +(T)6*A[xyyz]*B[SRT::xyz]; 00429 00430 x[2] = A[zzzz]*B[SRT::zzz]+A[xxxz]*B[SRT::xxx]+A[yyyz]*B[SRT::yyy] 00431 +(T)3*(A[xxyz]*B[SRT::xxy]+A[xyyz]*B[SRT::xyy]+A[xxzz]*B[SRT::xxz]+A[yyzz]*B[SRT::yyz]+A[xzzz]*B[SRT::xzz]+A[yzzz]*B[SRT::yzz]) 00432 +(T)6*A[xyzz]*B[SRT::xyz]; 00433 } 00434 }; 00435 00437 template <typename T, template<typename U> class Descriptor> 00438 struct SymmetricRankFourTensor { 00440 static const int d = Descriptor<T>::d; 00442 static const int n = SymmetricRankFourTensorImpl<T,d>::n; 00443 00445 static T contractIndexes(Array<T,n> const& A, Array<T,n> const& B) { 00446 return SymmetricRankFourTensorImpl<T,d>::contractIndexes(A, B); 00447 } 00449 static void contractLastTwoIndexes(Array<T,n> const& tens, Array<T,SymmetricTensor<T,Descriptor>::n> &res) { 00450 SymmetricRankFourTensorImpl<T,d>::contractLastTwoIndexes(tens, res); 00451 } 00452 static void multWithRankThreeSymTensor(Array<T,n> const&A, 00453 Array<T,SymmetricRankThreeTensor<T,Descriptor>::n> const &B, 00454 Array<T,d> &x) { 00455 SymmetricRankFourTensorImpl<T,d>::multWithRankThreeSymTensor(A, B, x); 00456 } 00457 }; 00458 00459 template <typename T> 00460 void crossProduct(Array<T,3> const& u1, Array<T,3> const& u2, Array<T,3>& result) 00461 { 00462 result[0] = u1[1]*u2[2] - u1[2]*u2[1]; 00463 result[1] = u1[2]*u2[0] - u1[0]*u2[2]; 00464 result[2] = u1[0]*u2[1] - u1[1]*u2[0]; 00465 } 00466 00468 template<typename T, pluint n> 00469 T dot(Array<T,n> const& v1, Array<T,n> const& v2) { 00470 return VectorTemplateImpl<T,n>::scalarProduct(v1,v2); 00471 } 00472 00474 template<typename T, pluint n> 00475 T dot(T v1[n], Array<T,n> const& v2) { 00476 return VectorTemplateImpl<T,n>::scalarProduct(v1,v2); 00477 } 00478 00479 template<typename T, pluint n> 00480 T normSqr(Array<T,n> const& v) { 00481 return VectorTemplateImpl<T,n>::normSqr(v); 00482 } 00483 00484 template<typename T, pluint n> 00485 T norm(Array<T,n> const& v) { 00486 return sqrt(normSqr<T,n>(v)); 00487 } 00488 00489 template<typename T> 00490 T computeTriangleArea(Array<T,3> const& v0, Array<T,3> const& v1, Array<T,3> const& v2) 00491 { 00492 Array<T,3> e01 = v1 - v0; 00493 Array<T,3> e02 = v2 - v0; 00494 Array<T,3> cross; 00495 crossProduct<T>(e01, e02, cross); 00496 00497 return 0.5 * norm<T,3>(cross); 00498 } 00499 00500 template<typename T> 00501 T computeTriangleArea(T *v0, T *v1, T *v2) 00502 { 00503 int i; 00504 T e01[3], e02[3], cross[3]; 00505 00506 for (i = 0; i < 3; e01[i] = v1[i] - v0[i], i++) 00507 ; 00508 for (i = 0; i < 3; e02[i] = v2[i] - v0[i], i++) 00509 ; 00510 00511 cross[0] = e01[1]*e02[2] - e01[2]*e02[1]; 00512 cross[1] = e01[2]*e02[0] - e01[0]*e02[2]; 00513 cross[2] = e01[0]*e02[1] - e01[1]*e02[0]; 00514 00515 return 0.5 * sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]); 00516 } 00517 00520 template<typename T> 00521 T angleBetweenVectors(Array<T,3> const& v1, Array<T,3> const& v2) 00522 { 00523 Array<T,3> cross; 00524 crossProduct<T>(v1, v2, cross); 00525 return atan2(norm(cross), dot(v1,v2)); 00526 } 00527 00528 template<typename T> 00529 Array<T,3> rotateAtOrigin(Array<T,3> const& p, Array<T,3> const& normedAxis, T theta) { 00530 Array<T,3> const& u = normedAxis; 00531 T d = sqrt(u[1]*u[1] + u[2]*u[2]); 00532 00533 Array<T,3> q1 = p; 00534 Array<T,3> q2 = q1; 00535 00536 T eps = 1.e-2; 00537 //T eps = (T)100.*std::numeric_limits<T>::epsilon(); 00538 // Rotate about the x-axis to be in xz-plane. 00539 if (!util::fpequal(d, (T)0., eps)) { 00540 q2[0] = q1[0]; 00541 q2[1] = q1[1] * u[2] / d - q1[2] * u[1] / d; 00542 q2[2] = q1[1] * u[1] / d + q1[2] * u[2] / d; 00543 } 00544 00545 // Rotate about the y-axis to fall on z-axis. 00546 q1[0] = q2[0] * d - q2[2] * u[0]; 00547 q1[1] = q2[1]; 00548 q1[2] = q2[0] * u[0] + q2[2] * d; 00549 00550 // Perform desired rotation. 00551 T ct = cos(theta); 00552 T st = sin(theta); 00553 q2[0] = q1[0] * ct - q1[1] * st; 00554 q2[1] = q1[0] * st + q1[1] * ct; 00555 q2[2] = q1[2]; 00556 00557 // Rotate backward around y-axis. 00558 q1[0] = q2[0] * d + q2[2] * u[0]; 00559 q1[1] = q2[1]; 00560 q1[2] = - q2[0] * u[0] + q2[2] * d; 00561 00562 q2 = q1; 00563 // Rotate backward around x-axis. 00564 if (!util::fpequal(d, (T)0., eps)) { 00565 q2[0] = q1[0]; 00566 q2[1] = q1[1] * u[2] / d + q1[2] * u[1] / d; 00567 q2[2] = - q1[1] * u[1] / d + q1[2] * u[2] / d; 00568 } 00569 00570 return q2; 00571 } 00572 00573 } // namespace plb 00574 00575 #endif
1.6.3
1.6.3