• VTF
  • FSI
  • AMROC
  • SFC
  • Motion
  • STLIB
  • Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

amroc/lbm/LBMD3Q19Thermal_BC.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2012 Oak Ridge National Laboratory
00004 // Ralf Deiterding, deiterdingr@ornl.gov
00005 
00006 #ifndef LBM_D3Q19_H
00007 #define LBM_D3Q19_H
00008 
00016 #include "LBMBase.h"
00017 #include <cfloat>
00018 
00019 #define LB_FACTOR 1.0e5
00020 
00074 template <class DataType>
00075 class LBMD3Q19Thermal : public LBMBase<Vector<DataType,26>, Vector<DataType,5>, 3> {
00076   typedef LBMBase<Vector<DataType,26>, Vector<DataType,5>, 3> base;
00077 public:
00078   typedef typename base::vec_grid_data_type vec_grid_data_type;
00079   typedef typename base::grid_data_type grid_data_type;
00080   typedef typename base::MicroType MicroType;
00081   typedef typename base::MacroType MacroType;
00082   typedef GridData<MacroType,3> macro_grid_data_type;
00083   typedef typename base::SideName SideName;
00084   typedef typename base::point_type point_type;
00085 
00086   enum ICPredefined { GasAtRest, ConstantMacro, ConstantMicro };
00087   enum BCPredefined { Symmetry, SlipWall, NoSlipWall, Inlet, Outlet, Pressure, SlidingWall, ExtrapolationEquilibrium, SlipWallTemperature, NoSlipWallTemperature, BounceBackDirichlet };
00088   enum GFMPredefined { GFMExtrapolation, GFMSlipWallTemp, GFMNoSlipWallTemp, GFMWallLaw, GFMBounceBack };
00089   enum TurbulenceModel { laminar, LES_Smagorinsky, LES_dynamic };
00090 
00091   LBMD3Q19Thermal() : base(), P0(1.), R0(1.), U0(1.), S0(1.), Temp0(1.), prp(0.), rhop(0.), Tpmin(0.), Tpmax(0.), Tref(0.5), csp(0.), cs2p(0.), nup (0.), nutp (0.), gp(1.), Wp(1.), Rp(1.)  {
00092     cs2  = DataType(1.)/DataType(3.);
00093     cs22 = DataType(2.)*cs2;
00094     cssq = DataType(2.)/DataType(9.);
00095     ds2  = DataType(1.)/DataType(2.);
00096     dcs2 = ds2/cs2;
00097     method[0] = 2;
00098     turbulence = laminar;
00099 
00100     mdx[0]=mdx[3]=mdx[4]=mdx[5]=mdx[6]=mdx[11]=mdx[12]=mdx[13]=mdx[14]=0;
00101     mdx[1]=mdx[7]=mdx[9]=mdx[15]=mdx[17]=1;
00102     mdx[2]=mdx[8]=mdx[10]=mdx[16]=mdx[18]=-1;
00103 
00104     mdy[0]=mdy[1]=mdy[2]=mdy[5]=mdy[6]=mdy[15]=mdy[16]=mdy[17]=mdy[18]=0;
00105     mdy[3]=mdy[7]=mdy[10]=mdy[11]=mdy[13]=1;
00106     mdy[4]=mdy[8]=mdy[9]=mdy[12]=mdy[14]=-1;
00107 
00108     mdz[0]=mdz[1]=mdz[2]=mdz[3]=mdz[4]=mdz[7]=mdz[8]=mdz[9]=mdz[10]=0;
00109     mdz[5]=mdz[11]=mdz[14]=mdz[15]=mdz[18]=1;
00110     mdz[6]=mdz[12]=mdz[13]=mdz[16]=mdz[17]=-1;
00111 
00112     mdx[19]=mdx[22]=mdx[23]=mdx[24]=mdx[25]=0;
00113     mdx[20]=1;
00114     mdx[21]=-1;
00115    
00116     mdy[19]=mdy[20]=mdy[21]=mdy[24]=mdy[25]=0;
00117     mdy[22]=1;
00118     mdy[23]=-1;
00119 
00120     mdz[19]=mdz[20]=mdz[21]=mdz[22]=mdz[23]=0;
00121     mdz[24]=1;
00122     mdz[25]=-1;
00123 
00124   }
00125 
00126   virtual ~LBMD3Q19Thermal() {}
00127 
00128   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00129     base::LocCtrl = Ctrl.getSubDevice(prefix+"D3Q19");
00130     RegisterAt(base::LocCtrl,"Method(1)",method[0]);
00131     RegisterAt(base::LocCtrl,"Turbulence",turbulence);
00132     RegisterAt(base::LocCtrl,"Cs_Smagorinsky",Cs_Smagorinsky);
00133     RegisterAt(base::LocCtrl,"Gas_rho",rhop);
00134     RegisterAt(base::LocCtrl,"Gas_Cs",csp);
00135     RegisterAt(base::LocCtrl,"Gas_pr",prp);
00136     RegisterAt(base::LocCtrl,"Gas_nu",nup);
00137     RegisterAt(base::LocCtrl,"Gas_nuT",nutp); 
00138     RegisterAt(base::LocCtrl,"Gas_Tmin",Tpmin); 
00139     RegisterAt(base::LocCtrl,"Gas_Tmax",Tpmax); 
00140     RegisterAt(base::LocCtrl,"Gas_gamma",gp);
00141     RegisterAt(base::LocCtrl,"Gas_W",Wp);
00142     RegisterAt(base::LocCtrl,"Ideal_R",Rp);
00143     RegisterAt(base::LocCtrl,"SpeedUp",S0);
00144   }
00145 
00146   virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00147     base::SetupData(gh,ghosts);
00148     if (rhop>0.) R0 = rhop;
00149     if (prp>0.) P0 = prp;
00150     if (Tpmin!=0. || Tpmax!=0.0) SetTemperatureScale(Tpmin,Tpmax);
00151     if (csp>0.) {
00152       cs2p = csp*csp;
00153       SetTimeScale(LatticeSpeedOfSound()/csp*L0());
00154     }
00155     std::cout << "D3Q19Thermal: Gas_rho=" << rhop << "   Gas_Cs=" << csp
00156               << "   Gas_nu=" << nup << std::endl;
00157     std::cout << "D3Q19Thermal: L0=" << L0() << "   T0=" << T0() << "   U0=" << U0
00158               << "   R0=" << R0 << "   Temp0=" << Temp0 << "   S0=" << S0 << "   P0=" << P0 << std::endl;
00159     if ( TurbulenceType() ==  laminar ) {
00160       std::cout << "LBM Setup() Laminar" << std::endl;
00161     }
00162     if ( TurbulenceType() ==  LES_Smagorinsky ) {
00163       std::cout << "LBM Setup() LES_Smagorinsky : Smagorinsky Constant = " << SmagorinskyConstant()
00164                 << std::endl;
00165 
00166     }
00167     if ( TurbulenceType() ==  LES_dynamic ) {
00168       std::cout << "LBM Setup() LES_dynamic " << std::endl;
00169     }
00170   }
00171 
00172   inline virtual MacroType MacroVariables(const MicroType &f) const {
00173     MacroType q;
00174 
00175     DataType part1,part2;
00176 
00177     q(1)=f(1)-f(2)+f(7)-f(8)+f(9)-f(10)+f(15)-f(16)+f(17)-f(18);
00178     q(2)=f(3)-f(4)+f(7)-f(8)-f(9)+f(10)+f(11)-f(12)+f(13)-f(14);
00179     q(3)=f(5)-f(6)+f(11)-f(12)-f(13)+f(14)+f(15)-f(16)-f(17)+f(18);
00180 
00181     part1 = f(1)+f(2)+f(3)+f(4)+f(5)+f(6)+f(7)+f(8)+f(9)+f(10)+f(11)+f(12)+f(13)+f(14)+f(15)+f(16)+f(17)+f(18);
00182     part2 = ds2*(std::pow(q(1),2)+std::pow(q(2),2)+std::pow(q(3),2));
00183    
00184     q(0)= (DataType(1.)/DataType(2.))*(part1-part2);
00185     q(4)= f(20)+f(21)+f(22)+f(23)+f(24)+f(25);
00186     return q;
00187   }
00188 
00189   inline virtual MicroType Equilibrium(const MacroType &q) const {
00190     MicroType feq;
00191 
00192     DataType p  = q(0);
00193     DataType u  = q(1);
00194     DataType v  = q(2);
00195     DataType w  = q(3);
00196     DataType T  = q(4);
00197 
00198     DataType ri, rt0, rt1, rt2, pre0, pre1, pre2;
00199     
00200     ri = DataType(0.);
00201     rt0 = DataType(1.) / DataType(3.);
00202     rt1 = DataType(1.) / DataType(18.);
00203     rt2 = DataType(1.) / DataType(36.);
00204 
00205     pre0 =  -DataType(2.)*p;
00206     pre1 =  (DataType(1.)/DataType(6.))*p;
00207     pre2 =  (DataType(1.)/DataType(12.))*p;
00208 
00209 
00210     DataType usq = u * u;
00211     DataType vsq = v * v;
00212     DataType wsq = w * w;
00213     DataType sumsq = (usq + vsq + wsq) / cs22;
00214     DataType sumsqxy = (usq + vsq) / cs22;
00215     DataType sumsqyz = (vsq + wsq) / cs22;
00216     DataType sumsqxz = (usq + wsq) / cs22;
00217     DataType sumsq2xy = sumsqxy * (DataType(1.) - cs2) / cs2;
00218     DataType sumsq2yz = sumsqyz * (DataType(1.) - cs2) / cs2;
00219     DataType sumsq2xz = sumsqxz * (DataType(1.) - cs2) / cs2;
00220     DataType u2 = usq / cssq;
00221     DataType v2 = vsq / cssq;
00222     DataType w2 = wsq / cssq;
00223     DataType u22 = usq / cs22;
00224     DataType v22 = vsq / cs22;
00225     DataType w22 = wsq / cs22;
00226     DataType ui = u / cs2;
00227     DataType vi = v / cs2;
00228     DataType wi = w / cs2;
00229     DataType uv = ui * vi;
00230     DataType uw = ui * wi;
00231     DataType vw = vi * wi;
00232 
00233     DataType Temp = T / DataType(6.);
00234     DataType uT = DataType(3.) * u;
00235     DataType vT = DataType(3.) * v;
00236     DataType wT = DataType(3.) * w;
00237 
00238     feq(0) = pre0 + rt0 * (ri - sumsq);
00239     //x
00240     feq(1) = pre1 + rt1 * (ri - sumsq + u2 + ui);
00241     feq(2) = pre1 + rt1 * (ri - sumsq + u2 - ui);
00242     //y
00243     feq(3) = pre1 + rt1 * (ri - sumsq + v2 + vi);
00244     feq(4) = pre1 + rt1 * (ri - sumsq + v2 - vi);
00245     //z 
00246     feq(5) = pre1 + rt1 * (ri - sumsq + w2 + wi);
00247     feq(6) = pre1 + rt1 * (ri - sumsq + w2 - wi);
00248     //x-y
00249     feq(7) = pre2 + rt2 * (ri + sumsq2xy -w22 + ui + vi + uv);
00250     feq(8) = pre2 + rt2 * (ri + sumsq2xy -w22 - ui - vi + uv);
00251     feq(9) = pre2 + rt2 * (ri + sumsq2xy -w22 + ui - vi - uv);
00252     feq(10)= pre2 + rt2 * (ri + sumsq2xy -w22 - ui + vi - uv);
00253     //y-z
00254     feq(11)= pre2 + rt2 * (ri + sumsq2yz -u22 + vi + wi + vw);
00255     feq(12)= pre2 + rt2 * (ri + sumsq2yz -u22 - vi - wi + vw);
00256     feq(13)= pre2 + rt2 * (ri + sumsq2yz -u22 + vi - wi - vw);
00257     feq(14)= pre2 + rt2 * (ri + sumsq2yz -u22 - vi + wi - vw);
00258     //x-z
00259     feq(15)= pre2 + rt2 * (ri + sumsq2xz -v22 + ui + wi + uw);
00260     feq(16)= pre2 + rt2 * (ri + sumsq2xz -v22 - ui - wi + uw);
00261     feq(17)= pre2 + rt2 * (ri + sumsq2xz -v22 + ui - wi - uw);
00262     feq(18)= pre2 + rt2 * (ri + sumsq2xz -v22 - ui + wi - uw);
00263 
00264     //D3Q6 
00265     feq(19) = DataType(0.); //Temp; 
00266     feq(20) = Temp * (DataType(1.) + uT);
00267     feq(21) = Temp * (DataType(1.) - uT);
00268     feq(22) = Temp * (DataType(1.) + vT);
00269     feq(23) = Temp * (DataType(1.) - vT);
00270     feq(24) = Temp * (DataType(1.) + wT);
00271     feq(25) = Temp * (DataType(1.) - wT);
00272 
00273     return feq;
00274   }
00275 
00276   inline virtual void Collision(MicroType &f, const DataType dt) const {
00277     MacroType q = MacroVariables(f);
00278     MicroType feq = Equilibrium(q);
00279 
00280     DataType force = DataType(0.5)*dt/S0*gbeta*(q(4)-Tref);                         
00281 
00282     DataType omega = Omega(dt), omegaT = OmegaT(dt);
00283     
00284     for(int i=0;i<=25;i++){ 
00285             if(i<19){
00286                 f(i)=(DataType(1.)-omega)*f(i) + omega*feq(i);
00287                 if(i==3) f(3) += force; 
00288                 if(i==4) f(4) -= force; 
00289             }
00290             else f(i)=(DataType(1.)-omegaT)*f(i) + omegaT*feq(i);
00291     }
00292   }     
00293 
00294    virtual int IncomingIndices(const int side, int indices[]) const {
00295     switch (side) {
00296     case base::Left:
00297       indices[0] = 1; indices[1] = 7; indices[2] = 9; indices[3] = 15; indices[4] = 17;
00298       indices[5] = 20;  
00299       break;
00300     case base::Right:
00301       indices[0] = 2; indices[1] = 8; indices[2] = 10; indices[3] = 16; indices[4] = 18;   
00302       indices[5] = 21;
00303       break;
00304     case base::Bottom:
00305       indices[0] = 3; indices[1] = 7; indices[2] = 10; indices[3] = 11; indices[4] = 13;  
00306       indices[5] = 22;
00307       break;
00308     case base::Top:
00309       indices[0] = 4; indices[1] = 8; indices[2] = 9; indices[3] = 12; indices[4] = 14;  
00310       indices[5] = 23;
00311       break;
00312     case base::Front:
00313       indices[0] = 5; indices[1] = 11; indices[2] = 14; indices[3] = 15; indices[4] = 18;  
00314       indices[5] = 24;
00315       break;
00316     case base::Back:
00317       indices[0] = 6; indices[1] = 12; indices[2] = 13; indices[3] = 16; indices[4] = 17;  
00318       indices[5] = 25;
00319       break;
00320      }
00321     return 6;
00322   }
00323 
00324   virtual int OutgoingIndices(const int side, int indices[]) const {
00325     switch (side) {
00326     case base::Left:
00327       indices[0] = 2; indices[1] = 8; indices[2] = 10; indices[3] = 16; indices[4] = 18;   
00328       indices[5] = 21;
00329       break;
00330     case base::Right:
00331       indices[0] = 1; indices[1] = 7; indices[2] = 9; indices[3] = 15; indices[4] = 17;  
00332       indices[5] = 20;
00333       break;
00334     case base::Bottom:
00335       indices[0] = 4; indices[1] = 8; indices[2] = 9; indices[3] = 12; indices[4] = 14;  
00336       indices[5] = 23;
00337       break;
00338     case base::Top:
00339       indices[0] = 3; indices[1] = 7; indices[2] = 10; indices[3] = 11; indices[4] = 13;  
00340       indices[5] = 22;
00341       break;
00342     case base::Front:
00343       indices[0] = 6; indices[1] = 12; indices[2] = 13; indices[3] = 16; indices[4] = 17;  
00344       indices[5] = 25;
00345       break;
00346     case base::Back:
00347       indices[0] = 5; indices[1] = 11; indices[2] = 14; indices[3] = 15; indices[4] = 18;  
00348       indices[5] = 24;
00349       break;
00350      }
00351     return 6;
00352   }
00353 
00354   // Revert just one layer of cells at the boundary 
00355   virtual void ReverseStream(vec_grid_data_type &fvec, const BBox &bb, 
00356                              const int side) const {
00357     int Nx = fvec.extents(0), Ny = fvec.extents(1);
00358     int b = fvec.bottom();
00359     assert (fvec.stepsize(0)==bb.stepsize(0) && fvec.stepsize(1)==bb.stepsize(1) 
00360             && fvec.stepsize(2)==bb.stepsize(2));
00361     int mxs = std::max(bb.lower(0)/bb.stepsize(0),fvec.lower(0)/fvec.stepsize(0));
00362     int mys = std::max(bb.lower(1)/bb.stepsize(1),fvec.lower(1)/fvec.stepsize(1));
00363     int mzs = std::max(bb.lower(2)/bb.stepsize(2),fvec.lower(2)/fvec.stepsize(2));
00364     int mxe = std::min(bb.upper(0)/bb.stepsize(0),fvec.upper(0)/fvec.stepsize(0));
00365     int mye = std::min(bb.upper(1)/bb.stepsize(1),fvec.upper(1)/fvec.stepsize(1));
00366     int mze = std::min(bb.upper(2)/bb.stepsize(2),fvec.upper(2)/fvec.stepsize(2));
00367     MicroType *f = (MicroType *)fvec.databuffer();
00368 
00369 #ifdef DEBUG_PRINT_FIXUP
00370     ( comm_service::log() << "Reverse streaming at Side: " << side << " of " 
00371       << fvec.bbox() << " using " << bb << "\n").flush();
00372 #endif
00373     
00374     switch (side) {
00375     case base::Left:
00376       for (register int k=mzs; k<=mze; k++) 
00377         for (register int j=mys; j<=mye; j++) {
00378           f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](2);
00379           f[b+base::idx(mxs,j,k,Nx,Ny)](21) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](21);
00380           f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](8);
00381           f[b+base::idx(mxs,j,k,Nx,Ny)](10)= f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](10);
00382           f[b+base::idx(mxs,j,k,Nx,Ny)](16)= f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](16);
00383           f[b+base::idx(mxs,j,k,Nx,Ny)](18)= f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](18);
00384         }
00385       break;
00386     case base::Right:
00387       for (register int k=mzs; k<=mze; k++) 
00388         for (register int j=mys; j<=mye; j++) {
00389           f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](1);
00390           f[b+base::idx(mxe,j,k,Nx,Ny)](20) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](20);
00391           f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](7);
00392           f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](9);
00393           f[b+base::idx(mxe,j,k,Nx,Ny)](15)= f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](15);
00394           f[b+base::idx(mxe,j,k,Nx,Ny)](17)= f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](17);
00395         }
00396       break;
00397     case base::Bottom:
00398       for (register int k=mzs; k<=mze; k++) 
00399         for (register int i=mxs; i<=mxe; i++) {
00400           f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](4);
00401           f[b+base::idx(i,mys,k,Nx,Ny)](23) = f[b+base::idx(i,mys-1,k,Nx,Ny)](23);
00402           f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](8);
00403           f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](9);
00404           f[b+base::idx(i,mys,k,Nx,Ny)](12)= f[b+base::idx(i,mys-1,k-1,Nx,Ny)](12);
00405           f[b+base::idx(i,mys,k,Nx,Ny)](14)= f[b+base::idx(i,mys-1,k+1,Nx,Ny)](14);
00406         }
00407       break;
00408     case base::Top:
00409       for (register int k=mzs; k<=mze; k++) 
00410         for (register int i=mxs; i<=mxe; i++) {
00411           f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](3);
00412           f[b+base::idx(i,mye,k,Nx,Ny)](22) = f[b+base::idx(i,mye+1,k,Nx,Ny)](22);
00413           f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](7);
00414           f[b+base::idx(i,mye,k,Nx,Ny)](10)= f[b+base::idx(i-1,mye+1,k,Nx,Ny)](10);
00415           f[b+base::idx(i,mye,k,Nx,Ny)](11)= f[b+base::idx(i,mye+1,k+1,Nx,Ny)](11);
00416           f[b+base::idx(i,mye,k,Nx,Ny)](13)= f[b+base::idx(i,mye+1,k-1,Nx,Ny)](13);
00417         }
00418       break;
00419     case base::Front:
00420       for (register int j=mys; j<=mye; j++) 
00421         for (register int i=mxs; i<=mxe; i++) {
00422           f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](6);
00423           f[b+base::idx(i,j,mzs,Nx,Ny)](25) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](25);
00424           f[b+base::idx(i,j,mzs,Nx,Ny)](12)= f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](12);
00425           f[b+base::idx(i,j,mzs,Nx,Ny)](13)= f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](13);
00426           f[b+base::idx(i,j,mzs,Nx,Ny)](16)= f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](16);
00427           f[b+base::idx(i,j,mzs,Nx,Ny)](17)= f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](17);
00428         }
00429       break;
00430     case base::Back:
00431       for (register int j=mys; j<=mye; j++) 
00432         for (register int i=mxs; i<=mxe; i++) {
00433           f[b+base::idx(i,j,mzs,Nx,Ny)](5) = f[b+base::idx(i,j,mzs+1,Nx,Ny)](5);
00434           f[b+base::idx(i,j,mzs,Nx,Ny)](24) = f[b+base::idx(i,j,mzs+1,Nx,Ny)](24);
00435           f[b+base::idx(i,j,mzs,Nx,Ny)](11)= f[b+base::idx(i,j+1,mzs+1,Nx,Ny)](11);
00436           f[b+base::idx(i,j,mzs,Nx,Ny)](14)= f[b+base::idx(i,j-1,mzs+1,Nx,Ny)](14);
00437           f[b+base::idx(i,j,mzs,Nx,Ny)](15)= f[b+base::idx(i+1,j,mzs+1,Nx,Ny)](15);
00438           f[b+base::idx(i,j,mzs,Nx,Ny)](18)= f[b+base::idx(i-1,j,mzs+1,Nx,Ny)](18);
00439         }
00440       break;
00441     }
00442   }   
00443 
00444   virtual void LocalStep(vec_grid_data_type &fvec, vec_grid_data_type &ovec, 
00445                          const BBox &bb, const double& dt) const {
00446     int Nx = fvec.extents(0), Ny = fvec.extents(1);
00447     int b = fvec.bottom();
00448     MicroType *f = (MicroType *)fvec.databuffer();
00449     MicroType *of = (MicroType *)ovec.databuffer();
00450 
00451 #ifdef DEBUG_PRINT_FIXUP
00452     ( comm_service::log() << "Local Step in " << fvec.bbox() << " from " << ovec.bbox() 
00453       << " using " << bb << "\n").flush();
00454 #endif
00455     
00456     assert (fvec.extents(0)==ovec.extents(0));
00457     assert (fvec.stepsize(0)==bb.stepsize(0) && fvec.stepsize(1)==bb.stepsize(1) && fvec.stepsize(2)==bb.stepsize(2) &&
00458             fvec.stepsize(0)==ovec.stepsize(0) && fvec.stepsize(1)==ovec.stepsize(1) && fvec.stepsize(2)==ovec.stepsize(2));
00459     int mxs = std::max(bb.lower(0)/bb.stepsize(0),fvec.lower(0)/fvec.stepsize(0));
00460     int mys = std::max(bb.lower(1)/bb.stepsize(1),fvec.lower(1)/fvec.stepsize(1));
00461     int mzs = std::max(bb.lower(2)/bb.stepsize(2),fvec.lower(2)/fvec.stepsize(2));
00462     int mxe = std::min(bb.upper(0)/bb.stepsize(0),fvec.upper(0)/fvec.stepsize(0));
00463     int mye = std::min(bb.upper(1)/bb.stepsize(1),fvec.upper(1)/fvec.stepsize(1));
00464     int mze = std::min(bb.upper(2)/bb.stepsize(2),fvec.upper(2)/fvec.stepsize(2));
00465 
00466     for (register int k=mzs; k<=mze; k++) 
00467       for (register int j=mys; j<=mye; j++) 
00468         for (register int i=mxs; i<=mxe; i++) {
00469           for (register int n=0; n<base::NMicroVar(); n++) 
00470             f[b+base::idx(i,j,k,Nx,Ny)](n) = of[b+base::idx(i-mdx[n],j-mdy[n],k-mdz[n],Nx,Ny)](n);
00471           Collision(f[b+base::idx(i,j,k,Nx,Ny)],dt);
00472         }
00473   }  
00474 
00475   virtual double Step(vec_grid_data_type &fvec, vec_grid_data_type &ovec, vec_grid_data_type* Flux[],
00476                       const double& t, const double& dt, const int& mpass) const {
00477     // Make sure that the physical length and times are scaling consistently
00478     // into lattice quantities
00479     DCoords dx = base::GH().worldStep(fvec.stepsize());
00480     
00481     //std::cout << "STEP   dt=" << dt << "   TO=" << T0() << std::endl;
00482     if ( (std::fabs(dx(0)/L0()-dx(1)/L0()) > DBL_EPSILON*LB_FACTOR)
00483          || (std::fabs(dx(1)/L0()-dx(2)/L0()) > DBL_EPSILON*LB_FACTOR) ) {
00484       std::cerr << "LBMD3Q19 expects dx(0)=" << dx(0)/L0() << " and dx(1)=" << dx(1)/L0()
00485                 << " and dx(2)=" << dx(2)/L0()
00486                 << " to be equal." << std::endl << std::flush;
00487       std::exit(-1);
00488     }
00489     if (std::fabs(dt/T0()-dx(0)/L0()) > DBL_EPSILON*LB_FACTOR)   {
00490       std::cerr << "LBMD3Q19 expects dt=" << dt/T0() << " and dx(0)=" << dx(0)/L0()
00491                 << " to be equal."
00492                 << "   dt=" << dt << "   TO=" << T0()
00493                 << std::endl << std::flush;
00494       std::exit(-1);
00495     }
00496 
00497     int Nx = fvec.extents(0), Ny = fvec.extents(1), Nz = fvec.extents(2);
00498     MicroType *f = (MicroType *)fvec.databuffer();
00499 
00500     // Streaming - update all cells
00501     for (register int k=Nz-1; k>=1; k--)
00502       for (register int j=Ny-1; j>=1; j--)
00503         for (register int i=0; i<=Nx-2; i++) {
00504           //x-y
00505           f[base::idx(i,j,k,Nx,Ny)](3) = f[base::idx(i,j-1,k,Nx,Ny)](3);
00506           f[base::idx(i,j,k,Nx,Ny)](22) = f[base::idx(i,j-1,k,Nx,Ny)](22);
00507           f[base::idx(i,j,k,Nx,Ny)](10) = f[base::idx(i+1,j-1,k,Nx,Ny)](10);
00508           //x-z
00509           f[base::idx(i,j,k,Nx,Ny)](5) = f[base::idx(i,j,k-1,Nx,Ny)](5);
00510           f[base::idx(i,j,k,Nx,Ny)](24) = f[base::idx(i,j,k-1,Nx,Ny)](24);
00511           f[base::idx(i,j,k,Nx,Ny)](18) = f[base::idx(i+1,j,k-1,Nx,Ny)](18);
00512         }
00513 
00514     for (register int k=0; k<=Nz-2; k++)
00515       for (register int j=Ny-1; j>=1; j--)
00516         for (register int i=0; i<=Nx-2; i++) {
00517           //y-z
00518           f[base::idx(i,j,k,Nx,Ny)](13) = f[base::idx(i,j-1,k+1,Nx,Ny)](13);//%%%%% -j,+k
00519         }
00520     for (register int k=Nz-1; k>=1; k--)
00521       for (register int j=Ny-1; j>=1; j--)
00522         for (register int i=Nx-1; i>=1; i--) {
00523           //x-y
00524           f[base::idx(i,j,k,Nx,Ny)](1) = f[base::idx(i-1,j,k,Nx,Ny)](1);
00525           f[base::idx(i,j,k,Nx,Ny)](20) = f[base::idx(i-1,j,k,Nx,Ny)](20);
00526           f[base::idx(i,j,k,Nx,Ny)](7) = f[base::idx(i-1,j-1,k,Nx,Ny)](7);
00527           //y-z
00528           f[base::idx(i,j,k,Nx,Ny)](11) = f[base::idx(i,j-1,k-1,Nx,Ny)](11);
00529           //x-z
00530           f[base::idx(i,j,k,Nx,Ny)](15) = f[base::idx(i-1,j,k-1,Nx,Ny)](15);
00531         }
00532 
00533     for (register int k=0; k<=Nz-2; k++)
00534       for (register int j=0; j<=Ny-2; j++)
00535         for (register int i=Nx-1; i>=1; i--) {
00536           //x-y
00537           f[base::idx(i,j,k,Nx,Ny)](4) = f[base::idx(i,j+1,k,Nx,Ny)](4);
00538           f[base::idx(i,j,k,Nx,Ny)](23) = f[base::idx(i,j+1,k,Nx,Ny)](23);
00539           f[base::idx(i,j,k,Nx,Ny)](9) = f[base::idx(i-1,j+1,k,Nx,Ny)](9);
00540           //x-z
00541           f[base::idx(i,j,k,Nx,Ny)](6) = f[base::idx(i,j,k+1,Nx,Ny)](6);
00542           f[base::idx(i,j,k,Nx,Ny)](25) = f[base::idx(i,j,k+1,Nx,Ny)](25);
00543           f[base::idx(i,j,k,Nx,Ny)](17) = f[base::idx(i-1,j,k+1,Nx,Ny)](17);
00544         }
00545     for (register int k=Nz-1; k>=1; k--)
00546       for (register int j=0; j<=Ny-2; j++)
00547         for (register int i=0; i<=Nx-2; i++) {
00548           //y-z
00549           f[base::idx(i,j,k,Nx,Ny)](14) = f[base::idx(i,j+1,k-1,Nx,Ny)](14);//%%%%% +j,-k
00550         }
00551     for (register int k=0; k<=Nz-2; k++)
00552       for (register int j=0; j<=Ny-2; j++)
00553         for (register int i=0; i<=Nx-2; i++) {
00554           //x-y
00555           f[base::idx(i,j,k,Nx,Ny)](2) = f[base::idx(i+1,j,k,Nx,Ny)](2);
00556           f[base::idx(i,j,k,Nx,Ny)](21) = f[base::idx(i+1,j,k,Nx,Ny)](21);
00557           f[base::idx(i,j,k,Nx,Ny)](8) = f[base::idx(i+1,j+1,k,Nx,Ny)](8);
00558           //y-z
00559           f[base::idx(i,j,k,Nx,Ny)](12) = f[base::idx(i,j+1,k+1,Nx,Ny)](12);
00560           //x-z
00561           f[base::idx(i,j,k,Nx,Ny)](16) = f[base::idx(i+1,j,k+1,Nx,Ny)](16);
00562         }
00563 
00564      // Collision - only in the interior region
00565     int mxs = base::NGhosts(), mys = base::NGhosts(), mzs = base::NGhosts();
00566     int mxe = Nx-base::NGhosts()-1, mye = Ny-base::NGhosts()-1, mze = Nz-base::NGhosts()-1;
00567     for (register int k=mzs; k<=mze; k++)
00568       for (register int j=mys; j<=mye; j++)
00569         for (register int i=mxs; i<=mxe; i++)
00570           Collision(f[base::idx(i,j,k,Nx,Ny)],dt);
00571 
00572     return DataType(1.);
00573   }
00574 
00575   virtual void ICStandard(vec_grid_data_type &fvec, const int type,
00576                           DataType* aux=0, const int naux=0, const int scaling=0) const {
00577     int Nx = fvec.extents(0), Ny = fvec.extents(1), Nz = fvec.extents(2);
00578     int mxs = base::NGhosts(), mys = base::NGhosts(), mzs = base::NGhosts();
00579     int mxe = Nx-base::NGhosts()-1, mye = Ny-base::NGhosts()-1, mze = Nz-base::NGhosts()-1;
00580     MicroType *f = (MicroType *)fvec.databuffer();
00581 
00582     //std::cout << "IC Nx=" << Nx << "   Ny=" << Ny << "   Nz=" << Nz << "   type=" << type << std::endl;
00583 
00584     if (type==ConstantMicro) {
00585       //std::cout << "ConstantMicro start\n";
00586       MicroType g;
00587       for (register int i=0; i<base::NMicroVar(); i++)
00588         g(i) = aux[i];
00589 
00590       for (register int k=mzs; k<=mze; k++)
00591         for (register int j=mys; j<=mye; j++)
00592           for (register int i=mxs; i<=mxe; i++)
00593             f[base::idx(i,j,k,Nx,Ny)] = g;
00594       //std::cout << "ConstantMicro end\n";
00595     }
00596     
00597     else if (type==ConstantMacro) {
00598       //std::cout << "ConstantMacro start\n";
00599       MacroType q;
00600       if (scaling==base::Physical) {
00601         q(0) = aux[0]/P0;
00602         q(1) = aux[1]/U0;
00603         q(2) = aux[2]/U0;
00604         q(3) = aux[3]/U0;
00605         q(4) = aux[4]/Temp0;
00606       }
00607       else
00608         for (register int i=0; i<base::NMacroVar(); i++)
00609           q(i) = aux[i];
00610       q(1) *= S0; q(2) *= S0; q(3) *= S0;
00611       
00612       for (register int k=mzs; k<=mze; k++)
00613         for (register int j=mys; j<=mye; j++)
00614           for (register int i=mxs; i<=mxe; i++)
00615             f[base::idx(i,j,k,Nx,Ny)] = Equilibrium(q);
00616       //std::cout << "ConstantMacro end\n";
00617     }
00618     
00619     else if (type==GasAtRest) {
00620       //std::cout << "GasAtRest start\n";
00621       MacroType q;
00622       q(0) = GasDensity()/R0;
00623       q(1) = DataType(0.);
00624       q(2) = DataType(0.);
00625       q(3) = DataType(0.);
00626       q(4) = DataType(0.);
00627       for (register int k=mzs; k<=mze; k++)
00628         for (register int j=mys; j<=mye; j++)
00629           for (register int i=mxs; i<=mxe; i++)
00630             f[base::idx(i,j,k,Nx,Ny)] = Equilibrium(q);
00631       //std::cout << "GasAtRest end\n";
00632     }
00633   }
00634 
00635   // Set just the one layer of ghost cells at the boundary
00636   virtual void BCStandard(vec_grid_data_type &fvec, const BBox &bb, const int type, const int side,
00637                           DataType* aux=0, const int naux=0, const int scaling=0) const {
00638     int Nx = fvec.extents(0), Ny = fvec.extents(1);
00639     int b = fvec.bottom();
00640     assert (fvec.stepsize(0)==bb.stepsize(0) && fvec.stepsize(1)==bb.stepsize(1) 
00641             && fvec.stepsize(2)==bb.stepsize(2));
00642     int mxs = std::max(bb.lower(0)/bb.stepsize(0),fvec.lower(0)/fvec.stepsize(0));
00643     int mys = std::max(bb.lower(1)/bb.stepsize(1),fvec.lower(1)/fvec.stepsize(1));
00644     int mzs = std::max(bb.lower(2)/bb.stepsize(2),fvec.lower(2)/fvec.stepsize(2));
00645     int mxe = std::min(bb.upper(0)/bb.stepsize(0),fvec.upper(0)/fvec.stepsize(0));
00646     int mye = std::min(bb.upper(1)/bb.stepsize(1),fvec.upper(1)/fvec.stepsize(1));
00647     int mze = std::min(bb.upper(2)/bb.stepsize(2),fvec.upper(2)/fvec.stepsize(2));
00648     MicroType *f = (MicroType *)fvec.databuffer();
00649     
00650     //std::cout << "BC Nx=" << Nx << "   Ny=" << Ny << "   Nz=" << Nz << std::endl;
00651     if (type==Symmetry) {
00652       switch (side) {
00653       case base::Left:
00654         for (register int k=mzs; k<=mze; k++)
00655           for (register int j=mys; j<=mye; j++) {
00656             if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](8);
00657             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
00658             f[b+base::idx(mxe,j,k,Nx,Ny)](20) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](21);
00659             if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](10);
00660 
00661             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](18);
00662             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](16);
00663           }
00664         break;
00665       case base::Right:
00666         for (register int k=mzs; k<=mze; k++)
00667           for (register int j=mys; j<=mye; j++) {
00668             if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](7);
00669             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
00670             f[b+base::idx(mxs,j,k,Nx,Ny)](21) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](20);
00671             if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](9);
00672 
00673             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](15);
00674             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](17);
00675           }
00676         break;
00677       case base::Bottom:
00678         for (register int k=mzs; k<=mze; k++)
00679           for (register int i=mxs; i<=mxe; i++) {
00680             if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i,mye+1,k,Nx,Ny)](9);
00681             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
00682             f[b+base::idx(i,mye,k,Nx,Ny)](22) = f[b+base::idx(i,mye+1,k,Nx,Ny)](23);
00683             if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i,mye+1,k,Nx,Ny)](8);
00684             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
00685             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
00686           }
00687         break;
00688       case base::Top:
00689         for (register int k=mzs; k<=mze; k++)
00690           for (register int i=mxs; i<=mxe; i++) {
00691             if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i,mys-1,k,Nx,Ny)](7);
00692             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
00693             f[b+base::idx(i,mys,k,Nx,Ny)](23) = f[b+base::idx(i,mys-1,k,Nx,Ny)](22);
00694             if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i,mys-1,k,Nx,Ny)](10);
00695             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k,Nx,Ny)](11);
00696             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k,Nx,Ny)](13);
00697           }
00698         break;
00699       case base::Front:
00700         //std::cout << "SYMMETRY Front Nz=" << Nz << std::endl;
00701         for (register int j=mys; j<=mye; j++)
00702           for (register int i=mxs; i<=mxe; i++) {
00703             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i,j,mze+1,Nx,Ny)](16);
00704             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
00705             f[b+base::idx(i,j,mze,Nx,Ny)](24) = f[b+base::idx(i,j,mze+1,Nx,Ny)](25);
00706             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i,j,mze+1,Nx,Ny)](17);
00707             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j,mze+1,Nx,Ny)](12);
00708             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j,mze+1,Nx,Ny)](13);
00709           }
00710         break;
00711       case base::Back:
00712         //std::cout << "SYMMETRY Back Nz=" << Nz << std::endl;
00713         for (register int j=mys; j<=mye; j++)
00714           for (register int i=mxs; i<=mxe; i++) {
00715             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](15);
00716             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
00717             f[b+base::idx(i,j,mzs,Nx,Ny)](25) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](24);
00718             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](18);
00719             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](11);
00720             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](14);
00721           }
00722         break;
00723       }
00724     }
00725     
00726     else if (type==SlipWall) {
00727       switch (side) {
00728       case base::Left:
00729         //std::cout << "S Left Nz=" << Nz << std::endl;
00730         for (register int k=mzs; k<=mze; k++)
00731           for (register int j=mys; j<=mye; j++) {
00732             if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](10);
00733             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
00734             f[b+base::idx(mxe,j,k,Nx,Ny)](20) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](21);
00735             if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](8);
00736             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18);
00737             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16);
00738           }
00739         break;
00740       case base::Right:
00741         //std::cout << "S Right Nz=" << Nz << std::endl;
00742         for (register int k=mzs; k<=mze; k++)
00743           for (register int j=mys; j<=mye; j++) {
00744             if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](7);
00745             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
00746             f[b+base::idx(mxs,j,k,Nx,Ny)](21) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](20);
00747             if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](9);
00748             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15);
00749             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17);
00750           }
00751         break;
00752       case base::Bottom:
00753         //std::cout << "S Bottom Nz=" << Nz << std::endl;
00754         for (register int k=mzs; k<=mze; k++)
00755           for (register int i=mxs; i<=mxe; i++) {
00756             if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i-1,mye+1,k,Nx,Ny)](9);
00757             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
00758             f[b+base::idx(i,mye,k,Nx,Ny)](22) = f[b+base::idx(i,mye+1,k,Nx,Ny)](23);
00759             if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](8);
00760             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
00761             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
00762           }
00763         break;
00764       case base::Top:
00765         //std::cout << "S Top Nz=" << Nz << std::endl;
00766         for (register int k=mzs; k<=mze; k++)
00767           for (register int i=mxs; i<=mxe; i++) {
00768             if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](7);
00769             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
00770             f[b+base::idx(i,mys,k,Nx,Ny)](23) = f[b+base::idx(i,mys-1,k,Nx,Ny)](22);
00771             if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](10);
00772             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11);
00773             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13);
00774           }
00775         break;
00776       case base::Front:
00777         //std::cout << "S Front Nz=" << Nz << std::endl;
00778         for (register int j=mys; j<=mye; j++)
00779           for (register int i=mxs; i<=mxe; i++) {
00780             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i-1,j,mze+1,Nx,Ny)](17);
00781             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
00782             f[b+base::idx(i,j,mze,Nx,Ny)](24) = f[b+base::idx(i,j,mze+1,Nx,Ny)](25);
00783             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i+1,j,mze+1,Nx,Ny)](16);
00784             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13);
00785             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12);
00786           }
00787         break;
00788       case base::Back:
00789         //std::cout << "S Back Nz=" << Nz << std::endl;
00790         for (register int j=mys; j<=mye; j++)
00791           for (register int i=mxs; i<=mxe; i++) {
00792             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](15);
00793             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
00794             f[b+base::idx(i,j,mzs,Nx,Ny)](25) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](24);
00795             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](18);
00796             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11);
00797             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14);
00798           }
00799         break;
00800       }
00801     }
00802 
00803     else if (type==NoSlipWall) {
00804       switch (side) {
00805       case base::Left:
00806         //std::cout << "NS Left Nz=" << Nz << std::endl;
00807         for (register int k=mzs; k<=mze; k++)
00808           for (register int j=mys; j<=mye; j++) {
00809             if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](10);
00810             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
00811             f[b+base::idx(mxe,j,k,Nx,Ny)](20) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](21);
00812             if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](8);
00813             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18);
00814             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16);
00815           }
00816         break;
00817       case base::Right:
00818         //std::cout << "NS Right Nz=" << Nz << std::endl;
00819         for (register int k=mzs; k<=mze; k++)
00820           for (register int j=mys; j<=mye; j++) {
00821             if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](7);
00822             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
00823             f[b+base::idx(mxs,j,k,Nx,Ny)](21) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](20);
00824             if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](9);
00825             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15);
00826             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17);
00827           }
00828         break;
00829       case base::Bottom:
00830         //std::cout << "NS Bottom Nz=" << Nz << std::endl;
00831         for (register int k=mzs; k<=mze; k++)
00832           for (register int i=mxs; i<=mxe; i++) {
00833             if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i-1,mye+1,k,Nx,Ny)](9);
00834             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
00835             f[b+base::idx(i,mye,k,Nx,Ny)](22) = f[b+base::idx(i,mye+1,k,Nx,Ny)](23);
00836             if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](8);
00837             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
00838             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
00839           }
00840         break;
00841       case base::Top:
00842         //std::cout << "NS Top Nz=" << Nz << std::endl;
00843         for (register int k=mzs; k<=mze; k++)
00844           for (register int i=mxs; i<=mxe; i++) {
00845             if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](7);
00846             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
00847             f[b+base::idx(i,mys,k,Nx,Ny)](23) = f[b+base::idx(i,mys-1,k,Nx,Ny)](22);
00848             if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](10);
00849             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11);
00850             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13);
00851           }
00852         break;
00853       case base::Front:
00854         //std::cout << "NS Front Nz=" << Nz << std::endl;
00855         for (register int j=mys; j<=mye; j++)
00856           for (register int i=mxs; i<=mxe; i++) {
00857             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i-1,j,mze+1,Nx,Ny)](17);
00858             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
00859             f[b+base::idx(i,j,mze,Nx,Ny)](24) = f[b+base::idx(i,j,mze+1,Nx,Ny)](25);
00860             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i+1,j,mze+1,Nx,Ny)](16);
00861             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13);
00862             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12);
00863           }
00864         break;
00865       case base::Back:
00866         //std::cout << "NS Back Nz=" << Nz << std::endl;
00867         for (register int j=mys; j<=mye; j++)
00868           for (register int i=mxs; i<=mxe; i++) {
00869             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](15);
00870             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
00871             f[b+base::idx(i,j,mzs,Nx,Ny)](25) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](24);
00872             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](18);
00873             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11);
00874             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14);
00875           }
00876         break;
00877       }
00878     }
00879 
00880     else if (type==Inlet) {
00881       if (aux==0 || naux<=0) return;
00882       DataType a0=S0*aux[0], a1=0., a2=0.;
00883       if (naux>1) {
00884         a1 = S0*aux[1];
00885         a2 = S0*aux[2];
00886       }
00887       if (scaling==base::Physical) {
00888         a0 /= U0;
00889         a1 /= U0;
00890         a2 /= U0;
00891       }
00892       switch (side) {
00893       case base::Left:
00894         for (register int k=mzs; k<=mze; k++)
00895           for (register int j=mys; j<=mye; j++) {
00896             MacroType q = MacroVariables(f[b+base::idx(mxe+1,j,k,Nx,Ny)]);
00897             q(1) = a0;
00898             if (naux>1) {
00899               q(2) = a1;
00900               q(3) = a2;
00901             }
00902             f[b+base::idx(mxe,j,k,Nx,Ny)] = Equilibrium(q);
00903           }
00904         break;
00905       case base::Right:
00906         for (register int k=mzs; k<=mze; k++)
00907           for (register int j=mys; j<=mye; j++) {
00908             MacroType q = MacroVariables(f[b+base::idx(mxs-1,j,k,Nx,Ny)]);
00909             q(1) = a0;
00910             if (naux>1) {
00911               q(2) = a1;
00912               q(3) = a2;
00913             }
00914             f[b+base::idx(mxs,j,k,Nx,Ny)] = Equilibrium(q);
00915           }
00916         break;
00917       case base::Bottom:
00918         for (register int k=mzs; k<=mze; k++)
00919           for (register int i=mxs; i<=mxe; i++) {
00920             MacroType q = MacroVariables(f[b+base::idx(i,mye+1,k,Nx,Ny)]);
00921             if (naux==1)
00922               q(2) = a0;
00923             else {
00924               q(1) = a0;
00925               q(2) = a1;
00926               q(3) = a2;
00927             }
00928             f[b+base::idx(i,mye,k,Nx,Ny)] = Equilibrium(q);
00929           }
00930         break;
00931       case base::Top:
00932         for (register int k=mzs; k<=mze; k++)
00933           for (register int i=mxs; i<=mxe; i++) {
00934             MacroType q = MacroVariables(f[b+base::idx(i,mys-1,k,Nx,Ny)]);
00935             if (naux==1)
00936               q(2) = a0;
00937             else {
00938               q(1) = a0;
00939               q(2) = a1;
00940               q(3) = a2;
00941             }
00942             f[b+base::idx(i,mys,k,Nx,Ny)] = Equilibrium(q);
00943           }
00944         break;
00945       case base::Front:
00946         for (register int j=mys; j<=mye; j++)
00947           for (register int i=mxs; i<=mxe; i++) {
00948             MacroType q = MacroVariables(f[b+base::idx(i,j,mze+1,Nx,Ny)]);
00949             if (naux==1)
00950               q(3) = a0;
00951             else {
00952               q(1) = a1;
00953               q(2) = a2;
00954               q(3) = a0;
00955             }
00956             f[b+base::idx(i,j,mze+1,Nx,Ny)] = Equilibrium(q);
00957           }
00958         break;
00959       case base::Back:
00960         for (register int j=mys; j<=mye; j++)
00961           for (register int i=mxs; i<=mxe; i++) {
00962             MacroType q = MacroVariables(f[b+base::idx(i,j,mzs-1,Nx,Ny)]);
00963             if (naux==1)
00964               q(3) = a0;
00965             else {
00966               q(1) = a1;
00967               q(2) = a2;
00968               q(3) = a0;
00969             }
00970             f[b+base::idx(i,j,mzs-1,Nx,Ny)] = Equilibrium(q);
00971           }
00972         break;
00973       }
00974     }
00975 
00976     else if (type==Outlet) {
00977       switch (side) {
00978       case base::Left:
00979         for (register int k=mzs; k<=mze; k++)
00980           for (register int j=mys; j<=mye; j++) {
00981             MacroType q = MacroVariables(f[b+base::idx(mxe+1,j,k,Nx,Ny)]);
00982             if (q(0)>0) f[b+base::idx(mxe,j,k,Nx,Ny)] = f[b+base::idx(mxe+1,j,k,Nx,Ny)]/q(0);
00983             //f[b+base::idx(mxe,j,k,Nx,Ny)] = f[b+base::idx(mxe+1,j,k,Nx,Ny)];
00984           }
00985         break;
00986       case base::Right:
00987         for (register int k=mzs; k<=mze; k++)
00988           for (register int j=mys; j<=mye; j++) {
00989             MacroType q = MacroVariables(f[b+base::idx(mxs-1,j,k,Nx,Ny)]);
00990             if (q(0)>0) f[b+base::idx(mxs,j,k,Nx,Ny)] = f[b+base::idx(mxs-1,j,k,Nx,Ny)]/q(0);
00991             //f[b+base::idx(mxs,j,k,Nx,Ny)] = f[b+base::idx(mxs-1,j,k,Nx,Ny)];
00992           }
00993         break;
00994       case base::Bottom:
00995         for (register int k=mzs; k<=mze; k++)
00996           for (register int i=mxs; i<=mxe; i++) {
00997             MacroType q = MacroVariables(f[b+base::idx(i,mye+1,k,Nx,Ny)]);
00998             if (q(0)>0) f[b+base::idx(i,mye,k,Nx,Ny)] = f[b+base::idx(i,mye+1,k,Nx,Ny)]/q(0);
00999             //f[b+base::idx(i,mye,k,Nx,Ny)] = f[b+base::idx(i,mye+1,k,Nx,Ny)];
01000           }
01001         break;
01002       case base::Top:
01003         for (register int k=mzs; k<=mze; k++)
01004           for (register int i=mxs; i<=mxe; i++) {
01005             MacroType q = MacroVariables(f[b+base::idx(i,mys-1,k,Nx,Ny)]);
01006             if (q(0)>0) f[b+base::idx(i,mys,k,Nx,Ny)] = f[b+base::idx(i,mys-1,k,Nx,Ny)]/q(0);
01007             //f[b+base::idx(i,mys,k,Nx,Ny)] = f[b+base::idx(i,mys-1,k,Nx,Ny)];
01008           }
01009         break;
01010       case base::Front:
01011         for (register int j=mys; j<=mye; j++)
01012           for (register int i=mxs; i<=mxe; i++) {
01013             MacroType q = MacroVariables(f[b+base::idx(i,j,mze+1,Nx,Ny)]);
01014             if (q(0)>0) f[b+base::idx(i,j,mze,Nx,Ny)] = f[b+base::idx(i,j,mze+1,Nx,Ny)]/q(0);
01015             //f[b+base::idx(i,j,mze,Nx,Ny)] = f[b+base::idx(i,j,mze+1,Nx,Ny)];
01016           }
01017         break;
01018       case base::Back:
01019         for (register int j=mys; j<=mye; j++)
01020           for (register int i=mxs; i<=mxe; i++) {
01021             MacroType q = MacroVariables(f[b+base::idx(i,j,mzs-1,Nx,Ny)]);
01022             if (q(0)>0) f[b+base::idx(i,j,mzs,Nx,Ny)] = f[b+base::idx(i,j,mzs-1,Nx,Ny)]/q(0);
01023             //f[b+base::idx(i,j,mzs,Nx,Ny)] = f[b+base::idx(i,j,mzs-1,Nx,Ny)];
01024           }
01025         break;
01026       }
01027     }
01028     
01029     // (Succi pg. 90 and Chen_Martinez_Mei_PhysFluids_8_2527)
01030     else if (type==Pressure) {
01031       if (aux==0 || naux<=0) return;
01032       DataType a0=aux[0];
01033       if (scaling==base::Physical)
01034         a0 /= R0;
01035       switch (side) {
01036       case base::Left:
01037         for (register int k=mzs; k<=mze; k++)
01038           for (register int j=mys; j<=mye; j++) {
01039             MacroType q = MacroVariables(f[b+base::idx(mxe+1,j,k,Nx,Ny)]);
01040             q(0) = a0;
01041             f[b+base::idx(mxe,j,k,Nx,Ny)] = Equilibrium(q);
01042           }
01043         break;
01044       case base::Right:
01045         for (register int k=mzs; k<=mze; k++)
01046           for (register int j=mys; j<=mye; j++) {
01047             MacroType q = MacroVariables(f[b+base::idx(mxs-1,j,k,Nx,Ny)]);
01048             q(0) = a0;
01049             f[b+base::idx(mxs,j,k,Nx,Ny)] = Equilibrium(q);
01050           }
01051         break;
01052       case base::Bottom:
01053         for (register int k=mzs; k<=mze; k++)
01054           for (register int i=mxs; i<=mxe; i++) {
01055             MacroType q = MacroVariables(f[b+base::idx(i,mye+1,k,Nx,Ny)]);
01056             q(0) = a0;
01057             f[b+base::idx(i,mye,k,Nx,Ny)] = Equilibrium(q);
01058           }
01059         break;
01060       case base::Top:
01061         for (register int k=mzs; k<=mze; k++)
01062           for (register int i=mxs; i<=mxe; i++) {
01063             MacroType q = MacroVariables(f[b+base::idx(i,mys-1,k,Nx,Ny)]);
01064             q(0) = a0;
01065             f[b+base::idx(i,mys,k,Nx,Ny)] = Equilibrium(q);
01066           }
01067         break;
01068       case base::Front:
01069         for (register int j=mys; j<=mye; j++)
01070           for (register int i=mxs; i<=mxe; i++) {
01071             MacroType q = MacroVariables(f[b+base::idx(i,j,mze+1,Nx,Ny)]);
01072             q(0) = a0;
01073             f[b+base::idx(i,j,mze+1,Nx,Ny)] = Equilibrium(q);
01074           }
01075         break;
01076       case base::Back:
01077         for (register int j=mys; j<=mye; j++)
01078           for (register int i=mxs; i<=mxe; i++) {
01079             MacroType q = MacroVariables(f[b+base::idx(i,j,mzs-1,Nx,Ny)]);
01080             q(0) = a0;
01081             f[b+base::idx(i,j,mzs-1,Nx,Ny)] = Equilibrium(q);
01082           }
01083         break;
01084       }
01085     }
01086     
01087     else if (type==SlidingWall) {
01088       if (aux==0 || naux<=0) return;
01089       if (aux==0 || naux<=0) return;
01090       DataType a0=S0*aux[0];
01091       if (scaling==base::Physical)
01092         a0 /= U0;
01093       switch (side) {
01094       case base::Left:
01095         for (register int k=mzs; k<=mze; k++)
01096           for (register int j=mys; j<=mye; j++) {
01097             MacroType q = MacroVariables(f[b+base::idx(mxe+1,j,k,Nx,Ny)]);
01098             DataType rd1 = f[b+base::idx(mxe+1,j,k,Nx,Ny)](10), rd2 = f[b+base::idx(mxe+1,j,k,Nx,Ny)](8);
01099             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01100             DataType pw = DataType(1.)-qw;
01101             if (j<mye) f[b+base::idx(mxe,j+1,k,Nx,Ny)](9) = pw*rd1+qw*rd2;
01102             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
01103             if (j>mys) f[b+base::idx(mxe,j-1,k,Nx,Ny)](7) = qw*rd1+pw*rd2;
01104 
01105             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18);
01106             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16);
01107           }
01108         break;
01109       case base::Right:
01110         for (register int k=mzs; k<=mze; k++)
01111           for (register int j=mys; j<=mye; j++) {
01112             MacroType q = MacroVariables(f[b+base::idx(mxs-1,j,k,Nx,Ny)]);
01113             DataType rd1 = f[b+base::idx(mxs-1,j,k,Nx,Ny)](7), rd2 = f[b+base::idx(mxs-1,j,k,Nx,Ny)](9);
01114             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01115             DataType pw = DataType(1.)-qw;
01116             if (j<mye) f[b+base::idx(mxs,j+1,k,Nx,Ny)](8) = pw*rd1+qw*rd2;
01117             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
01118             if (j>mys) f[b+base::idx(mxs,j-1,k,Nx,Ny)](10) = qw*rd1+pw*rd2;
01119 
01120             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15);
01121             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17);
01122           }
01123         break;
01124       case base::Bottom:
01125         for (register int k=mzs; k<=mze; k++)
01126           for (register int i=mxs; i<=mxe; i++) {
01127             MacroType q = MacroVariables(f[b+base::idx(i,mye+1,k,Nx,Ny)]);
01128             DataType rd1 = f[b+base::idx(i,mye+1,k,Nx,Ny)](9), rd2 = f[b+base::idx(i,mye+1,k,Nx,Ny)](8);
01129             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01130             DataType pw = DataType(1.)-qw;
01131             if (i<mxe) f[b+base::idx(i+1,mye,k,Nx,Ny)](10) = pw*rd1+qw*rd2;
01132             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
01133             if (i>mxs) f[b+base::idx(i-1,mye,k,Nx,Ny)](7) = qw*rd1+pw*rd2;
01134 
01135             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
01136             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
01137           }
01138         break;
01139       case base::Top:
01140         for (register int k=mzs; k<=mze; k++)
01141           for (register int i=mxs; i<=mxe; i++) {
01142             MacroType q = MacroVariables(f[b+base::idx(i,mys-1,k,Nx,Ny)]);
01143             DataType rd1 = f[b+base::idx(i,mys-1,k,Nx,Ny)](7), rd2 = f[b+base::idx(i,mys-1,k,Nx,Ny)](10);
01144             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01145             DataType pw = DataType(1.)-qw;
01146             if (i<mxe) f[b+base::idx(i+1,mys,k,Nx,Ny)](8) = pw*rd1+qw*rd2;
01147             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
01148             if (i>mxs) f[b+base::idx(i-1,mys,k,Nx,Ny)](9) = qw*rd1+pw*rd2;
01149 
01150             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11);
01151             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13);
01152           }
01153         break;
01154       case base::Front:
01155         for (register int j=mys; j<=mye; j++)
01156           for (register int i=mxs; i<=mxe; i++) {
01157             MacroType q = MacroVariables(f[b+base::idx(i,j,mze+1,Nx,Ny)]);
01158             DataType rd1 = f[b+base::idx(i,j,mze+1,Nx,Ny)](7), rd2 = f[b+base::idx(i,j,mze+1,Nx,Ny)](10);
01159             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01160             DataType pw = DataType(1.)-qw;
01161             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](18) = pw*rd1+qw*rd2;
01162             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
01163             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](15) = qw*rd1+pw*rd2;
01164 
01165             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13);
01166             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12);
01167           }
01168         break;
01169       case base::Back:
01170         for (register int j=mys; j<=mye; j++)
01171           for (register int i=mxs; i<=mxe; i++) {
01172             MacroType q = MacroVariables(f[b+base::idx(i,j,mzs-1,Nx,Ny)]);
01173             DataType rd1 = f[b+base::idx(i,j,mzs-1,Nx,Ny)](7), rd2 = f[b+base::idx(i,j,mzs-1,Nx,Ny)](10);
01174             DataType qw = (q(0)/DataType(6.)*a0)/(rd1-rd2);
01175             DataType pw = DataType(1.)-qw;
01176             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = pw*rd1+qw*rd2;
01177             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
01178             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = qw*rd1+pw*rd2;
01179 
01180             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11);
01181             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14);
01182           }
01183         break;
01184       }
01185     }
01186 
01187     // (Z.Guo, B. Shi and C.Zheng - A coupled lattice BGK model for the boussinesq equations)     
01188     else if (type==ExtrapolationEquilibrium) {
01189       switch (side) {
01190       case base::Left:
01191         for (register int k=mzs; k<=mze; k++) 
01192           for (register int j=mys; j<=mye; j++) {
01193           MacroType q = MacroVariables(f[b+base::idx(mxe+1,j,k,Nx,Ny)]);
01194           MacroType qBC = q;
01195           if (aux==0 || naux<=0) return;
01196           for(int i=0; i<=4; i++){
01197                 if(aux[i] != 0){
01198                         if(i==0) qBC(i) = aux[i+5]/P0;
01199                         else if(i>0 && i<4) qBC(i) = aux[i+5]/(U0/S0);
01200                         else qBC(i)=(aux[i+5]-Tpmin)/Temp0;
01201                 }
01202           }
01203 
01204           f[b+base::idx(mxe,j,k,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(mxe+1,j,k,Nx,Ny)]-Equilibrium(q);
01205         }
01206         break;
01207 
01208      case base::Right:
01209         for (register int k=mzs; k<=mze; k++) 
01210           for (register int j=mys; j<=mye; j++) {
01211           MacroType q = MacroVariables(f[b+base::idx(mxs-1,j,k,Nx,Ny)]);
01212           MacroType qBC = q;
01213           if (aux==0 || naux<=0) return;
01214           for(int i=0; i<=4; i++){
01215                 if(aux[i] != 0){
01216                         if(i==0) qBC(i) = aux[i+5]/P0;
01217                         else if(i>0 && i<4) qBC(i) = aux[i+5]/(U0/S0);
01218                         else qBC(i)=(aux[i+5]-Tpmin)/Temp0;
01219                 }
01220           }
01221 
01222           f[b+base::idx(mxs,j,k,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(mxs-1,j,k,Nx,Ny)]-Equilibrium(q);
01223         }
01224         break;
01225 
01226       case base::Bottom:
01227         for (register int k=mzs; k<=mze; k++)
01228           for (register int i=mxs; i<=mxe; i++) {
01229             MacroType q = MacroVariables(f[b+base::idx(i,mye+1,k,Nx,Ny)]);
01230             MacroType qBC = q;
01231             if (aux==0 || naux<=0) return;
01232           for(int j=0; j<=4; j++){
01233                 if(aux[j] != 0){
01234                         if(j==0) qBC(j) = aux[j+5]/P0;
01235                         else if (j>0 && j<4) qBC(j) = aux[j+5]/(U0/S0);
01236                         else qBC(j)=(aux[j+5]-Tpmin)/Temp0;
01237                 }
01238           }
01239 
01240           f[b+base::idx(i,mye,k,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(i,mye+1,k,Nx,Ny)]-Equilibrium(q);
01241          }
01242         break;
01243 
01244       case base::Top:
01245         for (register int k=mzs; k<=mze; k++)
01246           for (register int i=mxs; i<=mxe; i++) {
01247             MacroType q = MacroVariables(f[b+base::idx(i,mys-1,k,Nx,Ny)]);
01248             MacroType qBC = q;
01249             if (aux==0 || naux<=0) return;
01250           for(int j=0; j<=4; j++){
01251                 if(aux[j] != 0){
01252                         if(j==0) qBC(j) = aux[j+5]/P0;
01253                         else if (j>0 && j<4) qBC(j) = aux[j+5]/(U0/S0);
01254                         else qBC(j)=(aux[j+5]-Tpmin)/Temp0;
01255                 }
01256           }
01257 
01258           f[b+base::idx(i,mys,k,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(i,mys-1,k,Nx,Ny)]-Equilibrium(q);
01259           }
01260         break;
01261 
01262       case base::Front:
01263         for (register int j=mys; j<=mye; j++) 
01264           for (register int i=mxs; i<=mxe; i++) {
01265             MacroType q = MacroVariables(f[b+base::idx(i,j,mze+1,Nx,Ny)]);
01266             MacroType qBC = q;
01267           if (aux==0 || naux<=0) return;
01268           for(int k=0; k<=4; k++){
01269                 if(aux[k] != 0){
01270                         if(k==0) qBC(k) = aux[k+5]/P0;
01271                         else if (k>0 && k<4) qBC(k) = aux[k+5]/(U0/S0);
01272                         else qBC(k)=(aux[k+5]-Tpmin)/Temp0;
01273                 }
01274           }
01275 
01276           f[b+base::idx(i,j,mze,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(i,j,mze+1,Nx,Ny)]-Equilibrium(q);
01277 
01278         }
01279         break;
01280       case base::Back:
01281         for (register int j=mys; j<=mye; j++) 
01282           for (register int i=mxs; i<=mxe; i++) {
01283             MacroType q = MacroVariables(f[b+base::idx(i,j,mzs-1,Nx,Ny)]);
01284             MacroType qBC = q;
01285           if (aux==0 || naux<=0) return;
01286           for(int k=0; k<=4; k++){
01287                 if(aux[k] != 0){
01288                         if(k==0) qBC(k) = aux[k+5]/P0;
01289                         else if (k>0 && k<4) qBC(k) = aux[k+5]/(U0/S0);
01290                         else qBC(k)=(aux[k+5]-Tpmin)/Temp0;
01291                 }
01292           }
01293 
01294           f[b+base::idx(i,j,mzs,Nx,Ny)] = Equilibrium(qBC)+f[b+base::idx(i,j,mzs-1,Nx,Ny)]-Equilibrium(q);        
01295         }
01296         break;
01297       }
01298     }
01299 
01300    else if (type==SlipWallTemperature) {
01301       switch (side) {
01302       case base::Left:
01303         for (register int k=mzs; k<=mze; k++)
01304           for (register int j=mys; j<=mye; j++) {
01305             MacroType qBC;
01306             qBC(4) = (aux[0]-Tpmin)/Temp0;
01307             MicroType gBC = Equilibrium(qBC);
01308             if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](10);
01309             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
01310             f[b+base::idx(mxe,j,k,Nx,Ny)](20) = gBC(20);
01311             if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](8);
01312             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18);
01313             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16);
01314           }
01315         break;
01316       case base::Right:
01317         for (register int k=mzs; k<=mze; k++)
01318           for (register int j=mys; j<=mye; j++) {
01319             MacroType qBC;
01320             qBC(4) = (aux[0]-Tpmin)/Temp0;
01321             MicroType gBC = Equilibrium(qBC);
01322             if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](7);
01323             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
01324             f[b+base::idx(mxs,j,k,Nx,Ny)](21) = gBC(21);
01325             if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](9);
01326             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15);
01327             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17);
01328           }
01329         break;
01330       case base::Bottom:
01331         for (register int k=mzs; k<=mze; k++)
01332           for (register int i=mxs; i<=mxe; i++) {
01333             MacroType qBC;
01334             qBC(4) = (aux[0]-Tpmin)/Temp0;
01335             MicroType gBC = Equilibrium(qBC);
01336             if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i-1,mye+1,k,Nx,Ny)](9);
01337             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
01338             f[b+base::idx(i,mye,k,Nx,Ny)](22) = gBC(22);
01339             if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](8);
01340             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
01341             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
01342           }
01343         break;
01344       case base::Top:
01345         for (register int k=mzs; k<=mze; k++)
01346           for (register int i=mxs; i<=mxe; i++) {
01347             MacroType qBC;
01348             qBC(4) = (aux[0]-Tpmin)/Temp0;
01349             MicroType gBC = Equilibrium(qBC);
01350             if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](7);
01351             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
01352             f[b+base::idx(i,mys,k,Nx,Ny)](23) = gBC(23);
01353             if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](10);
01354             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11);
01355             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13);
01356           }
01357         break;
01358       case base::Front:
01359         for (register int j=mys; j<=mye; j++)
01360           for (register int i=mxs; i<=mxe; i++) {
01361             MacroType qBC;
01362             qBC(4) = (aux[0]-Tpmin)/Temp0;
01363             MicroType gBC = Equilibrium(qBC);
01364             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i-1,j,mze+1,Nx,Ny)](17);
01365             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
01366             f[b+base::idx(i,j,mze,Nx,Ny)](24) = gBC(24);
01367             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i+1,j,mze+1,Nx,Ny)](16);
01368             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13);
01369             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12);
01370           }
01371         break;
01372       case base::Back:
01373         for (register int j=mys; j<=mye; j++)
01374           for (register int i=mxs; i<=mxe; i++) {
01375             MacroType qBC;
01376             qBC(4) = (aux[0]-Tpmin)/Temp0;
01377             MicroType gBC = Equilibrium(qBC);
01378             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](15);
01379             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
01380             f[b+base::idx(i,j,mzs,Nx,Ny)](25) = gBC(25);
01381             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](18);
01382             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11);
01383             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14);
01384           }
01385         break;
01386       }
01387     }
01388 
01389     else if (type==NoSlipWallTemperature) {
01390       switch (side) {
01391       case base::Left:
01392         for (register int k=mzs; k<=mze; k++)
01393           for (register int j=mys; j<=mye; j++) {
01394             MacroType qBC;
01395             qBC(4) = (aux[0]-Tpmin)/Temp0;
01396             MicroType gBC = Equilibrium(qBC);
01397             if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](10);
01398             f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2);
01399             f[b+base::idx(mxe,j,k,Nx,Ny)](20) = gBC(20);
01400             if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](8);
01401             if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18);
01402             if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16);
01403           }
01404         break;
01405       case base::Right:
01406         for (register int k=mzs; k<=mze; k++)
01407           for (register int j=mys; j<=mye; j++) {
01408             MacroType qBC;
01409             qBC(4) = (aux[0]-Tpmin)/Temp0;
01410             MicroType gBC = Equilibrium(qBC);
01411             if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](7);
01412             f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1);
01413             f[b+base::idx(mxs,j,k,Nx,Ny)](21) = gBC(21);
01414             if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](9);
01415             if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15);
01416             if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17);
01417           }
01418         break;
01419       case base::Bottom:
01420         for (register int k=mzs; k<=mze; k++)
01421           for (register int i=mxs; i<=mxe; i++) {
01422             MacroType qBC;
01423             qBC(4) = (aux[0]-Tpmin)/Temp0;
01424             MicroType gBC = Equilibrium(qBC);
01425             if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i-1,mye+1,k,Nx,Ny)](9);
01426             f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4);
01427             f[b+base::idx(i,mye,k,Nx,Ny)](22) = gBC(22);
01428             if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](8);
01429             if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14);
01430             if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12);
01431           }
01432         break;
01433       case base::Top:
01434         for (register int k=mzs; k<=mze; k++)
01435           for (register int i=mxs; i<=mxe; i++) {
01436             MacroType qBC;
01437             qBC(4) = (aux[0]-Tpmin)/Temp0;
01438             MicroType gBC = Equilibrium(qBC);
01439             if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](7);
01440             f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3);
01441             f[b+base::idx(i,mys,k,Nx,Ny)](23) = gBC(23);
01442             if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](10);
01443             if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11);
01444             if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13);
01445           }
01446         break;
01447       case base::Front:
01448         for (register int j=mys; j<=mye; j++)
01449           for (register int i=mxs; i<=mxe; i++) {
01450             MacroType qBC;
01451             qBC(4) = (aux[0]-Tpmin)/Temp0;
01452             MicroType gBC = Equilibrium(qBC);
01453             if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i-1,j,mze+1,Nx,Ny)](17);
01454             f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6);
01455             f[b+base::idx(i,j,mze,Nx,Ny)](24) = gBC(24);
01456             if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i+1,j,mze+1,Nx,Ny)](16);
01457             if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13);
01458             if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12);
01459           }
01460         break;
01461       case base::Back:
01462         for (register int j=mys; j<=mye; j++)
01463           for (register int i=mxs; i<=mxe; i++) {
01464             MacroType qBC;
01465             qBC(4) = (aux[0]-Tpmin)/Temp0;
01466             MicroType gBC = Equilibrium(qBC);
01467             if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](15);
01468             f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5);
01469             f[b+base::idx(i,j,mzs,Nx,Ny)](25) = gBC(25);
01470             if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](18);
01471             if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11);
01472             if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14);
01473           }
01474         break;
01475       }
01476     }
01477 
01478     else if (type==BounceBackDirichlet) {
01479       switch (side) {
01480       case base::Left:
01481         for (register int k=mzs; k<=mze; k++) 
01482           for (register int j=mys; j<=mye; j++) {
01483           MacroType qBC;
01484           if (aux==0 || naux<=0) return;
01485           
01486           qBC(1) = aux[0]/(U0/S0);
01487           qBC(2) = aux[1]/(U0/S0);
01488           qBC(3) = aux[2]/(U0/S0);
01489           qBC(4) = (aux[3]-Tpmin)/Temp0;
01490 
01491           DataType Force = DataType(1.)/DataType(12.);
01492           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01493 
01494           if (j>mys) f[b+base::idx(mxe,j,k,Nx,Ny)](9) = f[b+base::idx(mxe+1,j-1,k,Nx,Ny)](10)+Force*(qBC(1)-qBC(2));
01495           f[b+base::idx(mxe,j,k,Nx,Ny)](1) = f[b+base::idx(mxe+1,j,k,Nx,Ny)](2)+Force/DataType(2.)*qBC(1);
01496           f[b+base::idx(mxe,j,k,Nx,Ny)](20) = -f[b+base::idx(mxe+1,j,k,Nx,Ny)](21)+ForceT;
01497           if (j<mye) f[b+base::idx(mxe,j,k,Nx,Ny)](7) = f[b+base::idx(mxe+1,j+1,k,Nx,Ny)](8)+Force*(qBC(1)+qBC(2));
01498           if (k>mzs) f[b+base::idx(mxe,j,k,Nx,Ny)](17) = f[b+base::idx(mxe+1,j,k-1,Nx,Ny)](18)+Force*(qBC(1)-qBC(3));
01499           if (k<mze) f[b+base::idx(mxe,j,k,Nx,Ny)](15) = f[b+base::idx(mxe+1,j,k+1,Nx,Ny)](16)+Force*(qBC(1)+qBC(3));        
01500 
01501         }
01502         break;
01503 
01504      case base::Right:
01505         for (register int k=mzs; k<=mze; k++) 
01506           for (register int j=mys; j<=mye; j++) {
01507           MacroType qBC;
01508           if (aux==0 || naux<=0) return;
01509           
01510           qBC(1) = aux[0]/(U0/S0);
01511           qBC(2) = aux[1]/(U0/S0);
01512           qBC(3) = aux[2]/(U0/S0);
01513           qBC(4) = (aux[3]-Tpmin)/Temp0;
01514 
01515           DataType Force = DataType(1.)/DataType(12.);
01516           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01517 
01518           if (j>mys) f[b+base::idx(mxs,j,k,Nx,Ny)](8) = f[b+base::idx(mxs-1,j-1,k,Nx,Ny)](7)+Force*(-qBC(1)-qBC(2));
01519           f[b+base::idx(mxs,j,k,Nx,Ny)](2) = f[b+base::idx(mxs-1,j,k,Nx,Ny)](1)+Force/DataType(2.)*(-qBC(1));
01520           f[b+base::idx(mxs,j,k,Nx,Ny)](21) = -f[b+base::idx(mxs-1,j,k,Nx,Ny)](20)+ForceT;
01521           if (j<mye) f[b+base::idx(mxs,j,k,Nx,Ny)](10) = f[b+base::idx(mxs-1,j+1,k,Nx,Ny)](9)+Force*(-qBC(1)+qBC(2));
01522           if (k>mzs) f[b+base::idx(mxs,j,k,Nx,Ny)](16) = f[b+base::idx(mxs-1,j,k-1,Nx,Ny)](15)+Force*(-qBC(1)-qBC(3));
01523           if (k<mze) f[b+base::idx(mxs,j,k,Nx,Ny)](18) = f[b+base::idx(mxs-1,j,k+1,Nx,Ny)](17)+Force*(-qBC(1)+qBC(3));
01524 
01525         }
01526         break;
01527 
01528       case base::Bottom:
01529         for (register int k=mzs; k<=mze; k++)
01530           for (register int i=mxs; i<=mxe; i++) {
01531           MacroType qBC;
01532           if (aux==0 || naux<=0) return;
01533           
01534           qBC(1) = aux[0]/(U0/S0);
01535           qBC(2) = aux[1]/(U0/S0);
01536           qBC(3) = aux[2]/(U0/S0);
01537           qBC(4) = (aux[3]-Tpmin)/Temp0;
01538 
01539           DataType Force = DataType(1.)/DataType(12.);
01540           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01541 
01542           if (i>mxs) f[b+base::idx(i,mye,k,Nx,Ny)](10) = f[b+base::idx(i-1,mye+1,k,Nx,Ny)](9)+Force*(-qBC(1)+qBC(2));
01543           f[b+base::idx(i,mye,k,Nx,Ny)](3) = f[b+base::idx(i,mye+1,k,Nx,Ny)](4)+Force/DataType(2.)*(qBC(2));
01544           f[b+base::idx(i,mye,k,Nx,Ny)](22) = -f[b+base::idx(i,mye+1,k,Nx,Ny)](23)+ForceT;
01545           if (i<mxe) f[b+base::idx(i,mye,k,Nx,Ny)](7) = f[b+base::idx(i+1,mye+1,k,Nx,Ny)](8)+Force*(qBC(1)+qBC(2));
01546           if (k>mzs) f[b+base::idx(i,mye,k,Nx,Ny)](13) = f[b+base::idx(i,mye+1,k-1,Nx,Ny)](14)+Force*(qBC(2)-qBC(3));
01547           if (k<mze) f[b+base::idx(i,mye,k,Nx,Ny)](11) = f[b+base::idx(i,mye+1,k+1,Nx,Ny)](12)+Force*(qBC(2)+qBC(3));
01548 
01549 
01550          }
01551         break;
01552 
01553       case base::Top:
01554         for (register int k=mzs; k<=mze; k++)
01555           for (register int i=mxs; i<=mxe; i++) {
01556           MacroType qBC;
01557           if (aux==0 || naux<=0) return;
01558           
01559           qBC(1) = aux[0]/(U0/S0);
01560           qBC(2) = aux[1]/(U0/S0);
01561           qBC(3) = aux[2]/(U0/S0);
01562           qBC(4) = (aux[3]-Tpmin)/Temp0;
01563 
01564           DataType Force = DataType(1.)/DataType(12.);
01565           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01566 
01567           if (i>mxs) f[b+base::idx(i,mys,k,Nx,Ny)](8) = f[b+base::idx(i-1,mys-1,k,Nx,Ny)](7)+Force*(-qBC(1)-qBC(2));
01568           f[b+base::idx(i,mys,k,Nx,Ny)](4) = f[b+base::idx(i,mys-1,k,Nx,Ny)](3)+Force/DataType(2.)*(-qBC(2));
01569           f[b+base::idx(i,mys,k,Nx,Ny)](23) = -f[b+base::idx(i,mys-1,k,Nx,Ny)](22)+ForceT;
01570           if (i<mxe) f[b+base::idx(i,mys,k,Nx,Ny)](9) = f[b+base::idx(i+1,mys-1,k,Nx,Ny)](10)+Force*(qBC(1)-qBC(2));
01571           if (k>mzs) f[b+base::idx(i,mys,k,Nx,Ny)](12) = f[b+base::idx(i,mys-1,k-1,Nx,Ny)](11)+Force*(-qBC(2)-qBC(3));
01572           if (k<mze) f[b+base::idx(i,mys,k,Nx,Ny)](14) = f[b+base::idx(i,mys-1,k+1,Nx,Ny)](13)+Force*(-qBC(2)+qBC(3));
01573 
01574 
01575           }
01576         break;
01577 
01578       case base::Front:
01579         for (register int j=mys; j<=mye; j++) 
01580           for (register int i=mxs; i<=mxe; i++) {
01581           MacroType qBC;
01582           if (aux==0 || naux<=0) return;
01583           
01584           qBC(1) = aux[0]/(U0/S0);
01585           qBC(2) = aux[1]/(U0/S0);
01586           qBC(3) = aux[2]/(U0/S0);
01587           qBC(4) = (aux[3]-Tpmin)/Temp0;
01588 
01589           DataType Force = DataType(1.)/DataType(12.);
01590           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01591 
01592           if (i>mxs) f[b+base::idx(i,j,mze,Nx,Ny)](18) = f[b+base::idx(i-1,j,mze+1,Nx,Ny)](17)+Force*(-qBC(1)+qBC(3));
01593           f[b+base::idx(i,j,mze,Nx,Ny)](5) = f[b+base::idx(i,j,mze+1,Nx,Ny)](6)+Force/DataType(2.)*qBC(3);
01594           f[b+base::idx(i,j,mze,Nx,Ny)](24) = -f[b+base::idx(i,j,mze+1,Nx,Ny)](25)+ForceT;
01595           if (i<mxe) f[b+base::idx(i,j,mze,Nx,Ny)](15) = f[b+base::idx(i+1,j,mze+1,Nx,Ny)](16)+Force*(qBC(1)+qBC(3));
01596           if (j>mys) f[b+base::idx(i,j,mze,Nx,Ny)](14) = f[b+base::idx(i,j-1,mze+1,Nx,Ny)](13)+Force*(-qBC(2)+qBC(3));
01597           if (j<mye) f[b+base::idx(i,j,mze,Nx,Ny)](11) = f[b+base::idx(i,j+1,mze+1,Nx,Ny)](12)+Force*(qBC(2)+qBC(3));
01598 
01599         }
01600         break;
01601 
01602       case base::Back:
01603         for (register int j=mys; j<=mye; j++) 
01604           for (register int i=mxs; i<=mxe; i++) {
01605           MacroType qBC;
01606           if (aux==0 || naux<=0) return;
01607           
01608           qBC(1) = aux[0]/(U0/S0);
01609           qBC(2) = aux[1]/(U0/S0);
01610           qBC(3) = aux[2]/(U0/S0);
01611           qBC(4) = (aux[3]-Tpmin)/Temp0;
01612 
01613           DataType Force = DataType(1.)/DataType(12.);
01614           DataType ForceT = (DataType(1.)/DataType(3.))*qBC(4);
01615 
01616           if (i>mxs) f[b+base::idx(i,j,mzs,Nx,Ny)](16) = f[b+base::idx(i-1,j,mzs-1,Nx,Ny)](15)+Force*(-qBC(1)-qBC(3));
01617           f[b+base::idx(i,j,mzs,Nx,Ny)](6) = f[b+base::idx(i,j,mzs-1,Nx,Ny)](5)+Force/DataType(2.)*(-qBC(3));
01618           f[b+base::idx(i,j,mzs,Nx,Ny)](25) = -f[b+base::idx(i,j,mzs-1,Nx,Ny)](24)+ForceT;
01619           if (i<mxe) f[b+base::idx(i,j,mzs,Nx,Ny)](17) = f[b+base::idx(i+1,j,mzs-1,Nx,Ny)](18)+Force*(qBC(1)-qBC(3));
01620           if (j>mys) f[b+base::idx(i,j,mzs,Nx,Ny)](12) = f[b+base::idx(i,j-1,mzs-1,Nx,Ny)](11)+Force*(-qBC(2)-qBC(3));
01621           if (j<mye) f[b+base::idx(i,j,mzs,Nx,Ny)](13) = f[b+base::idx(i,j+1,mzs-1,Nx,Ny)](14)+Force*(qBC(2)-qBC(3));
01622     
01623         }
01624         break;
01625       }
01626     }
01627   }
01628 
01629   virtual void GFMBCStandard(vec_grid_data_type &fvec, const int type, const int& nc, const int* idx,
01630                              const MicroType* f, const point_type* xc, const DataType* distance,
01631                              const point_type* normal, DataType* aux=0, const int naux=0,
01632                              const int scaling=0) const {
01633     if (type==GFMNoSlipWallTemp || type==GFMSlipWallTemp) {
01634       DataType fac = S0;
01635       if (scaling==base::Physical)
01636         fac /= U0;
01637       for (int n=0; n<nc; n++) {
01638         MacroType q=MacroVariables(f[n]);
01639         DataType u=-q(1);
01640         DataType v=-q(2);
01641         DataType w=-q(3);
01642         DataType T= q(4);
01643 
01644         // Add boundary velocities if available
01645         if (naux>=4) {
01646           u += fac*aux[naux*n];
01647           v += fac*aux[naux*n+1];
01648           w += fac*aux[naux*n+2];
01649           T = aux[naux*n+3];
01650         }
01651 
01652         if (type==GFMNoSlipWallTemp) {
01653           // Prescribe entire velocity vector in ghost cells
01654           q(1) += DataType(2.)*u;
01655           q(2) += DataType(2.)*v;
01656           q(3) += DataType(2.)*w;
01657           q(4)  = T;
01658         }
01659         else if (type==GFMSlipWallTemp) {
01660           // Prescribe only normal velocity vector in ghost cells
01661           DataType vl = DataType(2.)*(u*normal[n](0)+v*normal[n](1)+w*normal[n](2));
01662           q(1) += vl*normal[n](0);
01663           q(2) += vl*normal[n](1);
01664           q(3) += vl*normal[n](2);
01665           q(4)  = T;
01666         }
01667         fvec(Coords(base::Dim(),idx+base::Dim()*n)) = Equilibrium(q);
01668       }
01669     }
01670 
01671     else if (type==GFMExtrapolation) {
01672       for (int n=0; n<nc; n++) {
01673         MacroType q=MacroVariables(f[n]);
01674         DataType vl = q(1)*normal[n](0)+q(2)*normal[n](1)+q(3)*normal[n](2);
01675         q(1) = vl*normal[n](0);
01676         q(2) = vl*normal[n](1);
01677         q(3) = vl*normal[n](2);
01678         fvec(Coords(base::Dim(),idx+base::Dim()*n)) = Equilibrium(q);
01679       }
01680     }
01681 
01682     else if (type==GFMWallLaw ) {
01683       DCoords dx = base::GH().worldStep(fvec.stepsize());
01684       DataType fac = S0;
01685       if (scaling==base::Physical)
01686         fac /= U0;
01687 
01688       // DataType BLH = 10.;
01689       DataType yp_ = 0.,  yp = 0., yMax = 50.;
01690       DataType yPlus[3];
01691       int lc_low[3], lc_up[3], yPlus_lc[3];
01692 
01693       // int mxe = fvec.upper(0)/fvec.stepsize(0);
01694       // int mye = fvec.upper(1)/fvec.stepsize(1);
01695       // int mze = fvec.upper(2)/fvec.stepsize(2);
01696 
01697       DataType shear_vel = 1., karman = 0.41, y0 = 1., law = 1.;
01698 
01699       DataType shearStress;
01700       DataType u, v, w, u_, v_, w_, vel0;
01701       // DataType vel1;
01702       MacroType q, q_;
01703       int kMax = 0;
01704 
01705       for (int n=0; n<nc; n++) {
01706 
01708         q=MacroVariables(f[n]);
01709         q_=MacroVariables(f[n]);
01710 
01711         yPlus[0] = (xc[n](0) - DataType(2.)*dx(0)*normal[n](0));
01712         yPlus[1] = (xc[n](1) - DataType(2.)*dx(1)*normal[n](1));
01713         yPlus[2] = (xc[n](2) - DataType(2.)*dx(2)*normal[n](2));
01714 
01715         yPlus_lc[0] = base::GH().localCoords((const DataType *) yPlus )(0);
01716         yPlus_lc[1] = base::GH().localCoords((const DataType *) yPlus )(1);
01717         yPlus_lc[2] = base::GH().localCoords((const DataType *) yPlus )(2);
01718 
01719         lc_low[0] = fvec.lower(0);   lc_low[1] = fvec.lower(1);   lc_low[2] = fvec.lower(2);
01720         lc_up[0] = fvec.upper(0);   lc_up[1] = fvec.upper(1);   lc_up[2] = fvec.upper(2);
01721 
01722         //std::cout << "xc " << xc[n] << " yPlus " << yPlus[0] << " " << yPlus[1] << " " << yPlus[2] << std::endl;
01723 
01724         if ( yPlus_lc[0] >  lc_low[0] ) {
01725           if ( yPlus_lc[1] >  lc_low[1] ) {
01726             if ( yPlus_lc[2] >  lc_low[2] ) {
01727 
01728               if ( yPlus_lc[0] < lc_up[0] ) {
01729                 if ( yPlus_lc[1] <  lc_up[1] ) {
01730                   if ( yPlus_lc[2] <  lc_up[2] ) {
01731                     q=MacroVariables( fvec( base::GH().localCoords((const DataType *) yPlus) ) );
01732                   }
01733                 }
01734               }
01735 
01736             }
01737           }
01738         }
01739 
01740         u_=-q(1);
01741         v_=-q(2);
01742         w_=-q(3);
01743         // vel1 = sqrt(u_*u_+v_*v_+w_*w_);
01744 
01745         q=MacroVariables(f[n]);
01746         u=-q(1);
01747         v=-q(2);
01748         w=-q(3);
01749         vel0 = sqrt(u*u+v*v+w*w);
01750 
01751         u_+=q(1);
01752         v_+=q(2);
01753         w_+=q(3);
01754         vel0 = ( u_*normal[n](0) + v_*normal[n](1) + w_*normal[n](2) );
01755 
01756         u_ =  u_ - vel0 * normal[n](0);
01757         v_ =  v_ - vel0 * normal[n](1);
01758         w_ =  w_ - vel0 * normal[n](2);
01759         vel0 = sqrt(u_*u_ + v_*v_ + w_*w_)*U0/S0;
01760 
01761         shearStress = (DataType(0.5)*vel0/dx(0) * q(0)*R0*GasViscosity() );
01762 
01763         // Add boundary velocities if available
01764         if (naux>=3) {
01765           u += fac*aux[naux*n];
01766           v += fac*aux[naux*n+1];
01767           w += fac*aux[naux*n+2];
01768         }
01769         q(1) += DataType(2.)*u;
01770         q(2) += DataType(2.)*v;
01771         q(3) += DataType(2.)*w;
01772         fvec(Coords(base::Dim(),idx+base::Dim()*n)) = Equilibrium(q);
01773 
01775         shear_vel = std::sqrt( shearStress/(q(0)*R0) );
01776 
01778         y0 = karman/30.;
01779 
01780         //std::cout << n << " vel0 " << vel0 << " vel1 " << vel1  << " shear_vel = " << shear_vel << std::endl;
01781 
01782         if ( shear_vel > 1.e-5 ) {
01783           kMax = (int) std::ceil( (yMax*GasViscosity())/(dx(0)*shear_vel) );
01784 
01785           for (int k=1; k < kMax; k++) {
01786 
01787             yPlus[0] = (xc[n](0) - k*dx(0)*normal[n](0));
01788             yPlus[1] = (xc[n](1) - k*dx(1)*normal[n](1));
01789             yPlus[2] = (xc[n](2) - k*dx(2)*normal[n](2));
01790 
01791             yPlus_lc[0] = base::GH().localCoords((const DataType *) yPlus )(0);
01792             yPlus_lc[1] = base::GH().localCoords((const DataType *) yPlus )(1);
01793             yPlus_lc[2] = base::GH().localCoords((const DataType *) yPlus )(2);
01794 
01795             if ( yPlus_lc[0] >  lc_low[0] ) {
01796               if ( yPlus_lc[1] >  lc_low[1] ) {
01797                 if ( yPlus_lc[2] >  lc_low[2] ) {
01798 
01799                   if ( yPlus_lc[0] < lc_up[0] ) {
01800                     if ( yPlus_lc[1] <  lc_up[1] ) {
01801                       if ( yPlus_lc[2] <  lc_up[2] ) {
01802                         yp = k*dx(0);
01803                         yp_ = yp*shear_vel/GasViscosity();
01804 
01807                         if ( yp_ <= 5.0 ) {
01808                           law = yp_;
01809                         }
01811                         else if (yp_ > 5 && yp_ < 30.0 ) {
01812                           //law = (shear_vel/karman*std::log( yp/y0 ) + yp_)*DataType(0.5);
01813                           law = std::min( yp_ , shear_vel/karman*std::log( yp/y0 ) );
01814 
01815                         }
01817                         else if (yp_ >= 30.0 ) {
01818                           law = shear_vel/karman*std::log( yp/y0 );
01819                         }
01820                         //std::cout << "k = " << k << " yp = " << yp << " shear_vel = " << shear_vel << " yp_ = " << yp_ << " law = " << law << std::endl;
01821                         q_=MacroVariables(f[n]);
01822                         u = law*(-q_(1) + fac*aux[naux*n]);
01823                         v = law*(-q_(2) + fac*aux[naux*n+1]);
01824                         w = law*(-q_(3) + fac*aux[naux*n+2]);
01825 
01826                         q_(1) += DataType(2.)*u;
01827                         q_(2) += DataType(2.)*v;
01828                         q_(3) += DataType(2.)*w;
01829                         fvec( base::GH().localCoords((const DataType *) yPlus) ) = Equilibrium(q_);
01830                       }
01831                     }
01832                   }
01833 
01834 
01835                 }
01836               }
01837             }
01838 
01839           }
01840 
01841         }
01842 
01843       }
01844       //std::cout << "====== WallLaw Done\n";
01845     }
01846 
01847 
01848     else if (type==GFMBounceBack ) {
01849 
01850      DCoords dx = base::GH().worldStep(fvec.stepsize());
01851      DataType fac = S0;
01852      if(scaling==base::Physical) fac/=U0;
01853 
01854       DataType dt_temp = dx(0)*S0/U0;
01855    
01856       //xc : Cell midpoints of the ghost cells
01857       //nc : Number of ghost cells
01858       //normal : normalized normal vectors, pointed inside
01859       //distance: Level-Set distance between ghost cell midpoint and boundary
01860        
01861       DataType distB[3], distBScalar, cosa, leng, d_dist, qNorm, mdx2, mdy2, mdz2, zaehler, nenner, lengXi;
01862         
01863       for (int n=0; n<nc; n++){
01864         distB[0] = (double &)distance[n]*normal[n](0)*dx(0);
01865         distB[1] = (double &)distance[n]*normal[n](1)*dx(1);
01866         distB[2] = (double &)distance[n]*normal[n](2)*dx(2);
01867 
01868         
01869         //std::ofstream deb("debugOut.txt", std::ios::app);
01870 
01871 
01872         //alpha: Angle between discrete velocity direction (Ghostcell) and inner normal direction (Boundary)
01873         //leng: Distance between ghost cell midpoint and curved boundary along discrete velocity direction
01874         //d_dist: Distance between fluid-cellmidpoint and boundary along discrete velocity direction
01875         //qNorm: Normalized length from fluid-cellmidpoint to boundary along discrete velocity direction
01876  
01877         for(int ind=0; ind<base::NMicroVar(); ind++){
01878                 
01879                 mdx2 = mdx[ind]*mdx[ind];
01880                 mdy2 = mdy[ind]*mdy[ind];
01881                 mdz2 = mdz[ind]*mdz[ind];
01882                 zaehler = (distB[0]*mdx[ind]+distB[1]*mdy[ind]+distB[2]*mdz[ind]);
01883                 distBScalar = std::sqrt(std::pow(distB[0],2)+std::pow(distB[1],2)+std::pow(distB[2],2));
01884                 nenner = std::sqrt(mdx2+mdy2+mdz2)*distBScalar;
01885                 lengXi = std::sqrt(mdx2*dx(0)*dx(0)+mdy2*dx(1)*dx(1)+mdz2*dx(2)*dx(2));
01886 
01887                 if(nenner!=0) cosa = zaehler/nenner;
01888                 else cosa = 0;
01889                 if(cosa!=0) {
01890                         leng = distBScalar*(DataType(1.)/cosa);
01891                         d_dist = lengXi-leng;
01892                         qNorm = d_dist/lengXi;
01893                 }
01894                 else {
01895                         leng = 0;
01896                         d_dist = 0;
01897                         qNorm = 0;
01898                 }
01899                 
01900                 if(qNorm>0 && qNorm < std::sqrt(2.)){
01901                 //The positive lengths are important only       
01902                         
01903                         //Two cases: qNorm greater equal or lower than 0.5
01904                         int idxA, idxB;
01905                         if(ind<19){
01906                                 if(ind==0)      idxA=0;
01907                                 else if(ind % 2 == 0 && ind <19) idxA = ind-1;
01908                                 else idxA = ind+1;
01909                         }
01910                         else{
01911                                 if(ind==19) idxA=19;
01912                                 else if(ind % 2 == 0 && ind >19) idxA = ind+1;
01913                                 else idxA = ind-1;
01914                         }
01915 
01916                         //std::cout << "ind = " << ind <<  ", idxA = " << idxA << ", idxB = " << idxB << std::endl;
01917                         idxB=idxA;
01918                         if(qNorm>=DataType(0.5)) idxB=ind;
01919 
01920                         //Calculate Coordinates of needed fluidcell                     
01921                         DataType cn[3], cnA[3], cnB[3];
01922                         cn[0] = xc[n](0);
01923                         cn[1] = xc[n](1);
01924                         cn[2] = xc[n](2);
01925 
01926                         //cnA = cn; //Coords of fluidcell
01927                         cnA[0] = cn[0] + mdx[ind]*dx(0);
01928                         cnA[1] = cn[1] + mdy[ind]*dx(1);
01929                         cnA[2] = cn[2] + mdz[ind]*dx(2);
01930 
01931                         cnB[0] = cnA[0]; //Coords of 2nd fluidcell
01932                         cnB[1] = cnA[1]; 
01933                         cnB[2] = cnA[2]; 
01934 
01935                         if(qNorm<DataType(0.5) && qNorm > DataType(0.)){
01936                                 cnB[0] += mdx[ind]*dx(0);
01937                                 cnB[1] += mdy[ind]*dx(1);
01938                                 cnB[2] += mdz[ind]*dx(2);
01939                         }
01940 
01941                         //Getting the corresponding partial probability distribution functions
01942                         DataType distFuncA, distFuncB;
01943 
01944                         distFuncA = fvec(base::GH().localCoords((const DataType*) cnA))(idxA);
01945                         distFuncB = fvec(base::GH().localCoords((const DataType*) cnB))(idxB);
01946         
01947                         DataType intp1,intp2,intp,q2;
01948                         q2 = DataType(2.)*qNorm;
01949 
01950                         //Using formular from Eitel-Amor for velocity
01951                         if(ind<19){     
01952                                 if(qNorm<DataType(0.5) && qNorm >= DataType(0.)){
01953                                         intp1=q2*distFuncA;
01954                                         intp2=(DataType(1.)-q2)*distFuncB;
01955                                 }
01956                                 else{
01957                                         if(q2!=0){
01958                                                 intp1 = (DataType(1.)/q2)*distFuncA;
01959                                                 intp2 = ((q2-DataType(1.))/q2)*distFuncB;
01960                                         }
01961                                         else{
01962                                         intp1 = DataType(0.);
01963                                         intp2 = intp1;
01964                                         }
01965                                 }
01966                         }
01967                         //Using formular from L. Li et al. for temperature distributions
01968                         else{           
01969                                 if(qNorm<=DataType(0.5) && qNorm >= DataType(0.)){
01970                                         intp1 = -q2*distFuncA;
01971                                         intp2 = (q2-DataType(1.))*distFuncB;
01972                                 }
01973                                 else{
01974                                         if(q2!=0){
01975                                                 intp1 = -(DataType(1.)/q2)*distFuncA;
01976                                                 intp2 = (DataType(1.)-(DataType(1.)/q2))*distFuncB;
01977                                         }
01978                                         else{
01979                                                 intp1 = DataType(0.);
01980                                                 intp2 = intp1;
01981                                         }
01982                                 }
01983                         }
01984 
01985                         intp = intp1+intp2;
01986                         
01987                         fvec(base::GH().localCoords((const DataType *) cn))(ind) = intp;
01988 
01989                         //ADDITION PART FOR EXTERNAL FORCE LIKE VELOCITY OR TEMPERATURE
01990                         //From: Momentum transfer of a Boltzmann-lattice fluid with boundaries - M. Bouzidi et al. (2001) Physics of Fluids
01991 
01992                         if(naux>=3 && ind<19){
01993                                 DataType u = fac*aux[naux*n];
01994                                 DataType v = fac*aux[naux*n+1];
01995                                 DataType w = fac*aux[naux*n+2];
01996         
01997                                 DataType weight;
01998                                 weight = DataType(1.)/DataType(12.);
01999                                 if(ind==0) weight *= 0;
02000                                 else if(ind>=1 && ind<=6) weight *= DataType(2.);
02001         
02002                                 DataType velForce;
02003                                         
02004                                 if(qNorm<DataType(0.5)) velForce = DataType(2.)*weight;
02005                                 else velForce = (DataType(1.)/qNorm)*weight;
02006                                         
02007                                 velForce *= ((mdx[ind]*u)+(mdy[ind]*v)+(mdz[ind]*w));
02008                                 fvec(base::GH().localCoords((const DataType*) cn))(ind) +=velForce;
02009                         }
02010 
02011                         if(naux>=4 && ind>=19){
02012 
02013                                 DataType T = (aux[naux*n+3]-Tpmin)/(Tpmax-Tpmin);
02014                                 DataType TForce = DataType(1.)/DataType(3.);
02015 
02016                                 if(qNorm>DataType(0.5)) TForce /= q2;
02017 
02018                                 fvec(base::GH().localCoords((const DataType*) cn))(ind) +=TForce*T;
02019                         
02020                         }       
02021                 }       
02022         }
02023       }
02024 
02025     }//End GFMBounceBack
02026 
02027   }
02028 
02029   virtual void Output(vec_grid_data_type& fvec, grid_data_type& workvec, const int cnt,
02030                       const int skip_ghosts=1) const {
02031     int Nx = fvec.extents(0), Ny = fvec.extents(1), Nz = fvec.extents(2);
02032     int mxs = base::NGhosts()*skip_ghosts, mys = base::NGhosts()*skip_ghosts, mzs = base::NGhosts()*skip_ghosts;
02033     int mxe = Nx-base::NGhosts()*skip_ghosts-1, mye = Ny-base::NGhosts()*skip_ghosts-1, mze = Nz-base::NGhosts()*skip_ghosts-1;
02034     MicroType *f = (MicroType *)fvec.databuffer();
02035     DataType *work = (DataType *)workvec.databuffer();
02036     DCoords dx = base::GH().worldStep(fvec.stepsize());
02037     DataType dt_temp = dx(0)*S0/U0;
02038 
02039     if (cnt>=1 && cnt<=10) { 
02040       for (register int k=mzs; k<=mze; k++)
02041         for (register int j=mys; j<=mye; j++)
02042           for (register int i=mxs; i<=mxe; i++) {
02043             MacroType q=MacroVariables(f[base::idx(i,j,k,Nx,Ny)]);
02044             switch(cnt) {
02045             case 1:
02046               work[base::idx(i,j,k,Nx,Ny)]=0;
02047               break;
02048             case 2:
02049               work[base::idx(i,j,k,Nx,Ny)]=q(1)*U0/S0;
02050               break;
02051             case 3:
02052               work[base::idx(i,j,k,Nx,Ny)]=q(2)*U0/S0;
02053               break;
02054             case 4:
02055               work[base::idx(i,j,k,Nx,Ny)]=q(3)*U0/S0;
02056               break;
02057             case 6://Temperature
02058               work[base::idx(i,j,k,Nx,Ny)]=q(4)*(Tpmax-Tpmin)+Tpmin;
02059               break;
02060             case 7://Pressure
02061               work[base::idx(i,j,k,Nx,Ny)]=q(0)*P0; 
02062               break;
02063             case 9: {
02064               MicroType feq = Equilibrium(q);     
02065               work[base::idx(i,j,k,Nx,Ny)]=GasViscosity(Omega_LES_Smagorinsky(f[base::idx(i,j,k,Nx,Ny)],feq,q,dt_temp),
02066                                                         GasSpeedofSound(),dt_temp );
02067               break;
02068             }
02069             case 10:
02070               work[base::idx(i,j,k,Nx,Ny)]=std::sqrt(q(1)*q(1)+q(2)*q(2)+q(3)*q(3))*U0/S0;
02071               break;
02072             }     
02073           }
02074     }
02075     else if (cnt>=11 && cnt<=14) {
02076       macro_grid_data_type qgrid(fvec.bbox());
02077       MacroType *q = (MacroType *)qgrid.databuffer();
02078       for (register int k=mzs; k<=mze; k++)
02079         for (register int j=mys; j<=mye; j++)
02080           for (register int i=mxs; i<=mxe; i++) {
02081             q[base::idx(i,j,k,Nx,Ny)]=MacroVariables(f[base::idx(i,j,k,Nx,Ny)]);
02082             q[base::idx(i,j,k,Nx,Ny)](1)*=U0/S0;
02083             q[base::idx(i,j,k,Nx,Ny)](2)*=U0/S0;
02084             q[base::idx(i,j,k,Nx,Ny)](3)*=U0/S0;
02085           }
02086       
02087       if (skip_ghosts==0) {
02088         switch(cnt) {
02089         case 11:
02090           mys+=1; mye-=1; mzs+=1; mze-=1;
02091           break;
02092         case 12:
02093           mxs+=1; mxe-=1; mzs+=1; mze-=1;
02094           break;
02095         case 13:
02096           mxs+=1; mxe-=1; mys+=1; mye-=1; 
02097           break;
02098         case 14:
02099           mxs+=1; mxe-=1; mys+=1; mye-=1; mzs+=1; mze-=1;
02100           break;
02101         }
02102       }
02103 
02104       for (register int k=mzs; k<=mze; k++)
02105         for (register int j=mys; j<=mye; j++)
02106           for (register int i=mxs; i<=mxe; i++) 
02107             switch(cnt) {
02108             case 11: 
02109               work[base::idx(i,j,k,Nx,Ny)]=(q[base::idx(i,j+1,k,Nx,Ny)](3)-q[base::idx(i,j-1,k,Nx,Ny)](3))/(2.*dx(1))-
02110                 (q[base::idx(i,j,k+1,Nx,Ny)](2)-q[base::idx(i,j,k-1,Nx,Ny)](2))/(2.*dx(2));
02111               break;
02112             case 12: 
02113               work[base::idx(i,j,k,Nx,Ny)]=(q[base::idx(i,j,k+1,Nx,Ny)](1)-q[base::idx(i,j,k-1,Nx,Ny)](1))/(2.*dx(2))-
02114                 (q[base::idx(i+1,j,k,Nx,Ny)](3)-q[base::idx(i-1,j,k,Nx,Ny)](3))/(2.*dx(0));
02115               break;
02116             case 13: 
02117               work[base::idx(i,j,k,Nx,Ny)]=(q[base::idx(i+1,j,k,Nx,Ny)](2)-q[base::idx(i-1,j,k,Nx,Ny)](2))/(2.*dx(0))-
02118                 (q[base::idx(i,j+1,k,Nx,Ny)](1)-q[base::idx(i,j-1,k,Nx,Ny)](1))/(2.*dx(1));
02119               break;
02120             case 14:
02121               DataType ox = (q[base::idx(i,j+1,k,Nx,Ny)](3)-q[base::idx(i,j-1,k,Nx,Ny)](3))/(2.*dx(1))-
02122                 (q[base::idx(i,j,k+1,Nx,Ny)](2)-q[base::idx(i,j,k-1,Nx,Ny)](2))/(2.*dx(2));
02123               DataType oy = (q[base::idx(i,j,k+1,Nx,Ny)](1)-q[base::idx(i,j,k-1,Nx,Ny)](1))/(2.*dx(2))-
02124                 (q[base::idx(i+1,j,k,Nx,Ny)](3)-q[base::idx(i-1,j,k,Nx,Ny)](3))/(2.*dx(0));
02125               DataType oz = (q[base::idx(i+1,j,k,Nx,Ny)](2)-q[base::idx(i-1,j,k,Nx,Ny)](2))/(2.*dx(0))-
02126                 (q[base::idx(i,j+1,k,Nx,Ny)](1)-q[base::idx(i,j-1,k,Nx,Ny)](1))/(2.*dx(1));
02127               work[base::idx(i,j,k,Nx,Ny)] = std::sqrt(ox*ox+oy*oy+oz*oz);
02128               break;
02129             }
02130     }
02131   }
02132 
02133   virtual void Input(vec_grid_data_type& fvec, grid_data_type& workvec, const int cnt,
02134                      const int skip_ghosts=1) const {
02135     int Nx = fvec.extents(0), Ny = fvec.extents(1), Nz = fvec.extents(2);
02136     int mxs = base::NGhosts()*skip_ghosts, mys = base::NGhosts()*skip_ghosts, mzs = base::NGhosts()*skip_ghosts;
02137     int mxe = Nx-base::NGhosts()*skip_ghosts-1, mye = Ny-base::NGhosts()*skip_ghosts-1, mze = Nz-base::NGhosts()*skip_ghosts-1;
02138     MicroType *f = (MicroType *)fvec.databuffer();
02139     DataType *work = (DataType *)workvec.databuffer();
02140     DCoords dx = base::GH().worldStep(fvec.stepsize());
02141 
02142     for (register int k=mzs; k<=mze; k++)
02143       for (register int j=mys; j<=mye; j++)
02144         for (register int i=mxs; i<=mxe; i++) {
02145           switch(cnt) {
02146           case 2:
02147             f[base::idx(i,j,k,Nx,Ny)](1)=work[base::idx(i,j,k,Nx,Ny)]/(U0/S0);
02148             break;
02149           case 3:
02150             f[base::idx(i,j,k,Nx,Ny)](2)=work[base::idx(i,j,k,Nx,Ny)]/(U0/S0);
02151             break;
02152           case 4:
02153             f[base::idx(i,j,k,Nx,Ny)](3)=work[base::idx(i,j,k,Nx,Ny)]/(U0/S0);
02154             f[base::idx(i,j,k,Nx,Ny)] = Equilibrium((const MacroType &)f[base::idx(i,j,k,Nx,Ny)]);
02155             break;
02156           case 6://Temperature
02157             f[base::idx(i,j,k,Nx,Ny)](3)=(work[base::idx(i,j,k,Nx,Ny)]-Tpmin)/(Tpmax-Tpmin);
02158             break;
02159           case 7://Pressure
02160             f[base::idx(i,j,k,Nx,Ny)](0)=work[base::idx(i,j,k,Nx,Ny)]/P0;
02161             break;
02162           }
02163         }
02164   }
02165 
02166   virtual int Check(vec_grid_data_type& fvec, const BBox &bb, const double& time,
02167                     const int verbose) const {
02168     int Nx = fvec.extents(0), Ny = fvec.extents(1);
02169     int b = fvec.bottom();
02170     assert (fvec.stepsize(0)==bb.stepsize(0) && fvec.stepsize(1)==bb.stepsize(1));
02171     BBox bbmax = grow(fvec.bbox(),-base::NGhosts());
02172     int mxs = std::max(bb.lower(0)/bb.stepsize(0),bbmax.lower(0)/bbmax.stepsize(0));
02173     int mys = std::max(bb.lower(1)/bb.stepsize(1),bbmax.lower(1)/bbmax.stepsize(1));
02174     int mzs = std::max(bb.lower(2)/bb.stepsize(2),bbmax.lower(2)/bbmax.stepsize(2));
02175     int mxe = std::min(bb.upper(0)/bb.stepsize(0),bbmax.upper(0)/bbmax.stepsize(0));
02176     int mye = std::min(bb.upper(1)/bb.stepsize(1),bbmax.upper(1)/bbmax.stepsize(1));
02177     int mze = std::min(bb.upper(2)/bb.stepsize(2),bbmax.upper(2)/bbmax.stepsize(2));
02178     MicroType *f = (MicroType *)fvec.databuffer();
02179 
02180     //std::cout << "CHECK Nx=" << Nx << "   Ny=" << Ny << "   Nz=" << Nz << std::endl;
02181     int result = 1;
02182     for (register int k=mzs; k<=mze; k++)
02183       for (register int j=mys; j<=mye; j++)
02184         for (register int i=mxs; i<=mxe; i++)
02185           for (register int l=0; l<base::NMicroVar(); l++)
02186             if (!(f[b+base::idx(i-mdx[l],j-mdy[l],k-mdz[l],Nx,Ny)](l)>-1.e37)) {
02187               result = 0;
02188               if (verbose)
02189                 std::cerr << "D3Q19-Check(): f(" << i-mdx[l] << "," << j-mdy[l] << "," << k-mdz[l] << ")(" << l << ")="
02190                           << f[b+base::idx(i-mdx[l],j-mdy[l],k-mdz[l],Nx,Ny)](l) << " " << fvec.bbox() << std::endl;
02191             }
02192     return result;
02193   }
02194 
02195   virtual int NMethodOrder() const { return 2; }
02196 
02197   inline const DataType& L0() const { return base::LengthScale(); }
02198   inline const DataType& T0() const { return base::TimeScale(); }
02199   inline void SetDensityScale(const DataType r0) { R0 = r0; }
02200   inline void SetPressureScale(const DataType p0) { P0 = p0; }
02201   inline void SetVelocityScale(const DataType u0) { U0 = u0; base::T0 = L0()/U0; base::T0 *= S0; }
02202   inline void SetSpeedUp(const DataType s0) { S0 = s0; }
02203   inline virtual void SetTimeScale(const DataType t0) { base::T0 = t0; U0 = L0()/T0(); base::T0 *= S0; }
02204 
02205   inline void SetTemperatureScale(const DataType tpmin, const DataType tpmax) { 
02206     Tpmin = tpmin; Tpmax = tpmax; 
02207     Temp0 = tpmax-tpmin;
02208     Tref = DataType(0.5)*(Tpmax+Tpmin)/Temp0;
02209     //Tref = DataType(0.5);
02210   }
02211 
02212   inline const DataType& DensityScale() const { return R0; }
02213   inline const DataType& PressureScale() const { return P0; }
02214   inline const DataType VelocityScale() const { return U0/S0; }
02215   inline const DataType& TemperatureScale() const { return Temp0; }
02216   // Multiply all velocities and viscosity by S0 to speed up flow artificially, remove this scaling in output
02217   inline const DataType& SpeedUp() const { return S0; }
02218 
02219   // Lattice quantities for the operator
02220   inline DataType LatticeViscosity(const DataType omega) const { return ((DataType(1.)/omega-DataType(0.5))*cs2); }
02221   inline DataType LatticeViscosityT(const DataType omega) const { return ((DataType(1.)/omega-DataType(0.5))*ds2); }
02222   //inline DataType LatticeViscosityT(const DataType omega) const { return ((DataType(1.)/omega-DataType(0.5))*cs2); }
02223   inline DataType LatticeSpeedOfSound() const { return (std::sqrt(cs2)); }
02224   inline DataType LatticeSpeedOfSoundT() const { return (std::sqrt(ds2)); }
02225   //inline DataType LatticeSpeedOfSoundT() const { return (std::sqrt(cs2)); }
02226 
02227   // Physical quantities for the operator
02228   inline void SetGas(DataType pr, DataType rho, DataType nu, DataType cs) {
02229     rhop = rho; nup = nu; csp = cs; cs2p = cs*cs; prp = pr;
02230     SetTimeScale(LatticeSpeedOfSound()/GasSpeedofSound()*L0());
02231     SetPressureScale(prp);
02232   }
02233   inline void SetThermalGas(const DataType tmin, const DataType tmax, const DataType diff, 
02234                             const DataType gp, const DataType betap) {    
02235     nutp = diff;
02236     SetTemperatureScale(tmin,tmax);
02237     //DataType H = width;
02238 
02239     DataType g = gp/(L0()/T0()/T0()); //g in Lattice Coordinates
02240     DataType beta = betap*Temp0; //beta in Lattice Coordinates
02241     gbeta = g*beta;
02242 
02243     //Force input is Rayleigh-Number => Calculate gbeta directly in Lattice
02244     //gbeta = force*LatticeViscosity(Omega(T0()))*LatticeViscosityT(OmegaT(T0()))/(H/L0())/(H/L0())/(H/L0());
02245   }
02246 
02247   inline virtual const DataType Omega(const DataType dt) const { return (cs2p*dt/S0/(nup*S0+cs2p*dt/S0*DataType(0.5))); }
02248   inline virtual const DataType OmegaT(const DataType dt) const { return (dcs2*cs2p*dt/S0/(nutp*S0+dcs2*cs2p*dt/S0*DataType(0.5))); }
02249   //inline virtual const DataType OmegaT(const DataType dt) const { return (cs2p*dt/S0/(nutp*S0+cs2p*dt/S0*DataType(0.5))); }
02250 
02251   inline const DataType Omega_LES_Smagorinsky(const MicroType &f, const MicroType &feq, const MacroType& q,
02252                                               const DataType dt) const {
02253     DataType M2 = 0.0;
02254     //x-y
02255     M2 += (f(7) - feq(7))*(f(7) - feq(7));
02256     M2 += (f(8) - feq(8))*(f(8) - feq(8));
02257     M2 += (f(9) - feq(9))*(f(9) - feq(9));
02258     M2 += (f(10) - feq(10))*(f(10) - feq(10));
02259     //y-z
02260     M2 += (f(11) - feq(11))*(f(11) - feq(11));
02261     M2 += (f(12) - feq(12))*(f(12) - feq(12));
02262     M2 += (f(13) - feq(13))*(f(13) - feq(13));
02263     M2 += (f(14) - feq(14))*(f(14) - feq(14));
02264     //x-z
02265     M2 += (f(15) - feq(15))*(f(15) - feq(15));
02266     M2 += (f(16) - feq(16))*(f(16) - feq(16));
02267     M2 += (f(17) - feq(17))*(f(17) - feq(17));
02268     M2 += (f(18) - feq(18))*(f(18) - feq(18));
02269     M2 = std::sqrt(M2);
02270 
02271     DataType tau = DataType(1.0)/Omega(dt);
02272     DataType om_turb =  (DataType(2.0)/( tau
02273                                          + sqrt(tau*tau + (DataType(18.)*Cs_Smagorinsky*Cs_Smagorinsky*M2)/(R0*q(0)*cs2/S0/S0)) ));
02274 
02275     return ( om_turb );
02276   }
02277   inline const DataType Omega_LES_dynamic(const MicroType &f, const MicroType &feq, const MacroType& q,
02278                                           const DataType dt) const {
02279     DataType M2 = 0.0;
02280     //x-y
02281     M2 += (f(7) - feq(7))*(f(7) - feq(7));
02282     M2 += (f(8) - feq(8))*(f(8) - feq(8));
02283     M2 += (f(9) - feq(9))*(f(9) - feq(9));
02284     M2 += (f(10) - feq(10))*(f(10) - feq(10));
02285     //y-z
02286     M2 += (f(11) - feq(11))*(f(11) - feq(11));
02287     M2 += (f(12) - feq(12))*(f(12) - feq(12));
02288     M2 += (f(13) - feq(13))*(f(13) - feq(13));
02289     M2 += (f(14) - feq(14))*(f(14) - feq(14));
02290     //x-z
02291     M2 += (f(15) - feq(15))*(f(15) - feq(15));
02292     M2 += (f(16) - feq(16))*(f(16) - feq(16));
02293     M2 += (f(17) - feq(17))*(f(17) - feq(17));
02294     M2 += (f(18) - feq(18))*(f(18) - feq(18));
02295     M2 = std::sqrt(M2);
02296 
02297     DataType tau = DataType(1.0)/Omega(dt);
02298     DataType vel = sqrt( q(1)*q(1)+q(2)*q(2)+q(3)*q(3) );
02299     DataType Cs_SmagDYN = DataType(0.5)*L0()*L0()*( (vel*vel/csp*(M2-vel)) / ((M2-vel)*(M2-vel))  );
02300     DataType om_turb =  (DataType(2.0)/( tau
02301                                          + sqrt(tau*tau + (DataType(18.)*Cs_SmagDYN*M2)/(R0*q(0)*cs2/S0/S0)) ));
02302 
02303     return ( om_turb );
02304   }
02305   inline const int TurbulenceType() const { return turbulence; }
02306   inline const DataType& SmagorinskyConstant() { return Cs_Smagorinsky; }
02307   inline const DataType& GasDensity() const { return rhop; }
02308   inline const DataType& GasPressure() const { return prp; }
02309   inline const DataType& GasViscosity() const { return nup; }
02310   inline const DataType& GasViscosityT() const { return nutp; }
02311   inline const DataType& GasSpeedofSound() const { return csp; }
02312   inline const DataType GasViscosity(const DataType omega, const DataType cs, const DataType dt) const
02313   { return ((DataType(1.)/omega-DataType(0.5))*cs*cs*dt/S0/S0); }
02314   inline const DataType GasViscosityT(const DataType omegat, const DataType cs, const DataType dt) const
02315   { return ((DataType(1.)/omegat-DataType(0.5))*dcs2*cs*cs*dt/S0/S0); }
02316   // Quantities for output only
02317   inline void SetGasProp(DataType g, DataType W, DataType R) { gp = g; Wp = W; R = Rp; }
02318 
02319 protected:
02320   DataType cs2, cs22, cssq, ds2, dcs2;
02321   DataType P0, R0, U0, S0, Temp0, prp, rhop, Tpmin, Tpmax, Tref, csp, cs2p, nup, nutp, gbeta, gp, Wp, Rp;
02322   DataType Cs_Smagorinsky, turbulence;
02323   int method[1], mdx[26], mdy[26], mdz[26];
02324 };
02325 
02326 
02327 #endif