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

externalForceTemplates.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 
00025 /* Main author: Orestis Malaspinas
00026  */
00027 
00034 #ifndef EXTERNAL_FORCE_TEMPLATES_H
00035 #define EXTERNAL_FORCE_TEMPLATES_H
00036 
00037 #include "core/globalDefs.h"
00038 #include "core/cell.h"
00039 #include "core/util.h"
00040 #include "latticeBoltzmann/geometricOperationTemplates.h"
00041 
00042 namespace plb {
00043 
00044 template<typename T, class Descriptor> struct externalForceTemplatesImpl;
00045 
00046 template<typename T, template<typename U> class Descriptor>
00047 struct externalForceTemplates {
00048 
00050 static void addNaiveForce( Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u,
00051                          T omega, T amplitude)
00052 {
00053     externalForceTemplatesImpl<T, Descriptor<T> >
00054         ::addNaiveForce(cell.getRawPopulations(), cell.getExternal(0), u, omega, amplitude);
00055 }
00056 
00058 static void addGuoForce( Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u,
00059                          T omega, T amplitude)
00060 {
00061     externalForceTemplatesImpl<T, Descriptor<T> >
00062         ::addGuoForce(cell.getRawPopulations(), cell.getExternal(0), u, omega, amplitude);
00063 }
00064 
00066 static void addGuoCompressibleForce( Cell<T,Descriptor>& cell, T rho, Array<T,Descriptor<T>::d> const& u,
00067                                      T uSqr, T thetaBar, T omega, T amplitude)
00068 {
00069     externalForceTemplatesImpl<T, Descriptor<T> >
00070         ::addGuoCompressibleForce(cell.getRawPopulations(), cell.getExternal(0), rho, u, uSqr, thetaBar, omega, amplitude);
00071 }
00072 
00074 static T shanChenForcedBGKCollision (
00075              Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j, T omega )
00076 {
00077     return externalForceTemplatesImpl<T, Descriptor<T> >
00078                ::shanChenForcedBGKCollision(cell.getRawPopulations(), cell.getExternal(0),
00079                                             rhoBar, j, omega);
00080 }
00081 
00083 static T heForcedBGKCollision (
00084              Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j, T omega )
00085 {
00086     return externalForceTemplatesImpl<T, Descriptor<T> >
00087                ::heForcedBGKCollision(cell.getRawPopulations(), cell.getExternal(0),
00088                                             rhoBar, j, omega);
00089 }
00090 
00091 };
00092 
00093 template<typename T, class Descriptor>
00094 struct externalForceTemplatesImpl {
00095 
00096 static void addNaiveForce( Array<T,Descriptor::q>& f, T* externalScalars,
00097                            Array<T,Descriptor::d> const& u,
00098                            T omega, T amplitude )
00099 {
00100     static const int forceBeginsAt = Descriptor::ExternalField::forceBeginsAt;
00101     T* force = externalScalars + forceBeginsAt;
00102     for (plint iPop=0; iPop < Descriptor::q; ++iPop) 
00103     {
00104         T c_f = T();
00105         for (int iD=0; iD<Descriptor::d; ++iD) {
00106             c_f += Descriptor::c[iPop][iD]*force[iD];
00107         }
00108         f[iPop] += c_f * Descriptor::t[iPop] * Descriptor::invCs2;
00109     }
00110 }
00111 
00112 static void addGuoForce( Array<T,Descriptor::q>& f, T* externalScalars,
00113                          Array<T,Descriptor::d> const& u,
00114                          T omega, T amplitude )
00115 {
00116     static const int forceBeginsAt = Descriptor::ExternalField::forceBeginsAt;
00117     T* force = externalScalars + forceBeginsAt;
00118     for (plint iPop=0; iPop < Descriptor::q; ++iPop) 
00119     {
00120         T c_u = T();
00121         for (int iD=0; iD<Descriptor::d; ++iD) {
00122             c_u += Descriptor::c[iPop][iD]*u[iD];
00123         }
00124         c_u *= Descriptor::invCs2 * Descriptor::invCs2;
00125         T forceTerm = T();
00126         for (int iD=0; iD < Descriptor::d; ++iD) {
00127             forceTerm +=
00128                 (   ((T)Descriptor::c[iPop][iD]-u[iD]) * Descriptor::invCs2
00129                      + c_u * (T)Descriptor::c[iPop][iD]
00130                 )
00131                 * force[iD];
00132         }
00133         forceTerm *= Descriptor::t[iPop];
00134         forceTerm *= 1-omega/(T)2;
00135         forceTerm *= amplitude;
00136         f[iPop] += forceTerm;
00137     }
00138 }
00139 
00140 static void addGuoCompressibleForce( Array<T,Descriptor::q>& f, T* externalScalars,
00141                                      T rho, Array<T,Descriptor::d> const& u, T uSqr, T thetaBar,
00142                                      T omega, T amplitude )
00143 {
00144     static const int forceBeginsAt = Descriptor::ExternalField::forceBeginsAt;
00145     T* force = externalScalars + forceBeginsAt;
00146     for (plint iPop=0; iPop < Descriptor::q; ++iPop) 
00147     {
00148         T c_u = T();
00149         T f_u = T();
00150         T c_f = T();
00151         for (int iD=0; iD<Descriptor::d; ++iD) {
00152             c_u += Descriptor::c[iPop][iD]*u[iD];
00153             f_u += force[iD] * u[iD];
00154             f_u += Descriptor::c[iPop][iD]*force[iD];
00155         }
00156         
00157         T forceTerm = c_f*Descriptor::invCs2; // Hermite order 1
00158         forceTerm += Descriptor::invCs2*Descriptor::invCs2/(T)2 * (c_u*c_f-Descriptor::cs2*f_u);// Hermite order 2
00159         forceTerm +=  Descriptor::invCs2*Descriptor::invCs2*Descriptor::invCs2/(T)6 *
00160             (c_f*(c_u*c_u+Descriptor::cs2*(Descriptor::cNormSqr[iPop]*thetaBar))
00161             - Descriptor::cs2*(c_u*((T)2*f_u + uSqr+Descriptor::cs2*Descriptor::d*thetaBar) + (T)2*Descriptor::cs2*thetaBar*c_f));// Hermite order 3
00162             
00163         forceTerm *= Descriptor::t[iPop];
00164         forceTerm *= 1-omega/(T)2;
00165         forceTerm *= rho;
00166         forceTerm *= amplitude;
00167         
00168         f[iPop] += forceTerm;
00169     }
00170 }
00171 
00172 static T heForcedBGKCollision (
00173         Array<T,Descriptor::q>& f, T* externalScalars,
00174         T rhoBar, Array<T,Descriptor::d> const& j, T omega )
00175 {
00176     static const int forceBeginsAt = Descriptor::ExternalField::forceBeginsAt;
00177     T* force = externalScalars + forceBeginsAt;
00178     T invRho = Descriptor::invRho(rhoBar);
00179     const T jSqr = VectorTemplateImpl<T,Descriptor::d>::normSqr(j);
00180         
00181         Array<T,Descriptor::d> uLB;
00182         for (plint iD=0; iD<Descriptor::d; ++iD) {
00183                 uLB[iD] = invRho*j[iD];
00184         }
00185         const T uSqrLB = VectorTemplateImpl<T,Descriptor::d>::normSqr(uLB);
00186         
00187     for (plint iPop=0; iPop < Descriptor::q; ++iPop) {
00188         T ug = 0.;
00189         for (int iD=0; iD<Descriptor::d; ++iD) {
00190             ug += (Descriptor::c[iPop][iD]-uLB[iD])*force[iD];
00191         }
00192         f[iPop] *= (T)1-omega;
00193                 f[iPop] += omega * dynamicsTemplatesImpl<T,Descriptor>::bgk_ma2_equilibrium (
00194                                 iPop, rhoBar, invRho, j, jSqr );
00195                                         
00196                 f[iPop] += Descriptor::invCs2*ug *
00197                        dynamicsTemplatesImpl<T,Descriptor>::bgk_ma2_equilibrium (
00198                                                                 iPop, (T)1, (T)1, uLB, uSqrLB );
00199     }
00200         
00201         T uSqr = T();
00202         for (int iD=0; iD<Descriptor::d; ++iD) {
00203                 uSqr += util::sqr(uLB[iD] + 0.5*force[iD]);
00204         }
00205     
00206     return uSqr;
00207 }
00208 
00209 };  // struct externalForceTemplates
00210 
00211 }  // namespace plb
00212 
00213 #include "latticeBoltzmann/externalForceTemplates2D.h"
00214 #include "latticeBoltzmann/externalForceTemplates3D.h"
00215 
00216 #endif