$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 #ifndef FINITE_DIFFERENCE_BOUNDARY_PROCESSOR_3D_HH 00026 #define FINITE_DIFFERENCE_BOUNDARY_PROCESSOR_3D_HH 00027 00028 #include "boundaryCondition/finiteDifferenceBoundaryProcessor3D.h" 00029 #include "finiteDifference/finiteDifference3D.h" 00030 #include "atomicBlock/blockLattice3D.h" 00031 #include "latticeBoltzmann/offEquilibriumTemplates.h" 00032 #include "latticeBoltzmann/geometricOperationTemplates.h" 00033 #include "core/processorIdentifiers3D.h" 00034 #include <typeinfo> 00035 00036 namespace plb { 00037 00038 namespace fdBoundaryAlgorithm { 00039 00040 00041 00042 } // namespace fdBoundaryAlgorithm 00043 00045 00046 template<typename T, template<typename U> class Descriptor, int direction, int orientation> 00047 const int PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>::staticId = 00048 meta::registerProcessor3D < PlaneFdBoundaryFunctional3D<T, Descriptor, direction, orientation>, 00049 T, Descriptor, direction, orientation> (std::string("PlaneFdBoundary3D")); 00050 00051 template<typename T, template<typename U> class Descriptor, int direction, int orientation> 00052 void PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>::process ( 00053 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00054 { 00055 PLB_ASSERT( domain.x0==domain.x1 || domain.y0==domain.y1 || 00056 domain.z0==domain.z1 ); 00057 00058 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00059 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00060 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00061 processCell(iX,iY,iZ, lattice); 00062 } 00063 } 00064 } 00065 } 00066 00067 template<typename T, template<typename U> class Descriptor, int direction, int orientation> 00068 void PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>::processCell ( 00069 plint iX, plint iY, plint iZ, BlockLattice3D<T,Descriptor>& lattice ) 00070 { 00071 typedef SymmetricTensorImpl<T,Descriptor<T>::d> S; 00072 Array<T,Descriptor<T>::d> dx_u, dy_u, dz_u; 00073 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 00074 Dynamics<T,Descriptor>& dynamics = cell.getDynamics(); 00075 T rho = cell.computeDensity(); 00076 Array<T,Descriptor<T>:: d> vel; 00077 cell.computeVelocity(vel); 00078 00079 interpolateGradients<0> ( lattice, dx_u, iX, iY, iZ ); 00080 interpolateGradients<1> ( lattice, dy_u, iX, iY, iZ ); 00081 interpolateGradients<2> ( lattice, dz_u, iX, iY, iZ ); 00082 T dx_ux = dx_u[0]; 00083 T dy_ux = dy_u[0]; 00084 T dz_ux = dz_u[0]; 00085 T dx_uy = dx_u[1]; 00086 T dy_uy = dy_u[1]; 00087 T dz_uy = dz_u[1]; 00088 T dx_uz = dx_u[2]; 00089 T dy_uz = dy_u[2]; 00090 T dz_uz = dz_u[2]; 00091 T omega = cell.getDynamics().getOmega(); 00092 T sToPi = - rho / Descriptor<T>::invCs2 / omega; 00093 Array<T,SymmetricTensor<T,Descriptor>::n> pi; 00094 pi[S::xx] = (T)2 * dx_ux * sToPi; 00095 pi[S::yy] = (T)2 * dy_uy * sToPi; 00096 pi[S::zz] = (T)2 * dz_uz * sToPi; 00097 pi[S::xy] = (dx_uy + dy_ux) * sToPi; 00098 pi[S::xz] = (dx_uz + dz_ux) * sToPi; 00099 pi[S::yz] = (dy_uz + dz_uy) * sToPi; 00100 00101 Array<T,Descriptor<T>::d> j; 00102 if (cell.getDynamics().velIsJ()) { 00103 j = vel; 00104 } 00105 else { 00106 j = rho*vel; 00107 } 00108 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00109 00110 // Computation of the particle distribution functions 00111 // according to the regularized formula 00112 for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) 00113 cell[iPop] = dynamics.computeEquilibrium(iPop,Descriptor<T>::rhoBar(rho),j,jSqr) + 00114 offEquilibriumTemplates<T,Descriptor>::fromPiToFneq(iPop, pi); 00115 } 00116 00117 template<typename T, template<typename U> class Descriptor, int direction, int orientation> 00118 PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>* 00119 PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>::clone() const 00120 { 00121 return new PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>(*this); 00122 } 00123 00124 template<typename T, template<typename U> class Descriptor, int direction, int orientation> 00125 template<int deriveDirection> 00126 void PlaneFdBoundaryFunctional3D<T,Descriptor,direction,orientation>:: 00127 interpolateGradients(BlockLattice3D<T,Descriptor> const& lattice, Array<T,Descriptor<T>::d>& velDeriv, 00128 plint iX, plint iY, plint iZ) 00129 { 00130 fd::DirectedGradients3D<T, Descriptor, direction, orientation, deriveDirection, direction==deriveDirection>:: 00131 o1_velocityDerivative(velDeriv, lattice, iX, iY, iZ); 00132 } 00133 00134 00136 00137 00138 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00139 const int OuterVelocityEdgeFunctional3D<T,Descriptor,plane,normal1,normal2>::staticId = 00140 meta::registerProcessor3D < OuterVelocityEdgeFunctional3D<T, Descriptor, plane,normal1,normal2>, 00141 T, Descriptor, plane,normal1,normal2> (std::string("OuterVelocityEdge")); 00142 00143 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00144 void OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>::process ( 00145 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00146 { 00147 PLB_ASSERT ( 00148 (plane==2 && domain.x0==domain.x1 && domain.y0==domain.y1) || 00149 (plane==1 && domain.x0==domain.x1 && domain.z0==domain.z1) || 00150 (plane==0 && domain.y0==domain.y1 && domain.z0==domain.z1) ); 00151 00152 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00153 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00154 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00155 processCell(iX,iY,iZ, lattice); 00156 } 00157 } 00158 } 00159 } 00160 00161 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00162 void OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>::processCell ( 00163 plint iX, plint iY, plint iZ, BlockLattice3D<T,Descriptor>& lattice ) 00164 { 00165 typedef SymmetricTensorImpl<T,Descriptor<T>::d> S; 00166 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 00167 Dynamics<T,Descriptor>& dynamics = cell.getDynamics(); 00168 00169 T rho10 = getNeighborRho(iX,iY,iZ,1,0, lattice); 00170 T rho01 = getNeighborRho(iX,iY,iZ,0,1, lattice); 00171 T rho20 = getNeighborRho(iX,iY,iZ,2,0, lattice); 00172 T rho02 = getNeighborRho(iX,iY,iZ,0,2, lattice); 00173 T rho = (T)2/(T)3*(rho01+rho10)-(T)1/(T)6*(rho02+rho20); 00174 00175 std::vector<Array<T,3> > dA_uB_(3); 00176 interpolateGradients<plane,0> ( lattice, dA_uB_[0], iX, iY, iZ ); 00177 interpolateGradients<direction1,normal1> ( lattice, dA_uB_[1], iX, iY, iZ ); 00178 interpolateGradients<direction2,normal2> ( lattice, dA_uB_[2], iX, iY, iZ ); 00179 std::vector<Array<T,3> > dA_uB(3); 00180 for (int iBeta=0; iBeta<3; ++iBeta) { 00181 dA_uB[plane][iBeta] = dA_uB_[0][iBeta]; 00182 dA_uB[direction1][iBeta] = dA_uB_[1][iBeta]; 00183 dA_uB[direction2][iBeta] = dA_uB_[2][iBeta]; 00184 } 00185 T omega = dynamics.getOmega(); 00186 T sToPi = - rho / Descriptor<T>::invCs2 / omega; 00187 Array<T,SymmetricTensor<T,Descriptor>::n> pi; 00188 pi[S::xx] = (T)2 * dA_uB[0][0] * sToPi; 00189 pi[S::yy] = (T)2 * dA_uB[1][1] * sToPi; 00190 pi[S::zz] = (T)2 * dA_uB[2][2] * sToPi; 00191 pi[S::xy] = (dA_uB[0][1]+dA_uB[1][0]) * sToPi; 00192 pi[S::xz] = (dA_uB[0][2]+dA_uB[2][0]) * sToPi; 00193 pi[S::yz] = (dA_uB[1][2]+dA_uB[2][1]) * sToPi; 00194 00195 // Computation of the particle distribution functions 00196 // according to the regularized formula 00197 Array<T,Descriptor<T>::d> vel, j; 00198 cell.computeVelocity(vel); 00199 00200 if (cell.getDynamics().velIsJ()) { 00201 j = vel; 00202 } 00203 else { 00204 j = rho*vel; 00205 } 00206 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00207 00208 for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) { 00209 cell[iPop] = dynamics.computeEquilibrium(iPop,Descriptor<T>::rhoBar(rho),j,jSqr) + 00210 offEquilibriumTemplates<T,Descriptor>::fromPiToFneq(iPop, pi); 00211 } 00212 } 00213 00214 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00215 OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>* 00216 OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>::clone() const 00217 { 00218 return new OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>(*this); 00219 } 00220 00221 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00222 T OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>:: 00223 getNeighborRho(plint x, plint y, plint z, plint step1, plint step2, BlockLattice3D<T,Descriptor> const& lattice) 00224 { 00225 Array<int,3> coords (x, y, z); 00226 coords[direction1] += -normal1*step1; 00227 coords[direction2] += -normal2*step2; 00228 return lattice.get(coords[0], coords[1], coords[2]).computeDensity(); 00229 } 00230 00231 template<typename T, template<typename U> class Descriptor, int plane, int normal1, int normal2> 00232 template<int deriveDirection, int orientation> 00233 void OuterVelocityEdgeFunctional3D<T,Descriptor, plane,normal1,normal2>:: 00234 interpolateGradients(BlockLattice3D<T,Descriptor> const& lattice, 00235 Array<T,Descriptor<T>::d>& velDeriv, 00236 plint iX, plint iY, plint iZ) 00237 { 00238 fd::DirectedGradients3D<T,Descriptor,deriveDirection,orientation,deriveDirection,deriveDirection!=plane>:: 00239 o1_velocityDerivative(velDeriv, lattice, iX, iY, iZ); 00240 } 00241 00243 00244 template<typename T, template<typename U> class Descriptor, int xNormal, int yNormal, int zNormal> 00245 const int OuterVelocityCornerFunctional3D<T,Descriptor,xNormal,yNormal,zNormal>::staticId = 00246 meta::registerProcessor3D < OuterVelocityCornerFunctional3D<T, Descriptor, xNormal,yNormal,zNormal>, 00247 T, Descriptor, xNormal,yNormal,zNormal> (std::string("OuterVelocityCorner3D")); 00248 00249 template<typename T, template<typename U> class Descriptor, int xNormal, int yNormal, int zNormal> 00250 void OuterVelocityCornerFunctional3D<T, Descriptor, xNormal, yNormal, zNormal>::process ( 00251 Box3D domain, BlockLattice3D<T,Descriptor>& lattice ) 00252 { 00253 plint x = domain.x0; 00254 plint y = domain.y0; 00255 plint z = domain.z0; 00256 PLB_ASSERT( x==domain.x1 && y==domain.y1 && z==domain.z1 ); 00257 00258 processCell(x,y,z, lattice); 00259 } 00260 00261 template<typename T, template<typename U> class Descriptor, int xNormal, int yNormal, int zNormal> 00262 void OuterVelocityCornerFunctional3D<T, Descriptor, xNormal, yNormal, zNormal>::processCell ( 00263 plint iX, plint iY, plint iZ, BlockLattice3D<T,Descriptor>& lattice ) 00264 { 00265 typedef SymmetricTensorImpl<T,Descriptor<T>::d> S; 00266 Cell<T,Descriptor>& cell = lattice.get(iX,iY,iZ); 00267 Dynamics<T,Descriptor>& dynamics = cell.getDynamics(); 00268 00269 T rho100 = lattice.get(iX - 1*xNormal, iY - 0*yNormal, iZ - 0*zNormal).computeDensity(); 00270 T rho010 = lattice.get(iX - 0*xNormal, iY - 1*yNormal, iZ - 0*zNormal).computeDensity(); 00271 T rho001 = lattice.get(iX - 0*xNormal, iY - 0*yNormal, iZ - 1*zNormal).computeDensity(); 00272 T rho = (T)1/(T)3 * (rho001 + rho010 + rho100); 00273 00274 Array<T,Descriptor<T>::d> dx_u, dy_u, dz_u; 00275 fd::DirectedGradients3D<T, Descriptor, 0, xNormal, 0, true>::o1_velocityDerivative(dx_u, lattice, iX,iY,iZ); 00276 fd::DirectedGradients3D<T, Descriptor, 1, yNormal, 0, true>::o1_velocityDerivative(dy_u, lattice, iX,iY,iZ); 00277 fd::DirectedGradients3D<T, Descriptor, 2, zNormal, 0, true>::o1_velocityDerivative(dz_u, lattice, iX,iY,iZ); 00278 00279 T dx_ux = dx_u[0]; 00280 T dy_ux = dy_u[0]; 00281 T dz_ux = dz_u[0]; 00282 T dx_uy = dx_u[1]; 00283 T dy_uy = dy_u[1]; 00284 T dz_uy = dz_u[1]; 00285 T dx_uz = dx_u[2]; 00286 T dy_uz = dy_u[2]; 00287 T dz_uz = dz_u[2]; 00288 T omega = dynamics.getOmega(); 00289 T sToPi = - rho / Descriptor<T>::invCs2 / omega; 00290 Array<T,SymmetricTensor<T,Descriptor>::n> pi; 00291 pi[S::xx] = (T)2 * dx_ux * sToPi; 00292 pi[S::yy] = (T)2 * dy_uy * sToPi; 00293 pi[S::zz] = (T)2 * dz_uz * sToPi; 00294 pi[S::xy] = (dx_uy + dy_ux) * sToPi; 00295 pi[S::xz] = (dx_uz + dz_ux) * sToPi; 00296 pi[S::yz] = (dy_uz + dz_uy) * sToPi; 00297 00298 // Computation of the particle distribution functions 00299 // according to the regularized formula 00300 Array<T,Descriptor<T>::d> vel, j; 00301 cell.computeVelocity(vel); 00302 if (cell.getDynamics().velIsJ()) { 00303 j = vel; 00304 } 00305 else { 00306 j = rho*vel; 00307 } 00308 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00309 00310 for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) { 00311 cell[iPop] = dynamics.computeEquilibrium(iPop,Descriptor<T>::rhoBar(rho),j,jSqr) + 00312 offEquilibriumTemplates<T,Descriptor>::fromPiToFneq(iPop, pi); 00313 } 00314 } 00315 00316 template<typename T, template<typename U> class Descriptor, int xNormal, int yNormal, int zNormal> 00317 OuterVelocityCornerFunctional3D<T, Descriptor, xNormal, yNormal, zNormal>* 00318 OuterVelocityCornerFunctional3D<T, Descriptor, xNormal, yNormal, zNormal>::clone() const 00319 { 00320 return new OuterVelocityCornerFunctional3D<T, Descriptor, xNormal, yNormal, zNormal>(*this); 00321 } 00322 00323 } // namespace plb 00324 00325 #endif // FINITE_DIFFERENCE_BOUNDARY_PROCESSOR_3D_HH
1.6.3
1.6.3