$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 00028 #ifndef DYNAMICS_PROCESSOR_2D_HH 00029 #define DYNAMICS_PROCESSOR_2D_HH 00030 00031 #include "basicDynamics/dynamicsProcessor2D.h" 00032 #include "core/cell.h" 00033 #include "latticeBoltzmann/geometricOperationTemplates.h" 00034 #include "latticeBoltzmann/latticeTemplates.h" 00035 #include "atomicBlock/blockLattice2D.h" 00036 #include "multiGrid/multiGridUtil.h" 00037 #include "core/plbProfiler.h" 00038 00039 namespace plb { 00040 00041 /* ************* Class ExternalRhoJcollideAndStream2D ******************* */ 00042 00043 template<typename T, template<typename U> class Descriptor> 00044 void ExternalRhoJcollideAndStream2D<T,Descriptor>::collide ( 00045 BlockLattice2D<T,Descriptor>& lattice, Box2D const& domain, 00046 ScalarField2D<T> const& rhoBarField, Dot2D const& offset1, 00047 TensorField2D<T,2> const& jField, Dot2D const& offset2, BlockStatistics& stat ) 00048 { 00049 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00050 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00051 Cell<T,Descriptor>& cell = lattice.get(iX,iY); 00052 T rhoBar = rhoBarField.get(iX+offset1.x, iY+offset1.y); 00053 Array<T,2> const& j = jField.get(iX+offset2.x, iY+offset2.y); 00054 cell.getDynamics().collide(cell, rhoBar, j, T(), stat); 00055 cell.revert(); 00056 } 00057 } 00058 } 00059 00060 template<typename T, template<typename U> class Descriptor> 00061 void ExternalRhoJcollideAndStream2D<T,Descriptor>::bulkCollideAndStream ( 00062 BlockLattice2D<T,Descriptor>& lattice, Box2D const& domain, 00063 ScalarField2D<T> const& rhoBarField, Dot2D const& offset1, 00064 TensorField2D<T,2> const& jField, Dot2D const& offset2, BlockStatistics& stat ) 00065 { 00066 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00067 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00068 Cell<T,Descriptor>& cell = lattice.get(iX,iY); 00069 T rhoBar = rhoBarField.get(iX+offset1.x, iY+offset1.y); 00070 Array<T,2> const& j = jField.get(iX+offset2.x, iY+offset2.y); 00071 cell.getDynamics().collide(cell, rhoBar, j, T(), stat); 00072 latticeTemplates<T,Descriptor>::swapAndStream2D(lattice.grid, iX, iY); 00073 } 00074 } 00075 } 00076 00077 template<typename T, template<typename U> class Descriptor> 00078 void ExternalRhoJcollideAndStream2D<T,Descriptor>::boundaryStream ( 00079 BlockLattice2D<T,Descriptor>& lattice, 00080 Box2D const& bound, Box2D const& domain ) 00081 { 00082 // Make sure bound is contained within current lattice 00083 PLB_PRECONDITION( contained(bound, this->getBoundingBox()) ); 00084 // Make sure domain is contained within bound 00085 PLB_PRECONDITION( contained(domain, bound) ); 00086 00087 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00088 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00089 for (plint iPop=1; iPop<=Descriptor<T>::q/2; ++iPop) { 00090 plint nextX = iX + Descriptor<T>::c[iPop][0]; 00091 plint nextY = iY + Descriptor<T>::c[iPop][1]; 00092 if (nextX>=bound.x0 && nextX<=bound.x1 && nextY>=bound.y0 && nextY<=bound.y1) { 00093 std::swap(lattice.grid[iX][iY][iPop+Descriptor<T>::q/2], 00094 lattice.grid[nextX][nextY][iPop]); 00095 } 00096 } 00097 } 00098 } 00099 } 00100 00101 template<typename T, template<typename U> class Descriptor> 00102 void ExternalRhoJcollideAndStream2D<T,Descriptor>::processGenericBlocks ( 00103 Box2D domain, std::vector<AtomicBlock2D*> atomicBlocks ) 00104 { 00105 BlockLattice2D<T,Descriptor>& lattice = 00106 dynamic_cast<BlockLattice2D<T,Descriptor>&>(*atomicBlocks[0]); 00107 ScalarField2D<T> const& rhoBarField = 00108 dynamic_cast<ScalarField2D<T> const&>(*atomicBlocks[1]); 00109 TensorField2D<T,2> const& jField = 00110 dynamic_cast<TensorField2D<T,2> const&>(*atomicBlocks[2]); 00111 00112 BlockStatistics stat; 00113 stat.subscribeAverage(); 00114 stat.subscribeAverage(); 00115 stat.subscribeMax(); 00116 00117 static const plint vicinity = Descriptor<T>::vicinity; 00118 Box2D extDomain(domain.enlarge(vicinity)); 00119 00120 Dot2D offset1 = computeRelativeDisplacement(lattice, rhoBarField); 00121 Dot2D offset2 = computeRelativeDisplacement(lattice, jField); 00122 00123 global::profiler().start("collStream"); 00124 global::profiler().increment("collStreamCells", extDomain.nCells()); 00125 00126 // First, do the collision on cells within a boundary envelope of width 00127 // equal to the range of the lattice vectors (e.g. 1 for D2Q9) 00128 collide(lattice, Box2D(extDomain.x0,extDomain.x0+vicinity-1, extDomain.y0,extDomain.y1), 00129 rhoBarField, offset1, jField, offset2, stat); 00130 collide(lattice, Box2D(extDomain.x1-vicinity+1,extDomain.x1, extDomain.y0,extDomain.y1), 00131 rhoBarField, offset1, jField, offset2, stat); 00132 collide(lattice, Box2D(extDomain.x0+vicinity,extDomain.x1-vicinity, extDomain.y0,extDomain.y0+vicinity-1), 00133 rhoBarField, offset1, jField, offset2, stat); 00134 collide(lattice, Box2D(extDomain.x0+vicinity,extDomain.x1-vicinity, extDomain.y1-vicinity+1,extDomain.y1), 00135 rhoBarField, offset1, jField, offset2, stat); 00136 00137 // Then, do the efficient collideAndStream algorithm in the bulk, 00138 // excluding the envelope (this is efficient because there is no 00139 // if-then-else statement within the loop, given that the boundary 00140 // region is excluded) 00141 bulkCollideAndStream(lattice, Box2D(extDomain.x0+vicinity,extDomain.x1-vicinity, 00142 extDomain.y0+vicinity,extDomain.y1-vicinity), 00143 rhoBarField, offset1, jField, offset2, stat); 00144 00145 // Finally, do streaming in the boundary envelope to conclude the 00146 // collision-stream cycle 00147 boundaryStream(lattice, extDomain, Box2D(extDomain.x0,extDomain.x0+vicinity-1, 00148 extDomain.y0,extDomain.y1)); 00149 boundaryStream(lattice, extDomain, Box2D(extDomain.x1-vicinity+1,extDomain.x1, 00150 extDomain.y0,extDomain.y1)); 00151 boundaryStream(lattice, extDomain, Box2D(extDomain.x0+vicinity,extDomain.x1-vicinity, 00152 extDomain.y0,extDomain.y0+vicinity-1)); 00153 boundaryStream(lattice, extDomain, Box2D(extDomain.x0+vicinity,extDomain.x1-vicinity, 00154 extDomain.y1-vicinity+1,extDomain.y1)); 00155 00156 global::profiler().stop("collStream"); 00157 } 00158 00159 template<typename T, template<typename U> class Descriptor> 00160 ExternalRhoJcollideAndStream2D<T,Descriptor>* 00161 ExternalRhoJcollideAndStream2D<T,Descriptor>::clone() const 00162 { 00163 return new ExternalRhoJcollideAndStream2D<T,Descriptor>(*this); 00164 } 00165 00166 template<typename T, template<typename U> class Descriptor> 00167 void ExternalRhoJcollideAndStream2D<T,Descriptor>::getTypeOfModification ( 00168 std::vector<modif::ModifT>& modified) const 00169 { 00170 modified[0] = modif::staticVariables; 00171 modified[1] = modif::nothing; 00172 modified[2] = modif::nothing; 00173 } 00174 00175 00176 /* ************* Class Tau1CollideAndStream2D ******************* */ 00177 00178 template<typename T, template<typename U> class Descriptor> 00179 void Tau1CollideAndStream2D<T,Descriptor>::process ( 00180 Box2D domain, BlockLattice2D<T,Descriptor>& lattice ) 00181 { 00182 static const int rhoBarBeginsAt = Descriptor<T>::ExternalField::rhoBarBeginsAt; 00183 static const int jBeginsAt = Descriptor<T>::ExternalField::jBeginsAt; 00184 std::vector<T> rhoBarCol(domain.getNy()); 00185 std::vector<Array<T,2> > jCol1(domain.getNy()); 00186 Array<T,Descriptor<T>::q> fEq1(domain.getNy()); 00187 std::vector<Array<T,2> > jCol2(domain.getNy()); 00188 Array<T,Descriptor<T>::q> fEq2(domain.getNy()); 00189 00190 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00191 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00192 Cell<T,Descriptor>& cell = lattice.get(iX,iY); 00193 } 00194 } 00195 } 00196 00197 } // namespace plb 00198 00199 #endif // DYNAMICS_PROCESSOR_2D_HH
1.6.3
1.6.3