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

inamuroAnalyticalDynamics.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 INAMURO_ANALYTICAL_DYNAMICS_HH
00029 #define INAMURO_ANALYTICAL_DYNAMICS_HH
00030 
00031 #include "boundaryCondition/inamuroAnalyticalDynamics.h"
00032 #include "latticeBoltzmann/indexTemplates.h"
00033 #include "core/util.h"
00034 #include "core/latticeStatistics.h"
00035 #include "core/dynamicsIdentifiers.h"
00036 #include <cmath>
00037 
00038 namespace plb {
00039 
00040 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00041 void InamuroAnalyticalClosure ( Cell<T,Descriptor>& cell, Dynamics<T,Descriptor> const& dynamics )
00042 {
00043     typedef Descriptor<T> L;
00044 
00045     // Along all the commented parts of this code there will be an example based
00046     // on the situation where the wall's normal vector if (0,1) and the
00047     // numerotation of the velocites are done according to the D2Q9 
00048     // lattice of the OpenLB library.
00049 
00050     // Find all the missing populations
00051     // (directions 3,4,5)
00052     std::vector<plint> missInd = 
00053             indexTemplates::subIndexOutgoing<L,direction,orientation>();
00054 
00055     // Will contain the missing poputations that are not normal to the wall.
00056     // (directions 3,5)
00057     std::vector<plint> missDiagInd = missInd;
00058 
00059     for (pluint iPop = 0; iPop < missInd.size(); ++iPop)
00060     {
00061         plint numOfNonNullComp = 0;
00062         for (int iDim = 0; iDim < L:: d; ++iDim)
00063             numOfNonNullComp += abs(L::c[missInd[iPop]][iDim]);
00064 
00065         if (numOfNonNullComp == 1)
00066         {
00067             missDiagInd.erase(missDiagInd.begin()+iPop);
00068             break;
00069         }
00070     }
00071 
00072     // Will contain the populations normal to the wall's normal vector.
00073     // (directions 2,6)
00074     std::vector<plint> perpInd = indexTemplates::subIndex<L,direction,0>();
00075     for (pluint iPop = 0; iPop < perpInd.size(); ++iPop)
00076     {
00077         if (L::c[perpInd[iPop]][0] == 0 && L::c[perpInd[iPop]][1] == 0)
00078         {
00079             perpInd.erase(perpInd.begin() + iPop);
00080             break;
00081         }
00082     }
00083 
00084     T rho = dynamics.computeDensity(cell);
00085     Array<T,L::d> u;
00086     dynamics.computeVelocity(cell, u);
00087 
00088     T rhoCs = T();
00089     Array<T,L::d> jCs;
00090     for (int iDim = 0; iDim < L::d; ++iDim)
00091         jCs[iDim] = T();
00092 
00093     T fSum = T();
00094     for (pluint iPop = 0; iPop < missInd.size(); ++iPop)
00095     {
00096         fSum += cell[indexTemplates::opposite<L>(missInd[iPop])];
00097     }
00098     // do not forget the "+1" in the rhoCs equation in the numerator (it's
00099     // here because fEq = usualfEq - t[i])
00100     rhoCs = ((T)6 * (-orientation * rho * u[direction] + fSum) + (T)1) /
00101         ((T)3 * u[direction] * u[direction] - orientation * (T)3 * u[direction] + (T)1);
00102 
00103     T fDiffPerp = T();
00104     for (pluint iPop = 0; iPop < perpInd.size(); ++iPop)
00105        fDiffPerp += L::c[perpInd[iPop]][(direction + 1)%2] * cell[perpInd[iPop]];
00106     fDiffPerp *= orientation;
00107 
00108     T fDiffDiag = T();
00109     for (pluint iPop = 0; iPop < missDiagInd.size(); ++iPop)
00110         fDiffDiag += L::c[indexTemplates::opposite<L>(missDiagInd[iPop])][(direction + 1)%2]
00111                     * cell[indexTemplates::opposite<L>(missDiagInd[iPop])];
00112     fDiffDiag *= orientation;
00113 
00114     jCs[(direction + 1)%L::d] = (
00115             - orientation * (T)6 * rho * u[(direction+1)%L::d]
00116             + orientation * rhoCs * u[(direction+1)%L::d]
00117             - (T)3 * rhoCs * u[direction]*u[(direction+1)%L::d]
00118             + (T)6*(fDiffPerp + fDiffDiag))
00119             / ( -orientation + (T)3 * u[direction] );
00120 
00121     for (int iDim = 0; iDim < L::d; ++iDim)
00122         jCs[iDim] += rhoCs*u[iDim];
00123 
00124     T jSqr = VectorTemplate<T,Descriptor>::normSqr(jCs);
00125 
00126     for (pluint iPop = 0; iPop < missInd.size(); ++iPop) {
00127         cell[missInd[iPop]] = dynamics.computeEquilibrium (
00128                 missInd[iPop], Descriptor<T>::rhoBar(rhoCs), jCs, jSqr );
00129     }
00130 }
00131 
00132 template<typename T, template<typename U> class Descriptor,
00133          int direction, int orientation>
00134 int InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>::id =
00135     meta::registerCompositeDynamics<T,Descriptor, InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation> >
00136             ( std::string("Boundary_InamuroAnalytical_")+util::val2str(direction) +
00137               std::string("_")+util::val2str(orientation) );
00138 
00139 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00140 InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>::InamuroAnalyticalVelocityDynamics (
00141         Dynamics<T,Descriptor>* baseDynamics, bool automaticPrepareCollision )
00142     : VelocityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(baseDynamics,automaticPrepareCollision)
00143 { }
00144 
00145 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00146 InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>*
00147     InamuroAnalyticalVelocityDynamics<T,Descriptor, direction, orientation>::clone() const
00148 {
00149     return new InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>(*this);
00150 }
00151  
00152 template<typename T, template<typename U> class Descriptor,
00153          int direction, int orientation>
00154 int InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>::getId() const {
00155     return id;
00156 }
00157 
00158 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00159 void InamuroAnalyticalVelocityDynamics<T,Descriptor,direction,orientation>::completePopulations (
00160         Cell<T,Descriptor>& cell ) const
00161 {
00162     InamuroAnalyticalClosure<T,Descriptor,direction,orientation>(cell, *this);
00163 }
00164 
00165 
00166 template<typename T, template<typename U> class Descriptor,
00167          int direction, int orientation>
00168 int InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>::id =
00169     meta::registerCompositeDynamics<T,Descriptor, InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation> >
00170             ( std::string("Boundary_InamuroAnalyticalPressure_")+util::val2str(direction) +
00171               std::string("_")+util::val2str(orientation) );
00172 
00173 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00174 InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>::InamuroAnalyticalPressureDynamics (
00175         Dynamics<T,Descriptor>* baseDynamics, bool automaticPrepareCollision )
00176     : DensityDirichletBoundaryDynamics<T,Descriptor,direction,orientation>(baseDynamics,automaticPrepareCollision)
00177 { }
00178 
00179 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00180 InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>*
00181     InamuroAnalyticalPressureDynamics<T,Descriptor, direction, orientation>::clone() const
00182 {
00183     return new InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>(*this);
00184 }
00185  
00186 template<typename T, template<typename U> class Descriptor,
00187          int direction, int orientation>
00188 int InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>::getId() const {
00189     return id;
00190 }
00191 
00192 template<typename T, template<typename U> class Descriptor, int direction, int orientation>
00193 void InamuroAnalyticalPressureDynamics<T,Descriptor,direction,orientation>::completePopulations (
00194         Cell<T,Descriptor>& cell ) const
00195 {
00196     InamuroAnalyticalClosure<T,Descriptor,direction,orientation>(cell, *this);
00197 }
00198 
00199 }  // namespace plb
00200 
00201 
00202 #endif  // INAMURO_ANALYTICAL_DYNAMICS_HH