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

zouHeDynamics.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 
00025 /* Orestis Malaspinas contributed this code.
00026  */
00027 
00028 #ifndef ZOU_HE_DYNAMICS_HH
00029 #define ZOU_HE_DYNAMICS_HH
00030 
00031 #include "boundaryCondition/zouHeDynamics.h"
00032 #include "latticeBoltzmann/dynamicsTemplates.h"
00033 #include "latticeBoltzmann/momentTemplates.h"
00034 #include "latticeBoltzmann/geometricOperationTemplates.h"
00035 #include "latticeBoltzmann/indexTemplates.h"
00036 #include "core/latticeStatistics.h"
00037 #include "core/dynamicsIdentifiers.h"
00038 #include <cmath>
00039 
00040 
00041 namespace plb {
00042 
00043 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00044 void ZouHeClosure ( Cell<T,Descriptor>& cell, Dynamics<T,Descriptor> const& dynamics )
00045 {
00046     typedef momentTemplates<T,Descriptor> mtl;
00047     typedef Descriptor<T> L;
00048 
00049     // Along all the commented parts of this code there will be an example based
00050     // on the situation where the wall's normal vector if (0,1) and the
00051     // numbering of the velocites are done according to the D2Q9 
00052     // lattice of the Palabos library.
00053 
00054     // Find all the missing populations
00055     // (directions 3,4,5)
00056     std::vector<plint> missingIndexes = indexTemplates::subIndexOutgoing<L,direction,orientation>();
00057     
00058     // Will contain the missing populations that are not normal to the wall.
00059     // (directions 3,5)
00060     std::vector<plint> missingDiagonalIndexes = missingIndexes;
00061     for (pluint iPop = 0; iPop < missingIndexes.size(); ++iPop)
00062     {
00063         plint numOfNonNullComp = 0;
00064         for (int iDim = 0; iDim < L:: d; ++iDim)
00065             numOfNonNullComp += abs(L::c[missingIndexes[iPop]][iDim]);
00066 
00067         if (numOfNonNullComp == 1)
00068         {
00069             missingDiagonalIndexes.erase(missingDiagonalIndexes.begin()+iPop);
00070             break;
00071         }
00072     }
00073 
00074     T rhoBar;
00075     Array<T,L::d> j;
00076     dynamics.computeRhoBarJ(cell, rhoBar, j);
00077     
00078     T falseRho;
00079     Array<T,L::d> falseU;
00080 
00081     T jSqr = VectorTemplate<T,Descriptor>::normSqr(j);
00082 
00083     // The unknown non equilibrium populations are bounced back
00084     // (f[3] = feq[3] + fneq[7], f[4] = feq[4] + fneq[8], 
00085     //  f[5] = feq[5] + fneq[1])
00086     for (pluint iPop = 0; iPop < missingIndexes.size(); ++iPop)
00087     {
00088         plint pop = missingIndexes[iPop];
00089         plint opp = indexTemplates::opposite<L>(pop);
00090         cell[pop] = cell[opp]
00091             - dynamics.computeEquilibrium(opp, rhoBar, j, jSqr)
00092             + dynamics.computeEquilibrium(pop, rhoBar, j, jSqr);
00093     }
00094 
00095     // We recompute rho and u in order to have the new momentum and density. Since
00096     // the momentum is not conserved from this scheme, we will corect it. By adding
00097     // a contribution to the missingDiagonalVelocities.
00098     mtl::compute_rho_uLb(cell,falseRho,falseU);
00099 
00100     Array<T,L::d> diff;
00101     for (int iDim = 0; iDim < L:: d; ++iDim) {
00102         diff[iDim] = (j[iDim] - falseRho*falseU[iDim]) / (T)missingDiagonalIndexes.size();
00103     }
00104 
00105     for (pluint iPop = 0; iPop < missingDiagonalIndexes.size(); ++iPop)
00106     {
00107         for (int iDim = 1; iDim < L::d; ++iDim)
00108         {
00109             cell[missingDiagonalIndexes[iPop]] +=
00110                     L::c[missingDiagonalIndexes[iPop]][(direction+iDim)%L::d] * diff[(direction+iDim)%L::d];
00111         }
00112     }
00113 }
00114 
00115 template<typename T, template<typename U> class Descriptor,
00116          int direction, int orientation>
00117 int ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::id =
00118     meta::registerGeneralDynamics<T,Descriptor, ZouHeVelocityDynamics<T,Descriptor,direction,orientation> >
00119             ( std::string("Boundary_ZouHeVelocity_")+util::val2str(direction) +
00120               std::string("_")+util::val2str(orientation) );
00121 
00122 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00123 ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::ZouHeVelocityDynamics (
00124         Dynamics<T,Descriptor>* baseDynamics, bool automaticPrepareCollision)
00125     : VelocityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(baseDynamics, automaticPrepareCollision)
00126 { }
00127 
00128 template<typename T, template<typename U> class Descriptor,
00129          int direction, int orientation>
00130 ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::
00131     ZouHeVelocityDynamics(HierarchicUnserializer& unserializer)
00132         : VelocityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(0, false)
00133 {
00134     unserialize(unserializer);
00135 }
00136 
00137 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00138 ZouHeVelocityDynamics<T,Descriptor,direction,orientation>*
00139     ZouHeVelocityDynamics<T,Descriptor, direction, orientation>::clone() const
00140 {
00141     return new ZouHeVelocityDynamics<T,Descriptor,direction,orientation>(*this);
00142 }
00143  
00144 template<typename T, template<typename U> class Descriptor,
00145          int direction, int orientation>
00146 void ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::serialize(HierarchicSerializer& serializer) const
00147 {
00148     VelocityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>::serialize(serializer);
00149 }
00150 
00151 template<typename T, template<typename U> class Descriptor,
00152          int direction, int orientation>
00153 void ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::unserialize(HierarchicUnserializer& unserializer)
00154 {
00155     VelocityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>::unserialize(unserializer);
00156 }
00157 
00158  
00159 template<typename T, template<typename U> class Descriptor,
00160          int direction, int orientation>
00161 int ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::getId() const {
00162     return id;
00163 }
00164 
00165 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00166 void ZouHeVelocityDynamics<T,Descriptor,direction,orientation>::completePopulations(Cell<T,Descriptor>& cell) const
00167 {
00168     ZouHeClosure<T,Descriptor,direction,orientation>(cell, *this);
00169 }
00170 
00171 
00172 template<typename T, template<typename U> class Descriptor,
00173          int direction, int orientation>
00174 int ZouHePressureDynamics<T,Descriptor,direction,orientation>::id =
00175     meta::registerGeneralDynamics<T,Descriptor, ZouHePressureDynamics<T,Descriptor,direction,orientation> >
00176             ( std::string("Boundary_ZouHePressure_")+util::val2str(direction) +
00177               std::string("_")+util::val2str(orientation) );
00178 
00179 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00180 ZouHePressureDynamics<T,Descriptor,direction,orientation>::ZouHePressureDynamics (
00181             Dynamics<T,Descriptor>* baseDynamics, bool automaticPrepareCollision )
00182     : DensityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(baseDynamics, automaticPrepareCollision)
00183 { }
00184 
00185 template<typename T, template<typename U> class Descriptor,
00186          int direction, int orientation>
00187 ZouHePressureDynamics<T,Descriptor,direction,orientation>::
00188     ZouHePressureDynamics(HierarchicUnserializer& unserializer)
00189         : DensityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(0, false)
00190 {
00191     unserialize(unserializer);
00192 }
00193 
00194 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00195 ZouHePressureDynamics<T,Descriptor,direction,orientation>*
00196     ZouHePressureDynamics<T,Descriptor, direction, orientation>::clone() const
00197 {
00198     return new ZouHePressureDynamics<T,Descriptor,direction,orientation>(*this);
00199 }
00200  
00201 template<typename T, template<typename U> class Descriptor,
00202          int direction, int orientation>
00203 void ZouHePressureDynamics<T,Descriptor,direction,orientation>::serialize(HierarchicSerializer& serializer) const
00204 {
00205     DensityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>::serialize(serializer);
00206 }
00207 
00208 template<typename T, template<typename U> class Descriptor,
00209          int direction, int orientation>
00210 void ZouHePressureDynamics<T,Descriptor,direction,orientation>::unserialize(HierarchicUnserializer& unserializer)
00211 {
00212     DensityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>::unserialize(unserializer);
00213 }
00214  
00215 template<typename T, template<typename U> class Descriptor,
00216          int direction, int orientation>
00217 int ZouHePressureDynamics<T,Descriptor,direction,orientation>::getId() const {
00218     return id;
00219 }
00220 
00221 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00222 void ZouHePressureDynamics<T,Descriptor,direction,orientation>::completePopulations(Cell<T,Descriptor>& cell) const
00223 {
00224     ZouHeClosure<T,Descriptor,direction,orientation>(cell, *this);
00225 }
00226 
00227 }  // namespace plb
00228 
00229 #endif  // ZOU_HE_DYNAMICS_HH