$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 00025 /* This code was written with help of a Fortran code kindly provided 00026 * by Prof. Taehun Lee, and is massively co-authored by 00027 * Andrea Parmigiani. 00028 */ 00029 00030 #ifndef HE_LEE_PROCESSOR_3D_HH 00031 #define HE_LEE_PROCESSOR_3D_HH 00032 00033 #include "heLeeProcessor3D.h" 00034 #include "latticeBoltzmann/momentTemplates.h" 00035 #include "latticeBoltzmann/geometricOperationTemplates.h" 00036 00037 namespace plb { 00038 00039 00040 template<typename T> 00041 class FiniteDifference { 00042 public: 00043 FiniteDifference(ScalarField3D<T> const& field_, 00044 plint x_, plint y_, plint z_ ) 00045 : field(field_), 00046 x(x_), y(y_), z(z_) 00047 { } 00048 T val(plint iX, plint iY, plint iZ) const { 00049 return field.get(iX,iY,iZ); 00050 } 00051 void centralGradient(Array<T,3>& gradient) const { 00052 const T c1 = (T)2./(T)9.; 00053 const T c2 = (T)1./(T)18.; 00054 const T c3 = (T)1./(T)72.; 00055 gradient[0] = 00056 ( val(x+1,y,z) - val(x-1,y,z) ) *c1 00057 + ( val(x+1,y+1,z) - val(x-1,y-1,z) 00058 +val(x+1,y-1,z) - val(x-1,y+1,z) 00059 +val(x+1,y,z+1) - val(x-1,y,z-1) 00060 +val(x+1,y,z-1) - val(x-1,y,z+1) ) *c2 00061 + ( val(x+1,y+1,z+1) - val(x-1,y-1,z-1) 00062 +val(x+1,y-1,z+1) - val(x-1,y+1,z-1) 00063 +val(x+1,y+1,z-1) - val(x-1,y-1,z+1) 00064 +val(x+1,y-1,z-1) - val(x-1,y+1,z+1) ) *c3; 00065 gradient[1] = 00066 ( val(x,y+1,z) - val(x,y-1,z) ) *c1 00067 + ( val(x+1,y+1,z) - val(x-1,y-1,z) 00068 +val(x-1,y+1,z) - val(x+1,y-1,z) 00069 +val(x,y+1,z+1) - val(x,y-1,z-1) 00070 +val(x,y+1,z-1) - val(x,y-1,z+1) ) *c2 00071 + ( val(x+1,y+1,z+1) - val(x-1,y-1,z-1) 00072 +val(x+1,y+1,z-1) - val(x-1,y-1,z+1) 00073 +val(x-1,y+1,z+1) - val(x+1,y-1,z-1) 00074 +val(x-1,y+1,z-1) - val(x+1,y-1,z+1) ) *c3; 00075 gradient[2] = 00076 ( val(x,y,z+1) - val(x,y,z-1) ) *c1 00077 + ( val(x+1,y,z+1) - val(x-1,y,z-1) 00078 +val(x-1,y,z+1) - val(x+1,y,z-1) 00079 +val(x,y+1,z+1) - val(x,y-1,z-1) 00080 +val(x,y-1,z+1) - val(x,y+1,z-1) ) *c2 00081 + ( val(x+1,y+1,z+1) - val(x-1,y-1,z-1) 00082 +val(x+1,y-1,z+1) - val(x-1,y+1,z-1) 00083 +val(x-1,y+1,z+1) - val(x+1,y-1,z-1) 00084 +val(x-1,y-1,z+1) - val(x+1,y+1,z-1) ) *c3; 00085 } 00086 void biasedGradient(Array<T,3>& gradient) const { 00087 const T c1 = (T)1./(T)9.; 00088 const T c2 = (T)1./(T)36.; 00089 const T c3 = (T)1./(T)144.; 00090 gradient[0] = 00091 ( -val(x+2,y,z) + 4.*val(x+1,y,z) 00092 -4.*val(x-1,y,z) + val(x-2,y,z) ) *c1 00093 +( -val(x+2,y+2,z) + 4.*val(x+1,y+1,z) 00094 -4.*val(x-1,y-1,z) + val(x-2,y-2,z) 00095 -val(x+2,y-2,z) + 4.*val(x+1,y-1,z) 00096 -4.*val(x-1,y+1,z) + val(x-2,y+2,z) 00097 -val(x+2,y,z+2) + 4.*val(x+1,y,z+1) 00098 -4.*val(x-1,y,z-1) + val(x-2,y,z-2) 00099 -val(x+2,y,z-2) + 4.*val(x+1,y,z-1) 00100 -4.*val(x-1,y,z+1) + val(x-2,y,z+2) ) *c2 00101 +( -val(x+2,y+2,z+2) + 4.*val(x+1,y+1,z+1) 00102 -4.*val(x-1,y-1,z-1) + val(x-2,y-2,z-2) 00103 -val(x+2,y-2,z+2) + 4.*val(x+1,y-1,z+1) 00104 -4.*val(x-1,y+1,z-1) + val(x-2,y+2,z-2) 00105 -val(x+2,y+2,z-2) + 4.*val(x+1,y+1,z-1) 00106 -4.*val(x-1,y-1,z+1) + val(x-2,y-2,z+2) 00107 -val(x+2,y-2,z-2) + 4.*val(x+1,y-1,z-1) 00108 -4.*val(x-1,y+1,z+1) + val(x-2,y+2,z+2) ) *c3; 00109 gradient[1] = 00110 ( -val(x,y+2,z) + 4.*val(x,y+1,z) 00111 -4.*val(x,y-1,z) + val(x,y-2,z) ) *c1 00112 +( -val(x+2,y+2,z) + 4.*val(x+1,y+1,z) 00113 -4.*val(x-1,y-1,z) + val(x-2,y-2,z) 00114 -val(x-2,y+2,z) + 4.*val(x-1,y+1,z) 00115 -4.*val(x+1,y-1,z) + val(x+2,y-2,z) 00116 -val(x,y+2,z+2) + 4.*val(x,y+1,z+1) 00117 -4.*val(x,y-1,z-1) + val(x,y-2,z-2) 00118 -val(x,y+2,z-2) + 4.*val(x,y+1,z-1) 00119 -4.*val(x,y-1,z+1) + val(x,y-2,z+2) ) *c2 00120 +( -val(x+2,y+2,z+2) + 4.*val(x+1,y+1,z+1) 00121 -4.*val(x-1,y-1,z-1) + val(x-2,y-2,z-2) 00122 -val(x+2,y+2,z-2) + 4.*val(x+1,y+1,z-1) 00123 -4.*val(x-1,y-1,z+1) + val(x-2,y-2,z+2) 00124 -val(x-2,y+2,z+2) + 4.*val(x-1,y+1,z+1) 00125 -4.*val(x+1,y-1,z-1) + val(x+2,y-2,z-2) 00126 -val(x-2,y+2,z-2) + 4.*val(x-1,y+1,z-1) 00127 -4.*val(x+1,y-1,z+1) + val(x+2,y-2,z+2) ) *c3; 00128 gradient[2] = 00129 ( -val(x,y,z+2) + 4.*val(x,y,z+1) 00130 -4.*val(x,y,z-1) + val(x,y,z-2) ) *c1 00131 +( -val(x+2,y,z+2) + 4.*val(x+1,y,z+1) 00132 -4.*val(x-1,y,z-1) + val(x-2,y,z-2) 00133 -val(x-2,y,z+2) + 4.*val(x-1,y,z+1) 00134 -4.*val(x+1,y,z-1) + val(x+2,y,z-2) 00135 -val(x,y+2,z+2) + 4.*val(x,y+1,z+1) 00136 -4.*val(x,y-1,z-1) + val(x,y-2,z-2) 00137 -val(x,y-2,z+2) + 4.*val(x,y-1,z+1) 00138 -4.*val(x,y+1,z-1) + val(x,y+2,z-2) ) *c2 00139 +( -val(x+2,y+2,z+2) + 4.*val(x+1,y+1,z+1) 00140 -4.*val(x-1,y-1,z-1) + val(x-2,y-2,z-2) 00141 -val(x+2,y-2,z+2) + 4.*val(x+1,y-1,z+1) 00142 -4.*val(x-1,y+1,z-1) + val(x-2,y+2,z-2) 00143 -val(x-2,y+2,z+2) + 4.*val(x-1,y+1,z+1) 00144 -4.*val(x+1,y-1,z-1) + val(x+2,y-2,z-2) 00145 -val(x-2,y-2,z+2) + 4.*val(x-1,y-1,z+1) 00146 -4.*val(x+1,y+1,z-1) + val(x+2,y+2,z-2) ) *c3; 00147 } 00148 00149 T laplacian() const 00150 { 00151 static const T c1 = (T)4./(T)9.; 00152 static const T c2 = (T)1./(T)9.; 00153 static const T c3 = (T)1./(T)36.; 00154 static const T c4 = (T)38/(T)9.; 00155 00156 return 00157 ( val(x+1,y,z)+val(x-1,y,z) 00158 +val(x,y+1,z)+val(x,y-1,z) 00159 +val(x,y,z+1)+val(x,y,z-1) ) *c1 00160 +( val(x+1,y+1,z)+val(x-1,y-1,z) 00161 +val(x+1,y-1,z)+val(x-1,y+1,z) 00162 +val(x+1,y,z+1)+val(x-1,y,z-1) 00163 +val(x+1,y,z-1)+val(x-1,y,z+1) 00164 +val(x,y+1,z+1)+val(x,y-1,z-1) 00165 +val(x,y+1,z-1)+val(x,y-1,z+1) ) *c2 00166 +( val(x+1,y+1,z+1)+val(x+1,y+1,z-1) 00167 +val(x+1,y-1,z+1)+val(x+1,y-1,z-1) 00168 +val(x-1,y+1,z+1)+val(x-1,y+1,z-1) 00169 +val(x-1,y-1,z+1)+val(x-1,y-1,z-1) ) *c3 00170 -val(x,y,z) *c4; 00171 } 00172 00173 private: 00174 ScalarField3D<T> const& field; 00175 plint x,y,z; 00176 }; 00177 00178 00179 /* *************** Compute_C_processor ***************** */ 00180 00181 template<typename T, template<typename U> class Descriptor > 00182 Compute_C_processor <T,Descriptor>::Compute_C_processor(T M_) 00183 : M(M_) 00184 { } 00185 00186 template<typename T, template<typename U> class Descriptor > 00187 void Compute_C_processor<T,Descriptor>::processGenericBlocks ( 00188 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00189 { 00190 BlockLattice3D<T,Descriptor>& f = *dynamic_cast<BlockLattice3D<T,Descriptor>*>(blocks[0]); 00191 // Laplacian of chemical potential at previous time step t-1. 00192 ScalarField3D<T>& laplaceMu = *dynamic_cast<ScalarField3D<T>*>(blocks[1]); 00193 ScalarField3D<T>& C = *dynamic_cast<ScalarField3D<T>*>(blocks[2]); 00194 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00195 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00196 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00197 // Use templates to compute order-0 moment of f. 00198 C.get(iX,iY,iZ) = momentTemplates<T,Descriptor>::get_rhoBar(f.get(iX,iY,iZ)) 00199 + 0.5 * M * laplaceMu.get(iX,iY,iZ); 00200 } 00201 } 00202 } 00203 } 00204 00205 00206 template<typename T, template<typename U> class Descriptor > 00207 Compute_C_processor<T,Descriptor>* 00208 Compute_C_processor<T,Descriptor>::clone() const 00209 { 00210 return new Compute_C_processor<T,Descriptor>(*this); 00211 } 00212 00213 template<typename T, template<typename U> class Descriptor > 00214 void Compute_C_processor<T,Descriptor>::getTypeOfModification ( 00215 std::vector<modif::ModifT>& modified ) const 00216 { 00217 modified[0] = modif::nothing; // f 00218 modified[1] = modif::nothing; // laplaceMu(t-1) 00219 modified[2] = modif::staticVariables; // C 00220 } 00221 00222 00223 /* *************** Compute_gradC_rho_mu_processor ***************** */ 00224 00225 template<typename T> 00226 Compute_gradC_rho_mu_processor<T>::Compute_gradC_rho_mu_processor ( 00227 T beta_, T kappa_, T rho_h_, T rho_l_ ) 00228 : beta(beta_), 00229 kappa(kappa_), 00230 rho_h(rho_h_), 00231 rho_l(rho_l_) 00232 { } 00233 00234 template<typename T> 00235 void Compute_gradC_rho_mu_processor<T>::processGenericBlocks ( 00236 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00237 { 00238 // blocks[0] stands for the unused f. 00239 ScalarField3D<T>& C = *dynamic_cast<ScalarField3D<T>*>(blocks[1]); 00240 TensorField3D<T,3>& gradC = *dynamic_cast<TensorField3D<T,3>*>(blocks[2]); 00241 ScalarField3D<T>& rho = *dynamic_cast<ScalarField3D<T>*>(blocks[3]); 00242 ScalarField3D<T>& mu = *dynamic_cast<ScalarField3D<T>*>(blocks[4]); 00243 00244 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00245 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00246 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00247 FiniteDifference<T>(C,iX,iY,iZ).centralGradient(gradC.get(iX,iY,iZ)); 00248 T C_ = C.get(iX,iY,iZ); 00249 rho.get(iX,iY,iZ) = C_ * (rho_h-rho_l) + rho_l; 00250 mu.get(iX,iY,iZ) = 4.*beta*C_*(C_-0.5)*(C_-1.) - 00251 kappa*FiniteDifference<T>(C,iX,iY,iZ).laplacian(); 00252 } 00253 } 00254 } 00255 } 00256 00257 00258 template<typename T> 00259 Compute_gradC_rho_mu_processor<T>* 00260 Compute_gradC_rho_mu_processor<T>::clone() const 00261 { 00262 return new Compute_gradC_rho_mu_processor<T>(*this); 00263 } 00264 00265 template<typename T> 00266 void Compute_gradC_rho_mu_processor<T>::getTypeOfModification ( 00267 std::vector<modif::ModifT>& modified ) const 00268 { 00269 modified[0] = modif::nothing; // f 00270 modified[1] = modif::nothing; // C 00271 modified[2] = modif::staticVariables; // gradC 00272 modified[3] = modif::staticVariables; // rho 00273 modified[4] = modif::staticVariables; // mu 00274 } 00275 00276 00277 /* *************** Compute_gradMu_laplaceMu_processor ***************** */ 00278 00279 template<typename T, template<typename U> class Descriptor > 00280 Compute_gradMu_laplaceMu_processor <T,Descriptor>::Compute_gradMu_laplaceMu_processor() 00281 { } 00282 00283 template<typename T, template<typename U> class Descriptor > 00284 void Compute_gradMu_laplaceMu_processor<T,Descriptor>::processGenericBlocks ( 00285 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00286 { 00287 // blocks[0] stands for the unused f. 00288 ScalarField3D<T>& mu = *dynamic_cast<ScalarField3D<T>*>(blocks[1]); 00289 TensorField3D<T,3>& gradMu = *dynamic_cast<TensorField3D<T,3>*>(blocks[2]); 00290 ScalarField3D<T>& laplaceMu = *dynamic_cast<ScalarField3D<T>*>(blocks[3]); 00291 00292 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00293 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00294 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00295 FiniteDifference<T>(mu,iX,iY,iZ).centralGradient(gradMu.get(iX,iY,iZ)); 00296 laplaceMu.get(iX,iY,iZ) = FiniteDifference<T>(mu,iX,iY,iZ).laplacian(); 00297 } 00298 } 00299 } 00300 } 00301 00302 00303 template<typename T, template<typename U> class Descriptor > 00304 Compute_gradMu_laplaceMu_processor<T,Descriptor>* 00305 Compute_gradMu_laplaceMu_processor<T,Descriptor>::clone() const 00306 { 00307 return new Compute_gradMu_laplaceMu_processor<T,Descriptor>(*this); 00308 } 00309 00310 template<typename T, template<typename U> class Descriptor > 00311 void Compute_gradMu_laplaceMu_processor<T,Descriptor>::getTypeOfModification ( 00312 std::vector<modif::ModifT>& modified ) const 00313 { 00314 modified[0] = modif::nothing; // f 00315 modified[1] = modif::nothing; // mu 00316 modified[2] = modif::staticVariables; // gradMu 00317 modified[3] = modif::staticVariables; // laplaceMu 00318 } 00319 00320 00321 /* *************** Compute_gradMu_laplaceMu_u_p1_processor ***************** */ 00322 00323 template<typename T, template<typename U> class Descriptor > 00324 Compute_gradMu_laplaceMu_u_p1_processor <T,Descriptor>::Compute_gradMu_laplaceMu_u_p1_processor ( 00325 T rho_h_, T rho_l_, T RT_ ) 00326 : rho_h(rho_h_), 00327 rho_l(rho_l_), 00328 RT(RT_) 00329 { } 00330 00331 template<typename T, template<typename U> class Descriptor > 00332 void Compute_gradMu_laplaceMu_u_p1_processor<T,Descriptor>::processGenericBlocks ( 00333 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00334 { 00335 // blocks[0] stands for the unused f. 00336 BlockLattice3D<T,Descriptor>& g = *dynamic_cast<BlockLattice3D<T,Descriptor>*>(blocks[1]); 00337 ScalarField3D<T>& C = *dynamic_cast<ScalarField3D<T>*>(blocks[2]); 00338 ScalarField3D<T>& rho = *dynamic_cast<ScalarField3D<T>*>(blocks[3]); 00339 TensorField3D<T,3>& gradC = *dynamic_cast<TensorField3D<T,3>*>(blocks[4]); 00340 ScalarField3D<T>& mu = *dynamic_cast<ScalarField3D<T>*>(blocks[5]); 00341 TensorField3D<T,3>& gradMu = *dynamic_cast<TensorField3D<T,3>*>(blocks[6]); 00342 ScalarField3D<T>& laplaceMu = *dynamic_cast<ScalarField3D<T>*>(blocks[7]); 00343 TensorField3D<T,3>& u = *dynamic_cast<TensorField3D<T,3>*>(blocks[8]); 00344 ScalarField3D<T>& p1 = *dynamic_cast<ScalarField3D<T>*>(blocks[9]); 00345 00346 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00347 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00348 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00349 Array<T,3>& u_ = u.get(iX,iY,iZ); 00350 Array<T,3>& gradMu_ = gradMu.get(iX,iY,iZ); 00351 Array<T,3>& gradC_ = gradC.get(iX,iY,iZ); 00352 T invRho = (T)1 / rho.get(iX,iY,iZ); 00353 00354 FiniteDifference<T>(mu,iX,iY,iZ).centralGradient(gradMu_); 00355 laplaceMu.get(iX,iY,iZ) = FiniteDifference<T>(mu,iX,iY,iZ).laplacian(); 00356 // Use templates to compute order-0 and order-1 moment of g. 00357 momentTemplates<T,Descriptor>::get_rhoBar_j ( 00358 g.get(iX,iY,iZ), p1.get(iX,iY,iZ), u_); 00359 u_ *= invRho/RT; 00360 u_ -= gradMu_ * ( 0.5*invRho*C.get(iX,iY,iZ) ); 00361 p1.get(iX,iY,iZ) += 00362 0.5*RT * (rho_h-rho_l) 00363 * VectorTemplateImpl<T,3>::scalarProduct(u_, gradC_); 00364 } 00365 } 00366 } 00367 } 00368 00369 00370 template<typename T, template<typename U> class Descriptor > 00371 Compute_gradMu_laplaceMu_u_p1_processor<T,Descriptor>* 00372 Compute_gradMu_laplaceMu_u_p1_processor<T,Descriptor>::clone() const 00373 { 00374 return new Compute_gradMu_laplaceMu_u_p1_processor<T,Descriptor>(*this); 00375 } 00376 00377 template<typename T, template<typename U> class Descriptor > 00378 void Compute_gradMu_laplaceMu_u_p1_processor<T,Descriptor>::getTypeOfModification ( 00379 std::vector<modif::ModifT>& modified ) const 00380 { 00381 modified[0] = modif::nothing; // f 00382 modified[1] = modif::nothing; // g 00383 modified[2] = modif::nothing; // C 00384 modified[3] = modif::nothing; // rho 00385 modified[4] = modif::nothing; // gradC 00386 modified[5] = modif::nothing; // mu 00387 modified[6] = modif::staticVariables; // gradMu 00388 modified[7] = modif::staticVariables; // laplaceMu 00389 modified[8] = modif::staticVariables; // u 00390 modified[9] = modif::staticVariables; // p1 00391 } 00392 00393 00394 /* *************** HeLeeCollisionProcessor ***************** */ 00395 00396 template<typename T, template<typename U> class Descriptor > 00397 HeLeeCollisionProcessor <T,Descriptor>::HeLeeCollisionProcessor ( 00398 T rho_h_, T rho_l_, T tau_h_, T tau_l_, T M_, T RT_, 00399 bool initialize_ ) 00400 : rho_h(rho_h_), 00401 rho_l(rho_l_), 00402 tau_h(tau_h_), 00403 tau_l(tau_l_), 00404 M(M_), 00405 RT(RT_), 00406 initialize(initialize_) 00407 { } 00408 00409 template<typename T, template<typename U> class Descriptor > 00410 void HeLeeCollisionProcessor<T,Descriptor>::computeAdvectionTerms ( 00411 ScalarField3D<T> const& C, T& adv_gradC, T& bias_adv_gradC, 00412 plint iX, plint iY, plint iZ, plint iPop ) 00413 { 00414 typedef Descriptor<T> D; 00415 T diff_p2 = C.get(iX+2*D::c[iPop][0], iY+2*D::c[iPop][1], iZ+2*D::c[iPop][2]) - 00416 C.get(iX+D::c[iPop][0], iY+D::c[iPop][1], iZ+D::c[iPop][2]); 00417 T diff_p1 = C.get(iX+D::c[iPop][0], iY+D::c[iPop][1], iZ+D::c[iPop][2]) - 00418 C.get(iX, iY, iZ); 00419 T diff_p0 = C.get(iX, iY, iZ) - 00420 C.get(iX-D::c[iPop][0], iY-D::c[iPop][1], iZ-D::c[iPop][2]); 00421 adv_gradC = diff_p1 - 0.5*(diff_p1-diff_p0); 00422 bias_adv_gradC = diff_p1 - 0.25*(diff_p2-diff_p0); 00423 } 00424 00425 template<typename T, template<typename U> class Descriptor > 00426 void HeLeeCollisionProcessor<T,Descriptor>::processGenericBlocks ( 00427 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00428 { 00429 typedef Descriptor<T> D; 00430 BlockLattice3D<T,Descriptor>& f = *dynamic_cast<BlockLattice3D<T,Descriptor>*>(blocks[0]); 00431 BlockLattice3D<T,Descriptor>& g = *dynamic_cast<BlockLattice3D<T,Descriptor>*>(blocks[1]); 00432 ScalarField3D<T>& C = *dynamic_cast<ScalarField3D<T>*>(blocks[2]); 00433 ScalarField3D<T>& rho = *dynamic_cast<ScalarField3D<T>*>(blocks[3]); 00434 TensorField3D<T,3>& gradC = *dynamic_cast<TensorField3D<T,3>*>(blocks[4]); 00435 ScalarField3D<T>& mu = *dynamic_cast<ScalarField3D<T>*>(blocks[5]); 00436 TensorField3D<T,3>& gradMu = *dynamic_cast<TensorField3D<T,3>*>(blocks[6]); 00437 ScalarField3D<T>& laplaceMu = *dynamic_cast<ScalarField3D<T>*>(blocks[7]); 00438 TensorField3D<T,3>& u = *dynamic_cast<TensorField3D<T,3>*>(blocks[8]); 00439 ScalarField3D<T>& p1 = *dynamic_cast<ScalarField3D<T>*>(blocks[9]); 00440 00441 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00442 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00443 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00444 Array<T,3>& u_ = u.get(iX,iY,iZ); 00445 T& C_ = C.get(iX,iY,iZ); 00446 T& rho_ = rho.get(iX,iY,iZ); 00447 T& laplaceMu_ = laplaceMu.get(iX,iY,iZ); 00448 T& p1_ = p1.get(iX,iY,iZ); 00449 Cell<T,Descriptor>& f_ = f.get(iX,iY,iZ); 00450 Cell<T,Descriptor>& g_ = g.get(iX,iY,iZ); 00451 00452 T tau = C_*(tau_h-tau_l) + tau_l; 00453 00454 Array<T,3> biasGradC, biasGradMu, gradP, biasGradP; 00455 FiniteDifference<T>(C,iX,iY,iZ).biasedGradient(biasGradC); 00456 FiniteDifference<T>(mu,iX,iY,iZ).biasedGradient(biasGradMu); 00457 FiniteDifference<T>(p1,iX,iY,iZ).centralGradient(gradP); 00458 FiniteDifference<T>(p1,iX,iY,iZ).biasedGradient(biasGradP); 00459 00460 T uGradC = 00461 VectorTemplateImpl<T,3>::scalarProduct(u_, gradC.get(iX,iY,iZ)); 00462 T uBiasGradC = 00463 VectorTemplateImpl<T,3>::scalarProduct(u_, biasGradC); 00464 T uGradMu = 00465 VectorTemplateImpl<T,3>::scalarProduct(u_, gradMu.get(iX,iY,iZ)); 00466 T uBiasGradMu = 00467 VectorTemplateImpl<T,3>::scalarProduct(u_, biasGradMu); 00468 T uGradP = 00469 VectorTemplateImpl<T,3>::scalarProduct(u_, gradP); 00470 T uBiasGradP = 00471 VectorTemplateImpl<T,3>::scalarProduct(u_, biasGradP); 00472 T uSqr = 00473 VectorTemplateImpl<T,3>::normSqr(u_); 00474 for (plint iPop=0; iPop<Descriptor<T>::q; ++iPop) { 00475 T ci_u = D::c[iPop][0]*u_[0]+D::c[iPop][1]*u_[1]+D::c[iPop][2]*u_[2]; 00476 T ti = Descriptor<T>::t[iPop]; 00477 T gamma0 = ti; 00478 T gammaBar = 3.*ci_u + 4.5*ci_u*ci_u - 1.5*uSqr; 00479 T gamma = ti*(1.+gammaBar); 00480 00481 T adv_gradC, bias_adv_gradC; 00482 computeAdvectionTerms(C, adv_gradC, bias_adv_gradC, iX,iY,iZ,iPop); 00483 adv_gradC -= uGradC; 00484 bias_adv_gradC -= uBiasGradC; 00485 00486 T adv_gradP, bias_adv_gradP; 00487 computeAdvectionTerms(p1, adv_gradP, bias_adv_gradP, iX,iY,iZ,iPop); 00488 adv_gradP -= uGradP; 00489 bias_adv_gradP -= uBiasGradP; 00490 00491 T adv_gradMu, bias_adv_gradMu; 00492 computeAdvectionTerms(mu, adv_gradMu, bias_adv_gradMu, iX,iY,iZ,iPop); 00493 adv_gradMu -= uGradMu; 00494 adv_gradMu *= C_; 00495 bias_adv_gradMu -= uBiasGradMu; 00496 bias_adv_gradMu *= C_; 00497 00498 T fieq = ti * C_*(1+gammaBar) 00499 - 0.5*gamma*(adv_gradC-1./RT*(adv_gradP+adv_gradMu)*C_/rho_) 00500 - 0.5*gamma*M*laplaceMu_; 00501 00502 T gieq = ti*(p1_+rho_*RT*gammaBar) 00503 - 0.5*RT*adv_gradC*(rho_h-rho_l)*(gamma-gamma0) 00504 + 0.5*gamma*adv_gradMu; 00505 if (initialize) { 00506 f_[iPop] = fieq; 00507 g_[iPop] = gieq; 00508 } 00509 else { 00510 f_[iPop] += -(f_[iPop]-fieq)* 1./(tau+0.5) 00511 +gamma* ( 00512 bias_adv_gradC-(bias_adv_gradP+bias_adv_gradMu)*1./RT*C_/rho_ ) 00513 + M*laplaceMu_*gamma; 00514 g_[iPop] += -(g_[iPop]-gieq)* 1./(tau+0.5) 00515 + bias_adv_gradC*(rho_h-rho_l)*RT*(gamma-gamma0)-bias_adv_gradMu*gamma; 00516 } 00517 } 00518 } 00519 } 00520 } 00521 } 00522 00523 00524 template<typename T, template<typename U> class Descriptor > 00525 HeLeeCollisionProcessor<T,Descriptor>* 00526 HeLeeCollisionProcessor<T,Descriptor>::clone() const 00527 { 00528 return new HeLeeCollisionProcessor<T,Descriptor>(*this); 00529 } 00530 00531 template<typename T, template<typename U> class Descriptor > 00532 void HeLeeCollisionProcessor<T,Descriptor>::getTypeOfModification ( 00533 std::vector<modif::ModifT>& modified ) const 00534 { 00535 modified[0] = modif::staticVariables; // f 00536 modified[1] = modif::staticVariables; // g 00537 modified[2] = modif::nothing; // C 00538 modified[3] = modif::nothing; // rho 00539 modified[4] = modif::nothing; // gradC 00540 modified[5] = modif::nothing; // mu 00541 modified[6] = modif::nothing; // gradMu 00542 modified[7] = modif::nothing; // laplaceMu 00543 modified[8] = modif::nothing; // u 00544 modified[9] = modif::nothing; // p1 00545 } 00546 00547 } // namespace plb 00548 00549 #endif // HE_LEE_PROCESSOR_3D_HH
1.6.3
1.6.3