00001
00002
00003
00004
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
00240 feq(1) = pre1 + rt1 * (ri - sumsq + u2 + ui);
00241 feq(2) = pre1 + rt1 * (ri - sumsq + u2 - ui);
00242
00243 feq(3) = pre1 + rt1 * (ri - sumsq + v2 + vi);
00244 feq(4) = pre1 + rt1 * (ri - sumsq + v2 - vi);
00245
00246 feq(5) = pre1 + rt1 * (ri - sumsq + w2 + wi);
00247 feq(6) = pre1 + rt1 * (ri - sumsq + w2 - wi);
00248
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
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
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
00265 feq(19) = DataType(0.);
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
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
00478
00479 DCoords dx = base::GH().worldStep(fvec.stepsize());
00480
00481
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
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
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
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
00518 f[base::idx(i,j,k,Nx,Ny)](13) = f[base::idx(i,j-1,k+1,Nx,Ny)](13);
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
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
00528 f[base::idx(i,j,k,Nx,Ny)](11) = f[base::idx(i,j-1,k-1,Nx,Ny)](11);
00529
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
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
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
00549 f[base::idx(i,j,k,Nx,Ny)](14) = f[base::idx(i,j+1,k-1,Nx,Ny)](14);
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
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
00559 f[base::idx(i,j,k,Nx,Ny)](12) = f[base::idx(i,j+1,k+1,Nx,Ny)](12);
00560
00561 f[base::idx(i,j,k,Nx,Ny)](16) = f[base::idx(i+1,j,k+1,Nx,Ny)](16);
00562 }
00563
00564
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
00583
00584 if (type==ConstantMicro) {
00585
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
00595 }
00596
00597 else if (type==ConstantMacro) {
00598
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
00617 }
00618
00619 else if (type==GasAtRest) {
00620
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
00632 }
00633 }
00634
00635
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01024 }
01025 break;
01026 }
01027 }
01028
01029
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
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
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
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
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
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
01694
01695
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
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
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
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
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
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
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
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
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
01857
01858
01859
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
01870
01871
01872
01873
01874
01875
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
01902
01903
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
01917 idxB=idxA;
01918 if(qNorm>=DataType(0.5)) idxB=ind;
01919
01920
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
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];
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
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
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
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
01990
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 }
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:
02058 work[base::idx(i,j,k,Nx,Ny)]=q(4)*(Tpmax-Tpmin)+Tpmin;
02059 break;
02060 case 7:
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:
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:
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
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
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
02217 inline const DataType& SpeedUp() const { return S0; }
02218
02219
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
02223 inline DataType LatticeSpeedOfSound() const { return (std::sqrt(cs2)); }
02224 inline DataType LatticeSpeedOfSoundT() const { return (std::sqrt(ds2)); }
02225
02226
02227
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
02238
02239 DataType g = gp/(L0()/T0()/T0());
02240 DataType beta = betap*Temp0;
02241 gbeta = g*beta;
02242
02243
02244
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
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
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
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
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
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
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
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
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