$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

dynamicsProcessor2D.hh

Go to the documentation of this file.
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