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

dynamicsTemplates2D.h

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 
00029 #ifndef DYNAMICS_TEMPLATES_2D_H
00030 #define DYNAMICS_TEMPLATES_2D_H
00031 
00032 #include "core/globalDefs.h"
00033 #include "latticeBoltzmann/nearestNeighborLattices2D.h"
00034 #include "latticeBoltzmann/geometricOperationTemplates.h"
00035 
00036 namespace plb {
00037 
00039 template<typename T>
00040 struct neqPiD2Q9 {
00041       
00042     typedef SymmetricTensorImpl<T,2> S;
00043 
00044     static T fromPiToFneq0(Array<T,3> const& pi) {
00045         return (T)2 * (-(T)1/(T)3*pi[S::xx] - (T)1/(T)3*pi[S::yy]);
00046     }
00047 
00048     static T fromPiToFneq1(Array<T,3> const& pi) {
00049         return (T)1/(T)4 * ((T)1/(T)3*pi[S::xx] + (T)1/(T)3*pi[S::yy] - pi[S::xy]);
00050     }
00051 
00052     static T fromPiToFneq2(Array<T,3> const& pi) {
00053         return (T)1/(T)2 * ((T)2/(T)3*pi[S::xx] - (T)1/(T)3*pi[S::yy]);
00054     }
00055 
00056     static T fromPiToFneq3(Array<T,3> const& pi) {
00057         return (T)1/(T)4 * ((T)1/(T)3*pi[S::xx] + (T)1/(T)3*pi[S::yy] + pi[S::xy]);
00058     }
00059 
00060     static T fromPiToFneq4(Array<T,3> const& pi) {
00061         return (T)1/(T)2 * (-(T)1/(T)3*pi[S::xx] + (T)2/(T)3*pi[S::yy]);
00062     }
00063 };  //struct neqPiD2Q9
00064 
00065 // Efficient specialization for D2Q9 base lattice
00066 template<typename T> struct dynamicsTemplatesImpl<T, descriptors::D2Q9DescriptorBase<T> > {
00067 
00068 typedef descriptors::D2Q9DescriptorBase<T> Descriptor;
00069 
00070 static T bgk_ma2_equilibrium(plint iPop, T rhoBar, T invRho, Array<T,2> const& j, T jSqr ) {
00071     typedef descriptors::D2Q9DescriptorBase<T> L;
00072     T c_j = L::c[iPop][0]*j[0] + L::c[iPop][1]*j[1];
00073     return L::t[iPop] * ( rhoBar +
00074                3.*c_j + invRho*(4.5*c_j*c_j - 1.5*jSqr) );
00075 }
00076 
00077 static void bgk_ma2_equilibria( T rhoBar, T invRho, Array<T,Descriptor::d> const& j,
00078                                 T jSqr, Array<T,Descriptor::q>& eqPop )
00079 {
00080     T t0 = Descriptor::t[0];
00081     T t1 = Descriptor::t[1];
00082     T t2 = Descriptor::t[2];
00083 
00084     T kx     = (T)3 * j[0];
00085     T ky     = (T)3 * j[1];
00086     T kxSqr_ = invRho / (T)2 * kx*kx;
00087     T kySqr_ = invRho / (T)2 * ky*ky;
00088     T kxky_  = invRho * kx*ky;
00089 
00090     T C1 = rhoBar + invRho*(T)3*jSqr;
00091     T C2, C3;
00092 
00093     // i=0
00094     C3 = -kxSqr_ - kySqr_;
00095     eqPop[0] = t0 * (C1+C3);
00096 
00097     // i=1 and i=5
00098     C2 = -kx + ky;
00099     C3 = -kxky_;
00100     eqPop[1] = t1 * (C1+C2+C3);
00101     eqPop[5] = t1 * (C1-C2+C3);
00102 
00103     // i=2 and i=6
00104     C2 = -kx;
00105     C3 = -kySqr_;
00106     eqPop[2] = t2 * (C1+C2+C3);
00107     eqPop[6] = t2 * (C1-C2+C3);
00108 
00109     // i=3 and i=7
00110     C2 = -kx - ky;
00111     C3 = kxky_;
00112     eqPop[3] = t1 * (C1+C2+C3);
00113     eqPop[7] = t1 * (C1-C2+C3);
00114 
00115     // i=4 and i=8
00116     C2 = -ky;
00117     C3 = -kxSqr_;
00118     eqPop[4] = t2 * (C1+C2+C3);
00119     eqPop[8] = t2 * (C1-C2+C3);
00120 }
00121 
00122 static T bgk_ma2_collision_base(Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j, T omega, bool incompressible) {
00123     T invRho = incompressible ? (T)1 : Descriptor::invRho(rhoBar);
00124     T one_m_omega = (T)1 - omega;
00125     T t0_omega = Descriptor::t[0] * omega;
00126     T t1_omega = Descriptor::t[1] * omega;
00127     T t2_omega = Descriptor::t[2] * omega;
00128 
00129     T jSqr   = j[0]*j[0] + j[1]*j[1];
00130     T kx     = (T)3 * j[0];
00131     T ky     = (T)3 * j[1];
00132     T kxSqr_ = invRho / (T)2 * kx*kx;
00133     T kySqr_ = invRho / (T)2 * ky*ky;
00134     T kxky_  = invRho * kx*ky;
00135 
00136     T C1 = rhoBar + invRho*(T)3*jSqr;
00137     T C2, C3;
00138 
00139     // i=0
00140     C3 = -kxSqr_ - kySqr_;
00141     f[0] *= one_m_omega; f[0] += t0_omega * (C1+C3);
00142 
00143     // i=1 and i=5
00144     C2 = -kx + ky;
00145     C3 = -kxky_;
00146     f[1] *= one_m_omega; f[1] += t1_omega * (C1+C2+C3);
00147     f[5] *= one_m_omega; f[5] += t1_omega * (C1-C2+C3);
00148 
00149     // i=2 and i=6
00150     C2 = -kx;
00151     C3 = -kySqr_;
00152     f[2] *= one_m_omega; f[2] += t2_omega * (C1+C2+C3);
00153     f[6] *= one_m_omega; f[6] += t2_omega * (C1-C2+C3);
00154 
00155     // i=3 and i=7
00156     C2 = -kx - ky;
00157     C3 = kxky_;
00158     f[3] *= one_m_omega; f[3] += t1_omega * (C1+C2+C3);
00159     f[7] *= one_m_omega; f[7] += t1_omega * (C1-C2+C3);
00160 
00161     // i=4 and i=8
00162     C2 = -ky;
00163     C3 = -kxSqr_;
00164     f[4] *= one_m_omega; f[4] += t2_omega * (C1+C2+C3);
00165     f[8] *= one_m_omega; f[8] += t2_omega * (C1-C2+C3);
00166 
00167     return invRho*invRho*jSqr;
00168 }
00169 
00170 static T bgk_ma2_collision(Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j, T omega) {
00171     return bgk_ma2_collision_base(f, rhoBar, j, omega, false);
00172 }
00173 
00174 static T bgk_inc_collision(Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j, T omega) {
00175     return bgk_ma2_collision_base(f, rhoBar, j, omega, true);
00176 }
00177 
00178 static T rlb_collision(Array<T,Descriptor::q>& f, T rhoBar, T invRho, Array<T,2> const& j, Array<T,3> const& PiNeq, T omega ) {
00179     typedef dynamicsTemplatesImpl<T, descriptors::D2Q9DescriptorBase<T> > DH;
00180     const T jSqr = j[0]*j[0] + j[1]*j[1];
00181 
00182     T piNeq0 = neqPiD2Q9<T>::fromPiToFneq0(PiNeq);
00183     T piNeq1 = neqPiD2Q9<T>::fromPiToFneq1(PiNeq);
00184     T piNeq2 = neqPiD2Q9<T>::fromPiToFneq2(PiNeq);
00185     T piNeq3 = neqPiD2Q9<T>::fromPiToFneq3(PiNeq);
00186     T piNeq4 = neqPiD2Q9<T>::fromPiToFneq4(PiNeq);
00187 
00188     f[0] = DH::bgk_ma2_equilibrium(0, rhoBar, invRho, j, jSqr)
00189                   + ((T)1-omega) * piNeq0;
00190     f[1] = DH::bgk_ma2_equilibrium(1, rhoBar, invRho, j, jSqr)
00191                   + ((T)1-omega) * piNeq1;
00192     f[2] = DH::bgk_ma2_equilibrium(2, rhoBar, invRho, j, jSqr)
00193                   + ((T)1-omega) * piNeq2;
00194     f[3] = DH::bgk_ma2_equilibrium(3, rhoBar, invRho, j, jSqr)
00195                   + ((T)1-omega) * piNeq3;
00196     f[4] = DH::bgk_ma2_equilibrium(4, rhoBar, invRho, j, jSqr)
00197                   + ((T)1-omega) * piNeq4;
00198     f[5] = DH::bgk_ma2_equilibrium(5, rhoBar, invRho, j, jSqr)
00199                   + ((T)1-omega) * piNeq1;
00200     f[6] = DH::bgk_ma2_equilibrium(6, rhoBar, invRho, j, jSqr)
00201                   + ((T)1-omega) * piNeq2;
00202     f[7] = DH::bgk_ma2_equilibrium(7, rhoBar, invRho, j, jSqr)
00203                   + ((T)1-omega) * piNeq3;
00204     f[8] = DH::bgk_ma2_equilibrium(8, rhoBar, invRho, j, jSqr)
00205                   + ((T)1-omega) * piNeq4;
00206     return jSqr*invRho*invRho;
00207 }
00208 
00209 static T bgk_ma2_constRho_collision(Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j, T ratioRho, T omega) {
00210     typedef descriptors::D2Q9DescriptorBase<T> L;
00211     T invRho = L::invRho(rhoBar);
00212     const T jSqr = j[0]*j[0] + j[1]*j[1];
00213     for (plint iPop=0; iPop < L::q; ++iPop) {
00214         T feq = bgk_ma2_equilibrium(iPop, rhoBar, invRho, j, jSqr );
00215         f[iPop] =
00216           ratioRho*feq + L::t[iPop]*(ratioRho-(T)1) +
00217           ((T)1-omega)*(f[iPop]-feq);
00218     }
00219     return jSqr*invRho*invRho;
00220 }
00221 
00222 static T precond_bgk_ma2_equilibrium(plint iPop, T rhoBar, T invRho, Array<T,2> const& j, T jSqr, T invGamma ) {
00223     typedef descriptors::D2Q9DescriptorBase<T> L;
00224     T c_j = L::c[iPop][0]*j[0] + L::c[iPop][1]*j[1];
00225     return L::t[iPop] * ( rhoBar +
00226                3.*c_j + invGamma*invRho*(4.5*c_j*c_j - 1.5*jSqr) );
00227 }
00228 
00229 static T precond_bgk_ma2_collision_base( Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j, T omega,
00230                                          T invGamma, bool incompressible )
00231 {
00232     T invRho = incompressible ? (T)1 : Descriptor::invRho(rhoBar);
00233     T one_m_omega = (T)1 - omega;
00234     T t0_omega = Descriptor::t[0] * omega;
00235     T t1_omega = Descriptor::t[1] * omega;
00236     T t2_omega = Descriptor::t[2] * omega;
00237 
00238     T jSqr   = j[0]*j[0] + j[1]*j[1];
00239     T kx     = (T)3 * j[0];
00240     T ky     = (T)3 * j[1];
00241     T kxSqr_ = invGamma* invRho / (T)2 * kx*kx;
00242     T kySqr_ = invGamma* invRho / (T)2 * ky*ky;
00243     T kxky_  = invGamma* invRho * kx*ky;
00244 
00245     T C1 = rhoBar + invGamma*invRho*(T)3*jSqr;
00246     T C2, C3;
00247 
00248     // i=0
00249     C3 = -kxSqr_ - kySqr_;
00250     f[0] *= one_m_omega; f[0] += t0_omega * (C1+C3);
00251 
00252     // i=1 and i=5
00253     C2 = -kx + ky;
00254     C3 = -kxky_;
00255     f[1] *= one_m_omega; f[1] += t1_omega * (C1+C2+C3);
00256     f[5] *= one_m_omega; f[5] += t1_omega * (C1-C2+C3);
00257 
00258     // i=2 and i=6
00259     C2 = -kx;
00260     C3 = -kySqr_;
00261     f[2] *= one_m_omega; f[2] += t2_omega * (C1+C2+C3);
00262     f[6] *= one_m_omega; f[6] += t2_omega * (C1-C2+C3);
00263 
00264     // i=3 and i=7
00265     C2 = -kx - ky;
00266     C3 = kxky_;
00267     f[3] *= one_m_omega; f[3] += t1_omega * (C1+C2+C3);
00268     f[7] *= one_m_omega; f[7] += t1_omega * (C1-C2+C3);
00269 
00270     // i=4 and i=8
00271     C2 = -ky;
00272     C3 = -kxSqr_;
00273     f[4] *= one_m_omega; f[4] += t2_omega * (C1+C2+C3);
00274     f[8] *= one_m_omega; f[8] += t2_omega * (C1-C2+C3);
00275 
00276     return invRho*invRho*jSqr;
00277 }
00278 
00279 static T precond_bgk_ma2_collision( Array<T,Descriptor::q>& f, T rhoBar, Array<T,2> const& j,
00280                                     T omega, T invGamma )
00281 {
00282     return precond_bgk_ma2_collision_base(f, rhoBar, j, omega, invGamma, false);
00283 }
00284 
00285 };  //struct dynamicsTemplatesImpl<D2Q9DescriptorBase>
00286 
00287 }  // namespace plb
00288 
00289 #endif  // DYNAMICS_TEMPLATES_2D_H