$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 GUO_ADV_DIFF_OFF_LATTICE_MODEL_3D_HH 00026 #define GUO_ADV_DIFF_OFF_LATTICE_MODEL_3D_HH 00027 00028 #include "offLattice/guoAdvDiffOffLatticeModel3D.h" 00029 #include "offLattice/nextNeighbors3D.h" 00030 #include "latticeBoltzmann/geometricOperationTemplates.h" 00031 #include "latticeBoltzmann/externalFieldAccess.h" 00032 #include <algorithm> 00033 #include <cmath> 00034 00035 namespace plb { 00036 00037 template<typename T, template<typename U> class Descriptor> 00038 GuoAdvDiffOffLatticeModel3D<T,Descriptor>::GuoAdvDiffOffLatticeModel3D ( 00039 BoundaryShape3D<T,Array<T,2> >* shape_, int flowType_ ) 00040 : OffLatticeModel3D<T,Array<T,2> >(shape_, flowType_) 00041 { } 00042 00043 template<typename T, template<typename U> class Descriptor> 00044 GuoAdvDiffOffLatticeModel3D<T,Descriptor>::GuoAdvDiffOffLatticeModel3D ( 00045 GuoAdvDiffOffLatticeModel3D<T,Descriptor> const& rhs ) 00046 : OffLatticeModel3D<T,Array<T,2> >(rhs) 00047 { } 00048 00049 template<typename T, template<typename U> class Descriptor> 00050 GuoAdvDiffOffLatticeModel3D<T,Descriptor>& 00051 GuoAdvDiffOffLatticeModel3D<T,Descriptor>::operator=(GuoAdvDiffOffLatticeModel3D<T,Descriptor> const& rhs) 00052 { 00053 OffLatticeModel3D<T,Array<T,2> >::operator=(rhs); 00054 return *this; 00055 } 00056 00057 template<typename T, template<typename U> class Descriptor> 00058 GuoAdvDiffOffLatticeModel3D<T,Descriptor>* GuoAdvDiffOffLatticeModel3D<T,Descriptor>::clone() const { 00059 return new GuoAdvDiffOffLatticeModel3D(*this); 00060 } 00061 00062 template<typename T, template<typename U> class Descriptor> 00063 plint GuoAdvDiffOffLatticeModel3D<T,Descriptor>::getNumNeighbors() const { 00064 return 2; 00065 } 00066 00067 template<typename T, template<typename U> class Descriptor> 00068 void GuoAdvDiffOffLatticeModel3D<T,Descriptor>::prepareCell ( 00069 Dot3D const& cellLocation, 00070 AtomicContainerBlock3D& container ) 00071 { 00072 Dot3D offset = container.getLocation(); 00073 GuoAdvDiffOffLatticeInfo3D* info = 00074 dynamic_cast<GuoAdvDiffOffLatticeInfo3D*>(container.getData()); 00075 PLB_ASSERT( info ); 00076 if (!this->isFluid(cellLocation+offset)) { 00077 std::vector<std::pair<int,int> > liquidNeighbors; 00078 std::vector<plint> ids; 00079 for (int iNeighbor=0; iNeighbor<NextNeighbor<T>::numNeighbors; ++iNeighbor) { 00080 int const* c = NextNeighbor<T>::c[iNeighbor]; 00081 Dot3D neighbor(cellLocation.x+c[0], cellLocation.y+c[1], cellLocation.z+c[2]); 00082 // If the non-fluid node has a fluid neighbor ... 00083 if (this->isFluid(neighbor+offset)) { 00084 // ... check how many fluid nodes it has ahead of it ... 00085 int depth = 1; 00086 for (int iDepth=2; iDepth<=getNumNeighbors(); ++iDepth) { 00087 Dot3D nextNeighbor(cellLocation.x+iDepth*c[0], 00088 cellLocation.y+iDepth*c[1], 00089 cellLocation.z+iDepth*c[2]); 00090 if (this->isFluid(nextNeighbor+offset)) { 00091 depth = iDepth; 00092 } 00093 else { 00094 break; 00095 } 00096 } 00097 // ... then add this node to the list. 00098 liquidNeighbors.push_back(std::make_pair(iNeighbor,depth)); 00099 plint iTriangle=-1; 00100 global::timer("intersect").start(); 00101 Array<T,3> locatedPoint; 00102 T distance; 00103 Array<T,3> wallNormal; 00104 Array<T,2> surfaceData; 00105 OffBoundary::Type bdType; 00106 #ifdef PLB_DEBUG 00107 bool ok = 00108 #endif 00109 this->pointOnSurface ( 00110 cellLocation+offset, Dot3D(c[0],c[1],c[2]), locatedPoint, distance, 00111 wallNormal, surfaceData, bdType, iTriangle ); 00112 global::timer("intersect").stop(); 00113 PLB_ASSERT( ok ); 00114 ids.push_back(iTriangle); 00115 //normals.push_back(wallNormal); 00116 } 00117 } 00118 if (!liquidNeighbors.empty()) { 00119 info->getDryNodes().push_back(cellLocation); 00120 info->getDryNodeFluidDirections().push_back(liquidNeighbors); 00121 info->getDryNodeIds().push_back(ids); 00122 } 00123 } 00124 } 00125 00126 template<typename T, template<typename U> class Descriptor> 00127 ContainerBlockData* 00128 GuoAdvDiffOffLatticeModel3D<T,Descriptor>::generateOffLatticeInfo() const 00129 { 00130 return new GuoAdvDiffOffLatticeInfo3D; 00131 } 00132 00133 template<typename T, template<typename U> class Descriptor> 00134 void GuoAdvDiffOffLatticeModel3D<T,Descriptor>::boundaryCompletion ( 00135 AtomicBlock3D& nonTypeLattice, 00136 AtomicContainerBlock3D& container, 00137 std::vector<AtomicBlock3D const*> const& args ) 00138 { 00139 BlockLattice3D<T,Descriptor>& lattice = 00140 dynamic_cast<BlockLattice3D<T,Descriptor>&> (nonTypeLattice); 00141 GuoAdvDiffOffLatticeInfo3D* info = 00142 dynamic_cast<GuoAdvDiffOffLatticeInfo3D*>(container.getData()); 00143 PLB_ASSERT( info ); 00144 std::vector<Dot3D> const& 00145 dryNodes = info->getDryNodes(); 00146 std::vector<std::vector<std::pair<int,int> > > const& 00147 dryNodeFluidDirections = info->getDryNodeFluidDirections(); 00148 std::vector<std::vector<plint> > const& 00149 dryNodeIds = info->getDryNodeIds(); 00150 PLB_ASSERT( dryNodes.size() == dryNodeFluidDirections.size() ); 00151 00152 Dot3D absoluteOffset = lattice.getLocation(); 00153 00154 for (pluint iDry=0; iDry<dryNodes.size(); ++iDry) { 00155 cellCompletion ( 00156 lattice, dryNodes[iDry], dryNodeFluidDirections[iDry], 00157 dryNodeIds[iDry], absoluteOffset ); 00158 } 00159 } 00160 00161 template<typename T, template<typename U> class Descriptor> 00162 void GuoAdvDiffOffLatticeModel3D<T,Descriptor>::cellCompletion ( 00163 BlockLattice3D<T,Descriptor>& lattice, 00164 Dot3D const& guoNode, 00165 std::vector<std::pair<int,int> > const& dryNodeFluidDirections, 00166 std::vector<plint> const& dryNodeIds, Dot3D const& absoluteOffset ) 00167 { 00168 typedef Descriptor<T> D; 00169 Cell<T,Descriptor>& cell = 00170 lattice.get(guoNode.x, guoNode.y, guoNode.z); 00171 plint numDirections = (plint)dryNodeFluidDirections.size(); 00172 std::vector<T> weights(numDirections); 00173 std::vector<T> rhoBar_vect(numDirections); 00174 std::vector<Array<T,Descriptor<T>::d> > jNeq_vect(numDirections); 00175 T sumWeights = T(); 00176 Array<T,3> wallNormal; 00177 for (plint iDirection=0; iDirection<numDirections; ++iDirection) { 00178 int iNeighbor = dryNodeFluidDirections[iDirection].first; 00179 int const* c = NextNeighbor<T>::c[iNeighbor]; 00180 Dot3D fluidDirection(c[0],c[1],c[2]); 00181 plint dryNodeId = dryNodeIds[iDirection]; 00182 int depth = dryNodeFluidDirections[iDirection].second; 00183 00184 Array<T,3> wallNode; 00185 Array<T,2> wallData; 00186 T wallDistance; 00187 OffBoundary::Type bdType; 00188 #ifdef PLB_DEBUG 00189 bool ok = 00190 #endif 00191 pointOnSurface( guoNode+absoluteOffset, fluidDirection, 00192 wallNode, wallDistance, wallNormal, 00193 wallData, bdType, dryNodeId ); 00194 PLB_ASSERT( ok ); 00195 T invDistanceToNeighbor = NextNeighbor<T>::invD[iNeighbor]; 00196 PLB_ASSERT( wallDistance <= NextNeighbor<T>::d[iNeighbor] ); 00197 T delta = (T)1. - wallDistance * invDistanceToNeighbor; 00198 Array<T,3> normalFluidDirection((T)fluidDirection.x, (T)fluidDirection.y, (T)fluidDirection.z); 00199 normalFluidDirection *= invDistanceToNeighbor; 00200 weights[iDirection] = util::sqr(fabs ( dot(normalFluidDirection, wallNormal) )); 00201 sumWeights += weights[iDirection]; 00202 00203 computeRhoBarJNeq ( 00204 lattice, guoNode, fluidDirection, depth, 00205 wallNode, delta, wallData, bdType, wallNormal, 00206 00207 rhoBar_vect[iDirection], jNeq_vect[iDirection] ); 00208 } 00209 00210 T rhoBar = T(); 00211 Array<T,D::d> jNeq; jNeq.resetToZero(); 00212 for (plint iDirection=0; iDirection<numDirections; ++iDirection) { 00213 rhoBar += rhoBar_vect[iDirection] * weights[iDirection]; 00214 jNeq += jNeq_vect[iDirection] * weights[iDirection]; 00215 } 00216 rhoBar /= sumWeights; 00217 jNeq /= sumWeights; 00218 00219 T dummyJsqr = T(); 00220 Array<T,SymmetricTensor<T,Descriptor>::n> dummyPiNeq; 00221 00222 Array<T,Descriptor<T>::d> j; 00223 j.from_cArray(cell.getExternal(Descriptor<T>::ExternalField::velocityBeginsAt)); 00224 j *= Descriptor<T>::fullRho(rhoBar); // At this point we got jEq. 00225 j += jNeq; // And at this point we add off-equilibrium. 00226 00227 Dynamics<T,Descriptor> const& dynamics = cell.getDynamics(); 00228 if (this->getPartialReplace()) { 00229 Cell<T,Descriptor> saveCell(cell); 00230 dynamics.regularize(cell, rhoBar, j, dummyJsqr, dummyPiNeq); 00231 for (plint iDirection=0; iDirection<numDirections; ++iDirection) { 00232 int iNeighbor = dryNodeFluidDirections[iDirection].first; 00233 plint iPop = nextNeighborPop<T,Descriptor>(iNeighbor); 00234 plint oppPop = indexTemplates::opposite<D>(iPop); 00235 cell[oppPop] = saveCell[oppPop]; 00236 } 00237 } 00238 else { 00239 dynamics.regularize(cell, rhoBar, j, dummyJsqr, dummyPiNeq); 00240 } 00241 } 00242 00243 template<typename T, template<typename U> class Descriptor> 00244 void GuoAdvDiffOffLatticeModel3D<T,Descriptor>::computeRhoBarJNeq ( 00245 BlockLattice3D<T,Descriptor> const& lattice, Dot3D const& guoNode, 00246 Dot3D const& fluidDirection, int depth, Array<T,3> const& wallNode, T delta, 00247 Array<T,2> wallData, OffBoundary::Type bdType, Array<T,3> const& wallNormal, 00248 T& rhoBar, Array<T,Descriptor<T>::d>& jNeq ) const 00249 { 00250 T wall_scalar = wallData[0]; 00251 T rhoBar1, rhoBar2; 00252 Array<T,Descriptor<T>::d> jNeq1, jNeq2, jEqDummy; 00253 Cell<T,Descriptor> const& cell1 = 00254 lattice.get( guoNode.x+fluidDirection.x, 00255 guoNode.y+fluidDirection.y, 00256 guoNode.z+fluidDirection.z ); 00257 Cell<T,Descriptor> const& cell2 = 00258 lattice.get( guoNode.x+2*fluidDirection.x, 00259 guoNode.y+2*fluidDirection.y, 00260 guoNode.z+2*fluidDirection.z ); 00261 advectionDiffusionMomentTemplates<T,Descriptor>::get_rhoBar_jEq_jNeq ( 00262 cell1, rhoBar1, jEqDummy, jNeq1 ); 00263 advectionDiffusionMomentTemplates<T,Descriptor>::get_rhoBar_jEq_jNeq ( 00264 cell2, rhoBar2, jEqDummy, jNeq2 ); 00265 T wall_rhoBar = Descriptor<T>::rhoBar(wall_scalar); 00266 00267 if (depth < 2) { 00268 jNeq = jNeq1; 00269 if (delta < (T)0.25) { 00270 rhoBar = wall_rhoBar; 00271 } 00272 else { 00273 rhoBar = 1./delta * (wall_rhoBar+(delta-1.)*rhoBar1); 00274 } 00275 } 00276 else { // depth >= 2 00277 if (delta < (T)0.75) { 00278 jNeq = delta*jNeq1 + ((T)1.-delta)*jNeq2; 00279 rhoBar = wall_rhoBar + (delta-(T)1.)*rhoBar1 + 00280 ((T)1.-delta)/((T)1.+delta)*((T)2.*wall_rhoBar+(delta-(T)1.)*rhoBar2); 00281 } 00282 else { 00283 jNeq = jNeq1; 00284 rhoBar = (T)1./delta * (wall_rhoBar+(delta-(T)1.)*rhoBar1); 00285 } 00286 } 00287 if ( bdType==OffBoundary::neumann ) 00288 { 00289 rhoBar = rhoBar1; 00290 } 00291 else if ( bdType==OffBoundary::flux ) 00292 { 00293 T dx = sqrt(util::sqr((T)fluidDirection.x)+util::sqr((T)fluidDirection.y)+util::sqr((T)fluidDirection.z)); 00294 T gradRho = wallData[0]; 00295 rhoBar = rhoBar1 + dx*gradRho; 00296 } 00297 else if ( bdType==OffBoundary::isolation ) 00298 { 00299 T dx = sqrt(util::sqr((T)fluidDirection.x)+util::sqr((T)fluidDirection.y)+util::sqr((T)fluidDirection.z)); 00300 T rhoBarOut = Descriptor<T>::rhoBar(wallData[0]); 00301 T kappa = wallData[1]; 00302 rhoBar = (rhoBar1+kappa*dx*rhoBarOut)/((T)1+kappa*dx); 00303 //pcout << "RHOBAR " << rhoBar1 << " " << rhoBarOut << " " << kappa << " " << rhoBar << std::endl; 00304 } 00305 } 00306 00307 } // namespace plb 00308 00309 #endif // GUO_ADV_DIFF_OFF_LATTICE_MODEL_3D_HH
1.6.3
1.6.3