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

multiPhaseTemplates2D.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 
00031 #ifndef MULTI_PHASE_TEMPLATES_2D_H
00032 #define MULTI_PHASE_TEMPLATES_2D_H
00033 
00034 #include "core/globalDefs.h"
00035 #include "core/cell.h"
00036 #include "multiPhysics/shanChenLattices2D.h"
00037 
00038 namespace plb {
00039 
00041 template<typename T, template<typename U> class Descriptor>
00042 struct multiPhaseTemplates2D {
00043 
00044 static void shanChenInteraction( BlockLattice2D<T,Descriptor>& lattice,
00045                                  Array<T,Descriptor<T>::d>& rhoContribution,
00046                                  plint iX, plint iY )
00047 {
00048     enum {
00049         densityOffset  = Descriptor<T>::ExternalField::densityBeginsAt
00050     };
00051                      
00052     rhoContribution.resetToZero();
00053     for (plint iPop = 0; iPop < Descriptor<T>::q; ++iPop) {
00054         plint nextX = iX + Descriptor<T>::c[iPop][0];
00055         plint nextY = iY + Descriptor<T>::c[iPop][1];
00056         Cell<T,Descriptor> const& cell = lattice.get(nextX,nextY);
00057         T rho = *cell.getExternal(densityOffset);
00058         for (int iD = 0; iD < Descriptor<T>::d; ++iD) {
00059            rhoContribution[iD] += Descriptor<T>::t[iPop] * rho * Descriptor<T>::c[iPop][iD];
00060         }
00061     }
00062 }
00063 
00064 };
00065 
00066 template<typename T, template<typename U> class Descriptor>
00067 struct multiPhaseHelpers2D {
00068 typedef Descriptor<T> D;
00069 
00070 static void computeRhoAndJ(BlockLattice2D<T,Descriptor>& lattice,
00071                            plint iX, plint iY)
00072 {
00073     enum {
00074         densityOffset  = D::ExternalField::densityBeginsAt,
00075         momentumOffset = D::ExternalField::momentumBeginsAt
00076     };
00077 
00078     Cell<T,Descriptor>& cell = lattice.get(iX,iY);
00079     Array<T,Descriptor<T>::d> j;
00080     T rhoBar;
00081     cell.getDynamics().computeRhoBarJ(cell,rhoBar,j);
00082     momentTemplates<T,Descriptor>::get_j(cell,j);
00083     *cell.getExternal(densityOffset) = Descriptor<T>::fullRho(rhoBar);
00084     j.to_cArray(cell.getExternal(momentumOffset));
00085 }
00086 
00087 static void computeUstar(std::vector<BlockLattice2D<T,Descriptor>*> lattices,
00088                          plint iX, plint iY,
00089                          Array<T,Descriptor<T>::d>& uStar)
00090 {
00091     enum {
00092         densityOffset  = D::ExternalField::densityBeginsAt,
00093         momentumOffset = D::ExternalField::momentumBeginsAt
00094     };
00095 
00096     plint numSpecies = (plint) lattices.size();
00097     std::vector<T> omega(numSpecies);
00098     T rhoStar = T();
00099     for (plint iSpecies=0; iSpecies<numSpecies; ++iSpecies) {
00100         Cell<T,Descriptor> const& cell = lattices[iSpecies]->get(iX,iY);
00101         omega[iSpecies] = cell.getDynamics().getOmega();
00102         rhoStar += omega[iSpecies] * (*cell.getExternal(densityOffset));
00103     }
00104     // Computation of the common velocity, shared among all populations.
00105     for (int iD = 0; iD < Descriptor<T>::d; ++iD) {
00106         uStar[iD] = T();
00107         for (plint iSpecies=0; iSpecies<numSpecies; ++iSpecies) {
00108             T *momentum = lattices[iSpecies]->get(iX,iY).getExternal(momentumOffset);
00109             uStar[iD] += momentum[iD] * omega[iSpecies];
00110         }
00111         uStar[iD] /= rhoStar;
00112     }
00113 }
00114 
00115 static void computeUphys(std::vector<BlockLattice2D<T,Descriptor>*> lattices,
00116                          plint iX, plint iY,
00117                          Array<T,Descriptor<T>::d>& uPhys)
00118 {
00119     enum {      
00120         densityOffset  = D::ExternalField::densityBeginsAt,
00121         momentumOffset = D::ExternalField::momentumBeginsAt,
00122         gOffset        = D::ExternalField::GbeginsAt,
00123         interfOffset   = D::ExternalField::interactionFbeginsAt
00124     };       
00125     plint numSpecies = (plint) lattices.size();
00126     T rhoPhys = T();
00127     for (plint iSpecies=0; iSpecies<numSpecies; ++iSpecies) {
00128         Cell<T,Descriptor> const& cell = lattices[iSpecies]->get(iX,iY);
00129         rhoPhys += *cell.getExternal(densityOffset);
00130     }
00131     // Computation of the common velocity, shared among all populations.
00132     for (int iD = 0; iD < Descriptor<T>::d; ++iD) {
00133         uPhys[iD] = T();
00134         for (plint iSpecies=0; iSpecies<numSpecies; ++iSpecies) {
00135             Cell<T,Descriptor> const& cell = lattices[iSpecies]->get(iX,iY);
00136             T const *momentum = cell.getExternal(momentumOffset);
00137             T const *interf = cell.getExternal(interfOffset);
00138             T rho = *cell.getExternal(densityOffset);
00139             uPhys[iD] += momentum[iD] + 0.5*rho*interf[iD];
00140         }
00141         uPhys[iD] /= rhoPhys;
00142         T *externalf = lattices[0]->get(iX,iY).getExternal(gOffset);
00143         uPhys[iD] += 0.5*externalf[iD];
00144     }
00145 }
00146 
00147 };
00148 
00149 template<typename T>
00150 struct multiPhaseTemplates2D<T, descriptors::ForcedShanChenD2Q9Descriptor> {
00151     typedef descriptors::ForcedShanChenD2Q9Descriptor<T> D;
00152 
00153 static void shanChenInteraction (
00154         BlockLattice2D<T,descriptors::ForcedShanChenD2Q9Descriptor>& lattice,
00155         Array<T,D::d>& rhoContribution,
00156         plint iX, plint iY )
00157 {
00158 
00159     enum {
00160         densityOffset  = D::ExternalField::densityBeginsAt
00161     };
00162 
00163     T rho;
00164     rho = *lattice.get(iX-1,iY+1).getExternal(densityOffset);
00165     rhoContribution[0] = -D::t[1] * rho;
00166     rhoContribution[1] =  D::t[1] * rho;
00167     rho = *lattice.get(iX-1,iY  ).getExternal(densityOffset);
00168     rhoContribution[0] -= D::t[2] * rho;
00169     rho = *lattice.get(iX-1,iY-1).getExternal(densityOffset);
00170     rhoContribution[0] -= D::t[3] * rho;
00171     rhoContribution[1] -= D::t[3] * rho;
00172     rho = *lattice.get(iX  ,iY-1).getExternal(densityOffset);
00173     rhoContribution[1] -= D::t[4] * rho;
00174     rho = *lattice.get(iX+1,iY-1).getExternal(densityOffset);
00175     rhoContribution[0] += D::t[5] * rho;
00176     rhoContribution[1] -= D::t[5] * rho;
00177     rho = *lattice.get(iX+1,iY  ).getExternal(densityOffset);
00178     rhoContribution[0] += D::t[6] * rho;
00179     rho = *lattice.get(iX+1,iY+1).getExternal(densityOffset);
00180     rhoContribution[0] += D::t[7] * rho;
00181     rhoContribution[1] += D::t[7] * rho;
00182     rho = *lattice.get(iX  ,iY+1).getExternal(densityOffset);
00183     rhoContribution[1] += D::t[8] * rho;
00184 }
00185 
00186 };
00187 
00188 }  // namespace plb
00189 
00190 #endif  // MULTI_PHASE_TEMPLATES_2D_H