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

momentTemplates3D.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 MOMENT_TEMPLATES_3D_H
00030 #define MOMENT_TEMPLATES_3D_H
00031 
00032 #include "core/globalDefs.h"
00033 #include "latticeBoltzmann/nearestNeighborLattices3D.h"
00034 
00035 namespace plb {
00036 
00037 // Efficient specialization for D3Q27 lattice
00038 template<typename T>
00039 struct momentTemplatesImpl<T, descriptors::D3Q27DescriptorBase<T> > {
00040 
00041 typedef descriptors::D3Q27DescriptorBase<T> Descriptor;
00042 
00043 static void partial_rho ( Array<T,Descriptor::q> const& f,
00044                           T& surfX_M1, T& surfX_P1,
00045                           T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00046 {
00047     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7] +
00048                f[10] + f[11] + f[12] + f[13];
00049     surfX_P1 = f[14] + f[17] + f[18] + f[19] + f[20] +
00050                f[23] + f[24] + f[25] + f[26];
00051 
00052     surfY_M1 = f[2] + f[4] + f[8] + f[9] + f[10] +
00053                f[11] + f[18] + f[25] + f[26];
00054     surfY_P1 = f[5] + f[12] + f[13] + f[15] + f[17] +
00055                f[21] + f[22] + f[23] + f[24];
00056 
00057     surfZ_M1 = f[3] + f[6] + f[8] + f[10] + f[12] +
00058                f[20] + f[22] + f[24] + f[26];
00059     surfZ_P1 = f[7] + f[9] + f[11] + f[13] + f[16] +
00060                f[19] + f[21] + f[23] + f[25];
00061 }
00062 
00063 static void partial_rho ( Array<T,Descriptor::q> const& f,
00064                           T& surfX_M1, T& surfX_0, T& surfX_P1,
00065                           T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00066 {
00067     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00068     surfX_0  = f[0] + f[2] + f[3] + f[8] +
00069                f[9] + f[15] + f[16] + f[21] + f[22];
00070 }
00071 
00072 static T get_rhoBar(Array<T,Descriptor::q> const& f) {
00073     T rhoBar = f[0] + f[1] + f[2] + f[3] + f[4]
00074                        + f[5] + f[6] + f[7] + f[8]
00075                        + f[9] + f[10] + f[11] + f[12]
00076                        + f[13] + f[14] + f[15] + f[16]
00077                        + f[17] + f[18] + f[19] + f[20]
00078                        + f[21] + f[22] + f[23] + f[24]
00079                        + f[25] + f[26];
00080     return rhoBar;
00081 }
00082 
00083 static void get_j(Array<T,Descriptor::q> const& f, Array<T,3>& j) {
00084     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00085 
00086     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7] +
00087                f[10] + f[11] + f[12] + f[13];
00088     surfX_P1 = f[14] + f[17] + f[18] + f[19] + f[20] +
00089                f[23] + f[24] + f[25] + f[26];
00090 
00091     surfY_M1 = f[2] + f[4] + f[8] + f[9] + f[10] +
00092                f[11] + f[18] + f[25] + f[26];
00093     surfY_P1 = f[5] + f[12] + f[13] + f[15] + f[17] +
00094                f[21] + f[22] + f[23] + f[24];
00095 
00096     surfZ_M1 = f[3] + f[6] + f[8] + f[10] + f[12] +
00097                f[20] + f[22] + f[24] + f[26];
00098     surfZ_P1 = f[7] + f[9] + f[11] + f[13] + f[16] +
00099                f[19] + f[21] + f[23] + f[25];
00100 
00101     j[0]  = ( surfX_P1 - surfX_M1 );
00102     j[1]  = ( surfY_P1 - surfY_M1 );
00103     j[2]  = ( surfZ_P1 - surfZ_M1 );
00104 }
00105 
00106 static T get_eBar(Array<T,Descriptor::q> const& f) {
00107     T eBar = (T)3 * ( f[10] + f[11] + f[12] + f[13] +
00108                       f[23] + f[24] + f[25] + f[26] )
00109              +
00110              (T)2 * (f[4] + f[5] + f[6] +
00111                      f[7] + f[8] + f[9] +
00112                      f[17] + f[18] + f[19] +
00113                      f[20] + f[21] + f[22] )
00114              +
00115                  f[1] + f[2] + f[3] +
00116                  f[14] + f[15] + f[16];
00117     return eBar;
00118 }
00119 
00120 static void get_rhoBar_j(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j) {
00121     T surfX_M1, surfX_0, surfX_P1,
00122       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00123 
00124     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00125                       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00126 
00127     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00128 
00129     j[0]  = ( surfX_P1 - surfX_M1 );
00130     j[1]  = ( surfY_P1 - surfY_M1 );
00131     j[2]  = ( surfZ_P1 - surfZ_M1 );
00132 }
00133 
00134 static T compute_rho(Array<T,Descriptor::q> const& f) {
00135     return Descriptor::fullRho(get_rhoBar(f));
00136 }
00137 
00138 static void compute_uLb(Array<T,Descriptor::q> const& f, Array<T,3>& uLb ) {
00139     get_j(f, uLb);
00140     T invRho = Descriptor::invRho(get_rhoBar(f));
00141     uLb[0] *= invRho;
00142     uLb[1] *= invRho;
00143     uLb[2] *= invRho;
00144 }
00145 
00146 static void compute_rho_uLb(Array<T,Descriptor::q> const& f, T& rho, Array<T,3>& uLb ) {
00147     T rhoBar;
00148     get_rhoBar_j(f, rhoBar, uLb);
00149     T invRho = Descriptor::invRho(rhoBar);
00150     rho = Descriptor::fullRho(rhoBar);
00151     uLb[0] *= invRho;
00152     uLb[1] *= invRho;
00153     uLb[2] *= invRho;
00154 }
00155 
00156 static T compute_e(Array<T,Descriptor::q> const& f) {
00157     return get_eBar(f) + Descriptor::SkordosFactor * Descriptor::d * Descriptor::cs2;
00158 }
00159 
00160 static T compute_rhoThetaBar(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00161     T invRho = Descriptor::invRho(rhoBar);
00162     return Descriptor::invCs2 * Descriptor::invD * (get_eBar(f) - invRho*jSqr) - rhoBar;
00163 }
00164 
00165 static void compute_rho_rhoThetaBar(Array<T,Descriptor::q> const& f, T& rho, T& rhoThetaBar) {
00166     T rhoBar, j[3];
00167     get_rhoBar_j(f, rhoBar, j);
00168     T jSqr = VectorTemplateImpl<T,Descriptor::d>::normSqr(j);
00169     rho = Descriptor::fullRho(rhoBar);
00170     rhoThetaBar = compute_rhoThetaBar(f, rhoBar, jSqr);
00171 }
00172 
00173 static T compute_theta(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00174     T invRho = Descriptor::invRho(rhoBar);
00175     T e = compute_e(f);
00176     return invRho * Descriptor::invD * Descriptor::invCs2 * (e - invRho*jSqr);
00177 }
00178 
00179 static T compute_rhoEpsilon(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00180     T invRho = Descriptor::invRho(rhoBar);
00181     T e = compute_e(f);
00182     return (e - invRho*jSqr) / (T)2;
00183 }
00184 
00185 static void compute_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& PiNeq, bool incompr)
00186 {
00187     typedef SymmetricTensorImpl<T,3> S;
00188 
00189     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00190     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00191     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00192 
00193     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00194     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00195     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00196 
00197     PiNeq[S::xy] = f[4] - f[5] + f[10] + f[11] - f[12] - f[13]
00198                    + f[17] - f[18] + f[23] + f[24] - f[25] - f[26]
00199                    - invRho*j[0]*j[1];
00200     PiNeq[S::xz] = f[6] - f[7] + f[10] - f[11] + f[12] - f[13]
00201                    + f[19] - f[20] + f[23] - f[24] + f[25] - f[26]
00202                    - invRho*j[0]*j[2];
00203     PiNeq[S::yz] = f[8] - f[9] + f[10] - f[11] - f[12] + f[13]
00204                    + f[21] - f[22] + f[23] - f[24] - f[25] + f[26]
00205                    -invRho*j[1]*j[2];
00206 }
00207 
00208 static void compute_thermal_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, T thetaBar,
00209                                   Array<T,3> const& j, Array<T,6>& PiNeq)
00210 {
00211     typedef SymmetricTensorImpl<T,3> S;
00212 
00213     T rhoTheta_bar = rhoBar*thetaBar + rhoBar + Descriptor::SkordosFactor*thetaBar;
00214     T invRho = Descriptor::invRho(rhoBar);
00215     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00216     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00217 
00218     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[0]*j[0];
00219     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[1]*j[1];
00220     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[2]*j[2];
00221 
00222     PiNeq[S::xy] = f[4] - f[5] + f[10] + f[11] - f[12] - f[13]
00223                    + f[17] - f[18] + f[23] + f[24] - f[25] - f[26]
00224                    - invRho*j[0]*j[1];
00225     PiNeq[S::xz] = f[6] - f[7] + f[10] - f[11] + f[12] - f[13]
00226                    + f[19] - f[20] + f[23] - f[24] + f[25] - f[26]
00227                    - invRho*j[0]*j[2];
00228     PiNeq[S::yz] = f[8] - f[9] + f[10] - f[11] - f[12] + f[13]
00229                    + f[21] - f[22] + f[23] - f[24] - f[25] + f[26]
00230                    -invRho*j[1]*j[2];
00231 
00232 }
00233 
00234 static void compute_rhoBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j, Array<T,6>& PiNeq, bool incompr )
00235 {
00236     typedef SymmetricTensorImpl<T,3> S;
00237 
00238     T surfX_M1, surfX_0, surfX_P1,
00239       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00240 
00241     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00242                    surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00243     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00244     j[0]  = ( surfX_P1 - surfX_M1 );
00245     j[1]  = ( surfY_P1 - surfY_M1 );
00246     j[2]  = ( surfZ_P1 - surfZ_M1 );
00247     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00248 
00249     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00250     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00251     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00252 
00253     PiNeq[S::xy] = f[4] - f[5] + f[10] + f[11] - f[12] - f[13]
00254                    + f[17] - f[18] + f[23] + f[24] - f[25] - f[26]
00255                    - invRho*j[0]*j[1];
00256     PiNeq[S::xz] = f[6] - f[7] + f[10] - f[11] + f[12] - f[13]
00257                    + f[19] - f[20] + f[23] - f[24] + f[25] - f[26]
00258                    - invRho*j[0]*j[2];
00259     PiNeq[S::yz] = f[8] - f[9] + f[10] - f[11] - f[12] + f[13]
00260                    + f[21] - f[22] + f[23] - f[24] - f[25] + f[26]
00261                    -invRho*j[1]*j[2];
00262 }
00263 
00264 static void compute_rhoBar_thetaBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, T& thetaBar,
00265                                             Array<T,3> const& j, Array<T,6>& PiNeq )
00266 {
00267     get_rhoBar_j(f, rhoBar, j);
00268     bool incompr=false;
00269     compute_PiNeq(f, rhoBar, j, PiNeq, incompr);
00270     T rhoThetaBar = compute_rhoThetaBar(f);
00271     thetaBar = rhoThetaBar * Descriptor::invRho(rhoBar);
00272     compute_thermal_PiNeq(f, rhoBar, thetaBar, j, PiNeq);
00273 }
00274 
00275 static void compute_P(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& P) {
00276     typedef SymmetricTensorImpl<T,3> S;
00277 
00278     T invRho = Descriptor::invRho(rhoBar);
00279     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00280     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00281 
00282     P[S::xx] = surfX_P1+surfX_M1 - invRho*j[0]*j[0];
00283     P[S::yy] = surfY_P1+surfY_M1 - invRho*j[1]*j[1];
00284     P[S::zz] = surfZ_P1+surfZ_M1 - invRho*j[2]*j[2];
00285 
00286     P[S::xy] = f[4] - f[5] + f[10] + f[11] - f[12] - f[13]
00287                + f[17] - f[18] + f[23] + f[24] - f[25] - f[26]
00288                - invRho*j[0]*j[1];
00289     P[S::xz] = f[6] - f[7] + f[10] - f[11] + f[12] - f[13]
00290                + f[19] - f[20] + f[23] - f[24] + f[25] - f[26]
00291                - invRho*j[0]*j[2];
00292     P[S::yz] = f[8] - f[9] + f[10] - f[11] - f[12] + f[13]
00293                + f[21] - f[22] + f[23] - f[24] - f[25] + f[26]
00294                -invRho*j[1]*j[2];
00295 }
00296 
00297 static void modifyJ(Array<T,Descriptor::q>& f, Array<T,3> const& newJ) {
00298     T rhoBar, oldJ[3];
00299     get_rhoBar_j(f, rhoBar, oldJ);
00300     const T oldJSqr = VectorTemplateImpl<T,3>::normSqr(oldJ);
00301     const T newJSqr = VectorTemplateImpl<T,3>::normSqr(newJ);
00302     for (plint iPop=0; iPop<Descriptor::q; ++iPop) {
00303         f[iPop] = f[iPop]
00304                          - equilibrium(iPop, rhoBar, oldJ, oldJSqr)
00305                          + equilibrium(iPop, rhoBar, newJ, newJSqr);
00306     }
00307 }
00308 
00309 };  //struct momentTemplatesImpl<D3Q27DescriptorBase>
00310 
00311 // Efficient specialization for D3Q19 lattice
00312 template<typename T>
00313 struct momentTemplatesImpl<T, descriptors::D3Q19DescriptorBase<T> > {
00314 
00315 typedef descriptors::D3Q19DescriptorBase<T> Descriptor;
00316 
00317 static void partial_rho ( Array<T,Descriptor::q> const& f,
00318                           T& surfX_M1, T& surfX_P1,
00319                           T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00320 {
00321     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7];
00322     surfX_P1 = f[10] + f[13] + f[14] + f[15] + f[16];
00323 
00324     surfY_M1 = f[2] + f[4] + f[8] + f[9] + f[14];
00325     surfY_P1 = f[5] + f[11] + f[13] + f[17] + f[18];
00326 
00327     surfZ_M1 = f[3] + f[6] + f[8] + f[16] + f[18];
00328     surfZ_P1 = f[7] + f[9] + f[12] + f[15] + f[17];
00329 
00330 }
00331 
00332 static void partial_rho ( Array<T,Descriptor::q> const& f,
00333                           T& surfX_M1, T& surfX_0, T& surfX_P1,
00334                           T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00335 {
00336     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00337     surfX_0  = f[0] + f[2] + f[3] + f[8] +
00338                f[9] + f[11] + f[12] + f[17] + f[18];
00339 }
00340 
00341 static T get_rhoBar(Array<T,Descriptor::q> const& f) {
00342     T rhoBar = f[0] + f[1] + f[2] + f[3] + f[4]
00343                        + f[5] + f[6] + f[7] + f[8]
00344                        + f[9] + f[10] + f[11] + f[12]
00345                        + f[13] + f[14] + f[15] + f[16]
00346                        + f[17] + f[18];
00347     return rhoBar;
00348 }
00349 
00350 static void get_j(Array<T,Descriptor::q> const& f, Array<T,3>& j) {
00351     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00352 
00353     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7];
00354     surfX_P1 = f[10] + f[13] + f[14] + f[15] + f[16];
00355 
00356     surfY_M1 = f[2] + f[4] + f[8] + f[9] + f[14];
00357     surfY_P1 = f[5] + f[11] + f[13] + f[17] + f[18];
00358 
00359     surfZ_M1 = f[3] + f[6] + f[8] + f[16] + f[18];
00360     surfZ_P1 = f[7] + f[9] + f[12] + f[15] + f[17];
00361 
00362     j[0]  = ( surfX_P1 - surfX_M1 );
00363     j[1]  = ( surfY_P1 - surfY_M1 );
00364     j[2]  = ( surfZ_P1 - surfZ_M1 );
00365 }
00366 
00367 static T get_eBar(Array<T,Descriptor::q> const& f) {
00368     T eBar = (T)2 * (f[4] + f[5] + f[6] +
00369                      f[7] + f[8] + f[9] +
00370                      f[13] + f[14] + f[15] +
00371                      f[16] + f[17] + f[18] )
00372                    + f[1] + f[2] + f[3] +
00373                      f[10] + f[11] + f[12];
00374     return eBar;
00375 }
00376 
00377 static void get_rhoBar_j(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j) {
00378     T surfX_M1, surfX_0, surfX_P1,
00379       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00380 
00381     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00382                       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00383 
00384     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00385 
00386     j[0]  = ( surfX_P1 - surfX_M1 );
00387     j[1]  = ( surfY_P1 - surfY_M1 );
00388     j[2]  = ( surfZ_P1 - surfZ_M1 );
00389 }
00390 
00391 static T compute_rho(Array<T,Descriptor::q> const& f) {
00392     return Descriptor::fullRho(get_rhoBar(f));
00393 }
00394 
00395 static void compute_uLb(Array<T,Descriptor::q> const& f, Array<T,3>& uLb ) {
00396     get_j(f, uLb);
00397     T invRho = Descriptor::invRho(get_rhoBar(f));
00398     uLb[0] *= invRho;
00399     uLb[1] *= invRho;
00400     uLb[2] *= invRho;
00401 }
00402 
00403 static void compute_rho_uLb(Array<T,Descriptor::q> const& f, T& rho, Array<T,3>& uLb ) {
00404     T rhoBar;
00405     get_rhoBar_j(f, rhoBar, uLb);
00406     T invRho = Descriptor::invRho(rhoBar);
00407     rho = Descriptor::fullRho(rhoBar);
00408     uLb[0] *= invRho;
00409     uLb[1] *= invRho;
00410     uLb[2] *= invRho;
00411 }
00412 
00413 static T compute_e(Array<T,Descriptor::q> const& f) {
00414     return get_eBar(f) + Descriptor::SkordosFactor * Descriptor::d * Descriptor::cs2;
00415 }
00416 
00417 static T compute_rhoThetaBar(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00418     T invRho = Descriptor::invRho(rhoBar);
00419     return Descriptor::invCs2 * Descriptor::invD * (get_eBar(f) - invRho*jSqr) - rhoBar;
00420 }
00421 
00422 static void compute_rho_rhoThetaBar(Array<T,Descriptor::q> const& f, T& rho, T& rhoThetaBar) {
00423     T rhoBar, j[3];
00424     get_rhoBar_j(f, rhoBar, j);
00425     T jSqr = VectorTemplateImpl<T,Descriptor::d>::normSqr(j);
00426     rho = Descriptor::fullRho(rhoBar);
00427     rhoThetaBar = compute_rhoThetaBar(f, rhoBar, jSqr);
00428 }
00429 
00430 static T compute_theta(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00431     T invRho = Descriptor::invRho(rhoBar);
00432     T e = compute_e(f);
00433     return invRho * Descriptor::invD * Descriptor::invCs2 * (e - invRho*jSqr);
00434 }
00435 
00436 static T compute_rhoEpsilon(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00437     T invRho = Descriptor::invRho(rhoBar);
00438     T e = compute_e(f);
00439     return (e - invRho*jSqr) / (T)2;
00440 }
00441 
00442 static void compute_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& PiNeq, bool incompr)
00443 {
00444     typedef SymmetricTensorImpl<T,3> S;
00445 
00446     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00447     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00448     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00449 
00450     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00451     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00452     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00453 
00454     PiNeq[S::xy] = f[4] - f[5] + f[13] - f[14] - invRho*j[0]*j[1];
00455     PiNeq[S::xz] = f[6] - f[7] + f[15] - f[16] - invRho*j[0]*j[2];
00456     PiNeq[S::yz] = f[8] - f[9] + f[17] - f[18] - invRho*j[1]*j[2];
00457 }
00458 
00459 static void compute_thermal_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, T thetaBar,
00460                                   Array<T,3> const& j, Array<T,6>& PiNeq)
00461 {
00462     typedef SymmetricTensorImpl<T,3> S;
00463 
00464     T rhoTheta_bar = rhoBar*thetaBar + rhoBar + Descriptor::SkordosFactor*thetaBar;
00465     T invRho = Descriptor::invRho(rhoBar);
00466     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00467     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00468 
00469     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[0]*j[0];
00470     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[1]*j[1];
00471     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[2]*j[2];
00472 
00473     PiNeq[S::xy] = f[4] - f[5] + f[13] - f[14] - invRho*j[0]*j[1];
00474     PiNeq[S::xz] = f[6] - f[7] + f[15] - f[16] - invRho*j[0]*j[2];
00475     PiNeq[S::yz] = f[8] - f[9] + f[17] - f[18] - invRho*j[1]*j[2];
00476 }
00477 
00478 static void compute_rhoBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j, Array<T,6>& PiNeq, bool incompr )
00479 {
00480     typedef SymmetricTensorImpl<T,3> S;
00481 
00482     T surfX_M1, surfX_0, surfX_P1,
00483       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00484 
00485     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00486                    surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00487     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00488     j[0]  = ( surfX_P1 - surfX_M1 );
00489     j[1]  = ( surfY_P1 - surfY_M1 );
00490     j[2]  = ( surfZ_P1 - surfZ_M1 );
00491     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00492 
00493     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00494     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00495     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00496 
00497     PiNeq[S::xy] = f[4] - f[5] + f[13] - f[14] - invRho*j[0]*j[1];
00498     PiNeq[S::xz] = f[6] - f[7] + f[15] - f[16] - invRho*j[0]*j[2];
00499     PiNeq[S::yz] = f[8] - f[9] + f[17] - f[18] - invRho*j[1]*j[2];
00500 }
00501 
00502 static void compute_rhoBar_thetaBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, T& thetaBar,
00503                                             Array<T,3> const& j, Array<T,6>& PiNeq )
00504 {
00505     get_rhoBar_j(f, rhoBar, j);
00506     bool incompr = false;
00507     compute_PiNeq(f, rhoBar, j, PiNeq, incompr);
00508     T rhoThetaBar = compute_rhoThetaBar(f);
00509     thetaBar = rhoThetaBar * Descriptor::invRho(rhoBar);
00510     compute_thermal_PiNeq(f, rhoBar, thetaBar, j, PiNeq);
00511 }
00512 
00513 static void compute_P(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& P) {
00514     typedef SymmetricTensorImpl<T,3> S;
00515 
00516     T invRho = Descriptor::invRho(rhoBar);
00517     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00518     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00519 
00520     P[S::xx] = surfX_P1+surfX_M1 - invRho*j[0]*j[0];
00521     P[S::yy] = surfY_P1+surfY_M1 - invRho*j[1]*j[1];
00522     P[S::zz] = surfZ_P1+surfZ_M1 - invRho*j[2]*j[2];
00523 
00524     P[S::xy] = f[4] - f[5] + f[13] - f[14] - invRho*j[0]*j[1];
00525     P[S::xz] = f[6] - f[7] + f[15] - f[16] - invRho*j[0]*j[2];
00526     P[S::yz] = f[8] - f[9] + f[17] - f[18] - invRho*j[1]*j[2];
00527 }
00528 
00529 static void modifyJ(Array<T,Descriptor::q>& f, Array<T,3> const& newJ) {
00530     T rhoBar, oldJ[3];
00531     get_rhoBar_j(f, rhoBar, oldJ);
00532     const T oldJSqr = VectorTemplateImpl<T,3>::normSqr(oldJ);
00533     const T newJSqr = VectorTemplateImpl<T,3>::normSqr(newJ);
00534     for (plint iPop=0; iPop<Descriptor::q; ++iPop) {
00535         f[iPop] = f[iPop]
00536                          - equilibrium(iPop, rhoBar, oldJ, oldJSqr)
00537                          + equilibrium(iPop, rhoBar, newJ, newJSqr);
00538     }
00539 }
00540 
00541 };  //struct momentTemplatesImpl<D3Q19DescriptorBase>
00542 
00543 // Efficient specialization for D3Q15 lattice
00544 template<typename T>
00545 struct momentTemplatesImpl<T, descriptors::D3Q15DescriptorBase<T> > {
00546 
00547 typedef descriptors::D3Q15DescriptorBase<T> Descriptor;
00548 
00549 static void partial_rho(Array<T,Descriptor::q> const& f,
00550                         T& surfX_M1, T& surfX_P1,
00551                         T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00552 {
00553     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7];
00554     surfX_P1 = f[8] + f[11] + f[12] + f[13] + f[14];
00555 
00556     surfY_M1 = f[2] + f[4] + f[5] + f[13] + f[14];
00557     surfY_P1 = f[6] + f[7] + f[9] + f[11] + f[12];
00558 
00559     surfZ_M1 = f[3] + f[4] + f[6] + f[12] + f[14];
00560     surfZ_P1 = f[5] + f[7] + f[10] + f[11] + f[13];
00561 }
00562 
00563 static void partial_rho(Array<T,Descriptor::q> const& f,
00564                         T& surfX_M1, T& surfX_0, T& surfX_P1,
00565                         T& surfY_M1, T& surfY_P1, T& surfZ_M1, T& surfZ_P1 )
00566 {
00567     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00568     surfX_0  = f[0] + f[2] + f[3] + f[9] + f[10];
00569 }
00570 
00571 static T get_rhoBar(Array<T,Descriptor::q> const& f) {
00572     T rhoBar = f[0] + f[1] + f[2] + f[3] + f[4]
00573                        + f[5] + f[6] + f[7] + f[8]
00574                        + f[9] + f[10] + f[11] + f[12]
00575                        + f[13] + f[14];
00576     return rhoBar;
00577 }
00578 
00579 static void get_j(Array<T,Descriptor::q> const& f, Array<T,3>& j) {
00580     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00581 
00582     surfX_M1 = f[1] + f[4] + f[5] + f[6] + f[7];
00583     surfX_P1 = f[8] + f[11] + f[12] + f[13] + f[14];
00584 
00585     surfY_M1 = f[2] + f[4] + f[5] + f[13] + f[14];
00586     surfY_P1 = f[6] + f[7] + f[9] + f[11] + f[12];
00587 
00588     surfZ_M1 = f[3] + f[4] + f[6] + f[12] + f[14];
00589     surfZ_P1 = f[5] + f[7] + f[10] + f[11] + f[13];
00590 
00591     j[0]  = ( surfX_P1 - surfX_M1 );
00592     j[1]  = ( surfY_P1 - surfY_M1 );
00593     j[2]  = ( surfZ_P1 - surfZ_M1 );
00594 }
00595 
00596 static T get_eBar(Array<T,Descriptor::q> const& f) {
00597     T eBar = (T)3 * (f[4] + f[5] + f[6] + f[7] +
00598                      f[11] + f[12] + f[13] + f[14] )
00599                    + f[1] + f[2] + f[3] +
00600                      f[8] + f[9] + f[10];
00601     return eBar;
00602 
00603 }
00604 
00605 static void get_rhoBar_j(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j) {
00606     T surfX_M1, surfX_0, surfX_P1,
00607       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00608 
00609     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00610                       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00611 
00612     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00613 
00614     j[0]  = ( surfX_P1 - surfX_M1 );
00615     j[1]  = ( surfY_P1 - surfY_M1 );
00616     j[2]  = ( surfZ_P1 - surfZ_M1 );
00617 }
00618 
00619 static T compute_rho(Array<T,Descriptor::q> const& f) {
00620     return Descriptor::fullRho(get_rhoBar(f));
00621 }
00622 
00623 static void compute_uLb(Array<T,Descriptor::q> const& f, Array<T,3>& uLb ) {
00624     get_j(f, uLb);
00625     T invRho = Descriptor::invRho(get_rhoBar(f));
00626     uLb[0] *= invRho;
00627     uLb[1] *= invRho;
00628     uLb[2] *= invRho;
00629 }
00630 
00631 static void compute_rho_uLb(Array<T,Descriptor::q> const& f, T& rho, Array<T,3>& uLb ) {
00632     T rhoBar;
00633     get_rhoBar_j(f, rhoBar, uLb);
00634     T invRho = Descriptor::invRho(rhoBar);
00635     rho = Descriptor::fullRho(rhoBar);
00636     uLb[0] *= invRho;
00637     uLb[1] *= invRho;
00638     uLb[2] *= invRho;
00639 }
00640 
00641 static T compute_e(Array<T,Descriptor::q> const& f) {
00642     return get_eBar(f) + Descriptor::SkordosFactor * Descriptor::d * Descriptor::cs2;
00643 }
00644 
00645 static T compute_rhoThetaBar(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00646     T invRho = Descriptor::invRho(rhoBar);
00647     return Descriptor::invCs2 * Descriptor::invD * (get_eBar(f) - invRho*jSqr) - rhoBar;
00648 }
00649 
00650 static void compute_rho_rhoThetaBar(Array<T,Descriptor::q> const& f, T& rho, T& rhoThetaBar) {
00651     T rhoBar;
00652     Array<T,3> j;
00653     get_rhoBar_j(f, rhoBar, j);
00654     T jSqr = VectorTemplateImpl<T,Descriptor::d>::normSqr(j);
00655     rho = Descriptor::fullRho(rhoBar);
00656     rhoThetaBar = compute_rhoThetaBar(f, rhoBar, jSqr);
00657 }
00658 
00659 static T compute_theta(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00660     T invRho = Descriptor::invRho(rhoBar);
00661     T e = compute_e(f);
00662     return invRho * Descriptor::invD * Descriptor::invCs2 * (e - invRho*jSqr);
00663 }
00664 
00665 static T compute_rhoEpsilon(Array<T,Descriptor::q> const& f, T rhoBar, T jSqr) {
00666     T invRho = Descriptor::invRho(rhoBar);
00667     T e = compute_e(f);
00668     return (e - invRho*jSqr) / (T)2;
00669 }
00670 
00671 static void compute_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& PiNeq, bool incompr)
00672 {
00673     typedef SymmetricTensorImpl<T,3> S;
00674 
00675     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00676     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00677     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00678 
00679     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00680     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00681     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00682 
00683     PiNeq[S::xy] =   f[4] + f[5] - f[6]  - f[7]
00684                    + f[11] + f[12] - f[13] - f[14] - invRho*j[0]*j[1];
00685     PiNeq[S::xz] =   f[4] - f[5] + f[6]  - f[7]
00686                    + f[11] - f[12] + f[13] - f[14] - invRho*j[0]*j[2];
00687     PiNeq[S::yz] =   f[4] - f[5] - f[6]  + f[7]
00688                    + f[11] - f[12] - f[13] + f[14] - invRho*j[1]*j[2];
00689 }
00690 
00691 static void compute_thermal_PiNeq(Array<T,Descriptor::q> const& f, T rhoBar, T thetaBar,
00692                                   Array<T,3> const& j, Array<T,6>& PiNeq)
00693 {
00694     typedef SymmetricTensorImpl<T,3> S;
00695 
00696     T rhoTheta_bar = rhoBar*thetaBar + rhoBar + Descriptor::SkordosFactor*thetaBar;
00697     T invRho = Descriptor::invRho(rhoBar);
00698     T surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00699     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00700 
00701     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[0]*j[0];
00702     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[1]*j[1];
00703     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoTheta_bar - invRho*j[2]*j[2];
00704 
00705     PiNeq[S::xy] =   f[4] + f[5] - f[6]  - f[7]
00706                    + f[11] + f[12] - f[13] - f[14] - invRho*j[0]*j[1];
00707     PiNeq[S::xz] =   f[4] - f[5] + f[6]  - f[7]
00708                    + f[11] - f[12] + f[13] - f[14] - invRho*j[0]*j[2];
00709     PiNeq[S::yz] =   f[4] - f[5] - f[6]  + f[7]
00710                    + f[11] - f[12] - f[13] + f[14] - invRho*j[1]*j[2];
00711 }
00712 
00713 static void compute_rhoBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, Array<T,3>& j, Array<T,6>& PiNeq, bool incompr )
00714 {
00715     typedef SymmetricTensorImpl<T,3> S;
00716 
00717     T surfX_M1, surfX_0, surfX_P1,
00718       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00719 
00720     partial_rho(f, surfX_M1, surfX_0, surfX_P1,
00721                    surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00722     rhoBar = surfX_M1 + surfX_0 + surfX_P1;
00723     j[0]  = ( surfX_P1 - surfX_M1 );
00724     j[1]  = ( surfY_P1 - surfY_M1 );
00725     j[2]  = ( surfZ_P1 - surfZ_M1 );
00726     T invRho = incompr ? 1. : Descriptor::invRho(rhoBar);
00727 
00728     PiNeq[S::xx] = surfX_P1+surfX_M1 - Descriptor::cs2*rhoBar - invRho*j[0]*j[0];
00729     PiNeq[S::yy] = surfY_P1+surfY_M1 - Descriptor::cs2*rhoBar - invRho*j[1]*j[1];
00730     PiNeq[S::zz] = surfZ_P1+surfZ_M1 - Descriptor::cs2*rhoBar - invRho*j[2]*j[2];
00731 
00732     PiNeq[S::xy] =   f[4] + f[5] - f[6]  - f[7]
00733                    + f[11] + f[12] - f[13] - f[14] - invRho*j[0]*j[1];
00734     PiNeq[S::xz] =   f[4] - f[5] + f[6]  - f[7]
00735                    + f[11] - f[12] + f[13] - f[14] - invRho*j[0]*j[2];
00736     PiNeq[S::yz] =   f[4] - f[5] - f[6]  + f[7]
00737                    + f[11] - f[12] - f[13] + f[14] - invRho*j[1]*j[2];
00738 }
00739 
00740 static void compute_rhoBar_thetaBar_j_PiNeq(Array<T,Descriptor::q> const& f, T& rhoBar, T& thetaBar,
00741                                             Array<T,3> const& j, Array<T,6>& PiNeq )
00742 {
00743     get_rhoBar_j(f, rhoBar, j);
00744     bool incompr = false;
00745     compute_PiNeq(f, rhoBar, j, PiNeq, incompr);
00746     T rhoThetaBar = compute_rhoThetaBar(f);
00747     thetaBar = rhoThetaBar * Descriptor::invRho(rhoBar);
00748     compute_thermal_PiNeq(f, rhoBar, thetaBar, j, PiNeq);
00749 }
00750 
00751 static void compute_P(Array<T,Descriptor::q> const& f, T rhoBar, Array<T,3> const& j, Array<T,6>& P) {
00752     typedef SymmetricTensorImpl<T,3> S;
00753 
00754     T invRho = Descriptor::invRho(rhoBar);
00755     T surfX_M1, surfX_P1,
00756       surfY_M1, surfY_P1, surfZ_M1, surfZ_P1;
00757     partial_rho(f, surfX_M1, surfX_P1, surfY_M1, surfY_P1, surfZ_M1, surfZ_P1);
00758 
00759     P[S::xx] = surfX_P1+surfX_M1 - invRho*j[0]*j[0];
00760     P[S::yy] = surfY_P1+surfY_M1 - invRho*j[1]*j[1];
00761     P[S::zz] = surfZ_P1+surfZ_M1 - invRho*j[2]*j[2];
00762 
00763     P[S::xy] =   f[4] + f[5] - f[6]  - f[7]
00764                + f[11] + f[12] - f[13] - f[14] - invRho*j[0]*j[1];
00765     P[S::xz] =   f[4] - f[5] + f[6]  - f[7]
00766                + f[11] - f[12] + f[13] - f[14] - invRho*j[0]*j[2];
00767     P[S::yz] =   f[4] - f[5] - f[6]  + f[7]
00768                + f[11] - f[12] - f[13] + f[14] - invRho*j[1]*j[2];
00769 }
00770 
00771 static void modifyJ(Array<T,Descriptor::q>& f, Array<T,3> const& newJ) {
00772     T rhoBar, oldJ[3];
00773     get_rhoBar_j(f, rhoBar, oldJ);
00774     const T oldJSqr = VectorTemplateImpl<T,3>::normSqr(oldJ);
00775     const T newJSqr = VectorTemplateImpl<T,3>::normSqr(newJ);
00776     for (plint iPop=0; iPop<Descriptor::q; ++iPop) {
00777         f[iPop] = f[iPop]
00778                          - equilibrium(iPop, rhoBar, oldJ, oldJSqr)
00779                          + equilibrium(iPop, rhoBar, newJ, newJSqr);
00780     }
00781 }
00782 
00783 };  //struct momentTemplatesImpl<D3Q15DescriptorBase>
00784 
00785 }  // namespace plb
00786 
00787 #endif