save unfinished work; to be built and tested
This commit is contained in:
parent
e97dfa78df
commit
fee3d9eadc
@ -973,7 +973,7 @@ int ScaLBL_Communicator::MemoryOptimizedLayoutAA(IntArray &Map, int *neighborLis
|
||||
}
|
||||
|
||||
|
||||
void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, int Np)
|
||||
void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, int Np, bool SlippingVelBC=false)
|
||||
{
|
||||
|
||||
int idx,i,j,k;
|
||||
@ -1051,6 +1051,23 @@ void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, in
|
||||
int *bb_interactions_tmp = new int [local_count];
|
||||
ScaLBL_AllocateDeviceMemory((void **) &bb_dist, sizeof(int)*local_count);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &bb_interactions, sizeof(int)*local_count);
|
||||
int *fluid_boundary_tmp;
|
||||
double *lattice_weight_tmp;
|
||||
float *lattice_cx_tmp;
|
||||
float *lattice_cy_tmp;
|
||||
float *lattice_cz_tmp;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp = new int [local_count];
|
||||
lattice_weight_tmp = new double [local_count];
|
||||
lattice_cx_tmp = new float [local_count];
|
||||
lattice_cy_tmp = new float [local_count];
|
||||
lattice_cz_tmp = new float [local_count];
|
||||
ScaLBL_AllocateDeviceMemory((void **) &fluid_boundary, sizeof(int)*local_count);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &lattice_weight, sizeof(double)*local_count);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &lattice_cx, sizeof(float)*local_count);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &lattice_cy, sizeof(float)*local_count);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &lattice_cz, sizeof(float)*local_count);
|
||||
}
|
||||
|
||||
local_count=0;
|
||||
for (k=1;k<Nz-1;k++){
|
||||
@ -1064,36 +1081,78 @@ void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, in
|
||||
neighbor=Map(i-1,j,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i-1) + (j)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = -1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 2*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i+1,j,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i+1) + (j)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = 1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++] = idx + 1*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j-1,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j-1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = -1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 4*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j+1,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j+1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = 1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 3*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j,k-1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j)*Nx + (k-1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = -1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 6*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j,k+1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j)*Nx + (k+1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/18.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = 1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 5*Np;
|
||||
}
|
||||
}
|
||||
@ -1111,72 +1170,156 @@ void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, in
|
||||
neighbor=Map(i-1,j-1,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i-1) + (j-1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = -1.0;
|
||||
lattice_cy_tmp[local_count] = -1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 8*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i+1,j+1,k);
|
||||
if (neighbor==-1) {
|
||||
bb_interactions_tmp[local_count] = (i+1) + (j+1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 1.0;
|
||||
lattice_cy_tmp[local_count] = 1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 7*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i-1,j+1,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i-1) + (j+1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = -1.0;
|
||||
lattice_cy_tmp[local_count] = 1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 10*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i+1,j-1,k);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i+1) + (j-1)*Nx + (k)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 1.0;
|
||||
lattice_cy_tmp[local_count] = -1.0;
|
||||
lattice_cz_tmp[local_count] = 0.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 9*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i-1,j,k-1);
|
||||
if (neighbor==-1) {
|
||||
bb_interactions_tmp[local_count] = (i-1) + (j)*Nx + (k-1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = -1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = -1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 12*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i+1,j,k+1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i+1) + (j)*Nx + (k+1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = 1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 11*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i-1,j,k+1);
|
||||
if (neighbor==-1) {
|
||||
bb_interactions_tmp[local_count] = (i-1) + (j)*Nx + (k+1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = -1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = 1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 14*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i+1,j,k-1);
|
||||
if (neighbor==-1) {
|
||||
bb_interactions_tmp[local_count] = (i+1) + (j)*Nx + (k-1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 1.0;
|
||||
lattice_cy_tmp[local_count] = 0.0;
|
||||
lattice_cz_tmp[local_count] = -1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 13*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j-1,k-1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j-1)*Nx + (k-1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = -1.0;
|
||||
lattice_cz_tmp[local_count] = -1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 16*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j+1,k+1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j+1)*Nx + (k+1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = 1.0;
|
||||
lattice_cz_tmp[local_count] = 1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 15*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j-1,k+1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j-1)*Nx + (k+1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = -1.0;
|
||||
lattice_cz_tmp[local_count] = 1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 18*Np;
|
||||
}
|
||||
|
||||
neighbor=Map(i,j+1,k-1);
|
||||
if (neighbor==-1){
|
||||
bb_interactions_tmp[local_count] = (i) + (j+1)*Nx + (k-1)*Nx*Ny;
|
||||
if(SlippingVelBC==true){
|
||||
fluid_boundary_tmp[local_count] = idx;
|
||||
lattice_weight_tmp[local_count] = 1.0/36.0;
|
||||
lattice_cx_tmp[local_count] = 0.0;
|
||||
lattice_cy_tmp[local_count] = 1.0;
|
||||
lattice_cz_tmp[local_count] = -1.0;
|
||||
}
|
||||
bb_dist_tmp[local_count++]=idx + 17*Np;
|
||||
}
|
||||
}
|
||||
@ -1186,10 +1329,24 @@ void ScaLBL_Communicator::SetupBounceBackList(IntArray &Map, signed char *id, in
|
||||
n_bb_d3q19 = local_count; // this gives the d3q19 distributions not part of d3q7 model
|
||||
ScaLBL_CopyToDevice(bb_dist, bb_dist_tmp, local_count*sizeof(int));
|
||||
ScaLBL_CopyToDevice(bb_interactions, bb_interactions_tmp, local_count*sizeof(int));
|
||||
if(SlippingVelBC==true){
|
||||
ScaLBL_CopyToDevice(fluid_boundary, fluid_boundary_tmp, local_count*sizeof(int));
|
||||
ScaLBL_CopyToDevice(lattice_weight, lattice_weight_tmp, local_count*sizeof(double));
|
||||
ScaLBL_CopyToDevice(lattice_cx, lattice_cx_tmp, local_count*sizeof(float));
|
||||
ScaLBL_CopyToDevice(lattice_cy, lattice_cy_tmp, local_count*sizeof(float));
|
||||
ScaLBL_CopyToDevice(lattice_cz, lattice_cz_tmp, local_count*sizeof(float));
|
||||
}
|
||||
ScaLBL_DeviceBarrier();
|
||||
|
||||
delete [] bb_dist_tmp;
|
||||
delete [] bb_interactions_tmp;
|
||||
if(SlippingVelBC==true){
|
||||
delete [] fluid_boundary_tmp;
|
||||
delete [] lattice_weight_tmp;
|
||||
delete [] lattice_cx_tmp;
|
||||
delete [] lattice_cy_tmp;
|
||||
delete [] lattice_cz_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_Communicator::SolidDirichletD3Q7(double *fq, double *BoundaryValue){
|
||||
@ -1204,6 +1361,14 @@ void ScaLBL_Communicator::SolidNeumannD3Q7(double *fq, double *BoundaryValue){
|
||||
ScaLBL_Solid_Neumann_D3Q7(fq,BoundaryValue,bb_dist,bb_interactions,n_bb_d3q7);
|
||||
}
|
||||
|
||||
void ScaLBL_Communicator::SolidSlippingVelocityBCD3Q19(double *fq, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epslion_LB, double tau, double rho0, double den_scale,double h, double time_conv){
|
||||
// fq is a D3Q19 distribution
|
||||
// BoundaryValues is a list of values to assign at bounce-back solid sites
|
||||
ScaLBL_Solid_SlippingVelocityBC_D3Q19(fq,zeta_potential,Electricfield,SolidGrad,epsilon_LB,tau,rho0,den_scale,h,time_conv,
|
||||
bb_dist,bb_interactions,fluid_boundary,lattice_weight,lattice_cx,lattice_cy,lattice_cz,n_bb_d3q19,N);
|
||||
}
|
||||
|
||||
void ScaLBL_Communicator::SendD3Q19AA(double *dist){
|
||||
|
||||
// NOTE: the center distribution f0 must NOT be at the start of feven, provide offset to start of f2
|
||||
|
@ -288,6 +288,12 @@ extern "C" void ScaLBL_Solid_Dirichlet_D3Q7(double *dist,double *BoundaryValue,i
|
||||
|
||||
extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N);
|
||||
|
||||
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
|
||||
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
|
||||
double *lattice_weight, float *lattice_cx, float *lattice_cy, float *lattice_cz,
|
||||
int count, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(int *list, double *dist, double Vout, int count, int Np);
|
||||
@ -367,9 +373,11 @@ public:
|
||||
void RecvHalo(double *data);
|
||||
void RecvGrad(double *Phi, double *Gradient);
|
||||
void RegularLayout(IntArray map, const double *data, DoubleArray ®data);
|
||||
void SetupBounceBackList(IntArray &Map, signed char *id, int Np);
|
||||
void SetupBounceBackList(IntArray &Map, signed char *id, int Np, bool SlippingVelBC=false);
|
||||
void SolidDirichletD3Q7(double *fq, double *BoundaryValue);
|
||||
void SolidNeumannD3Q7(double *fq, double *BoundaryValue);
|
||||
void SolidSlippingVelocityBCD3Q19(double *fq, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epslion_LB, double tau, double rho0, double den_scale,double h, double time_conv);
|
||||
|
||||
// Routines to set boundary conditions
|
||||
void Color_BC_z(int *Map, double *Phi, double *Den, double vA, double vB);
|
||||
@ -444,6 +452,9 @@ private:
|
||||
//......................................................................................
|
||||
int *bb_dist;
|
||||
int *bb_interactions;
|
||||
int *fluid_boundary;
|
||||
double *lattice_weight;
|
||||
float *lattice_cx, *lattice_cy, *lattice_cz;
|
||||
//......................................................................................
|
||||
|
||||
};
|
||||
|
@ -38,6 +38,56 @@ __global__ void dvc_ScaLBL_Solid_Neumann_D3Q7(double *dist, double *BoundaryValu
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void dvc_ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
|
||||
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
|
||||
double *lattice_weight, float *lattice_cx, float *lattice_cy, float *lattice_cz,
|
||||
int count, int Np)
|
||||
{
|
||||
int idx;
|
||||
int iq,ib,ifluidBC;
|
||||
double value_b,value_q;
|
||||
double Ex,Ey,Ez;
|
||||
double Etx,Ety,Etz;//tangential part of electric field
|
||||
double nsx,nsy,nsz;//unit normal solid gradient
|
||||
double ubx,uby,ubz;//slipping velocity at fluid boundary nodes
|
||||
float cx,cy,cz;//lattice velocity (D3Q19)
|
||||
double LB_weight;//lattice weighting coefficient (D3Q19)
|
||||
double cs2_inv = 3.0;//inverse of cs^2 for D3Q19
|
||||
double nu_LB = (tau-0.5)/cs2_inv;
|
||||
idx = blockIdx.x*blockDim.x + threadIdx.x;
|
||||
if (idx < count){
|
||||
iq = BounceBackDist_list[idx];
|
||||
ib = BounceBackSolid_list[idx];
|
||||
ifluidBC = FluidBoundary_list[idx];
|
||||
value_b = zeta_potential[ib];//get zeta potential from a solid site
|
||||
value_q = dist[iq];
|
||||
|
||||
//Load electric field and compute its tangential componet
|
||||
Ex = ElectricField[ifluidBC+0*Np];
|
||||
Ey = ElectricField[ifluidBC+1*Np];
|
||||
Ez = ElectricField[ifluidBC+2*Np];
|
||||
nsx = SolidGrad[ifluidBC+0*Np];
|
||||
nsy = SolidGrad[ifluidBC+1*Np];
|
||||
nsz = SolidGrad[ifluidBC+2*Np];
|
||||
E_mag_normal = Ex*nsx+Ey*nsy+Ez*nsz;//magnitude of electric field in the direction normal to solid nodes
|
||||
//compute tangential electric field
|
||||
Etx = Ex - E_mag_normal*nsx;
|
||||
Ety = Ey - E_mag_normal*nsy;
|
||||
Etz = Ez - E_mag_normal*nsz;
|
||||
ubx = -eplison_LB*value_b*Etx/(nu_LB*rho0)*time_conv*time_conv/h/h/den_scale;
|
||||
uby = -eplison_LB*value_b*Ety/(nu_LB*rho0)*time_conv*time_conv/h/h/den_scale;
|
||||
ubz = -eplison_LB*value_b*Etz/(nu_LB*rho0)*time_conv*time_conv/h/h/den_scale;
|
||||
|
||||
//compute bounce-back distribution
|
||||
LB_weight = lattice_weight[idx];
|
||||
cx = lattice_cx[idx];
|
||||
cy = lattice_cy[idx];
|
||||
cz = lattice_cz[idx];
|
||||
dist[iq] = value_q - 2.0*LB_weight*rho0*cs2_inv*(cx*ubx+cy*uby+cz*ubz);
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void dvc_ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np)
|
||||
{
|
||||
int idx,n;
|
||||
@ -410,6 +460,23 @@ extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist, double *BoundaryValue, i
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_Solid_SlippingVelocityBC_D3Q19(double *dist, double *zeta_potential, double *ElectricField, double *SolidGrad,
|
||||
double epsilon_LB, double tau, double rho0,double den_scale, double h, double time_conv,
|
||||
int *BounceBackDist_list, int *BounceBackSolid_list, int *FluidBoundary_list,
|
||||
double *lattice_weight, float *lattice_cx, float *lattice_cy, float *lattice_cz,
|
||||
int count, int Np){
|
||||
int GRID = count / 512 + 1;
|
||||
dvc_ScaLBL_Solid_SlippingVelocityBC_D3Q19<<<GRID,512>>>(dist, zeta_potential, ElectricField, SolidGrad,
|
||||
epsilon_LB, tau, rho0, den_scale, h, time_conv,
|
||||
BounceBackDist_list, BounceBackSolid_list, FluidBoundary_list,
|
||||
lattice_weight, lattice_cx, lattice_cy, lattice_cz,
|
||||
count, Np);
|
||||
cudaError_t err = cudaGetLastError();
|
||||
if (cudaSuccess != err){
|
||||
printf("CUDA error in ScaLBL_Solid_SlippingVelocityBC_D3Q19 (kernel): %s \n",cudaGetErrorString(err));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np){
|
||||
int GRID = count / 512 + 1;
|
||||
dvc_ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z<<<GRID,512>>>(list, dist, Vin, count, Np);
|
||||
|
@ -98,9 +98,7 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
||||
h = domain_db->getScalar<double>( "voxel_length" );
|
||||
}
|
||||
|
||||
|
||||
//Re-calcualte model parameters if user updates input
|
||||
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
|
||||
if (rank==0) printf("***********************************************************************************\n");
|
||||
|
@ -8,6 +8,7 @@
|
||||
ScaLBL_StokesModel::ScaLBL_StokesModel(int RANK, int NP, const Utilities::MPI& COMM):
|
||||
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tau(0),
|
||||
Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),mu(0),h(0),nu_phys(0),rho_phys(0),rho0(0),den_scale(0),time_conv(0),tolerance(0),
|
||||
epsilon0(0),epsilon0_LB(0),epsilonR(0),epsilon_LB(0),UseSlippingVelBC(0),
|
||||
Nx(0),Ny(0),Nz(0),N(0),Np(0),nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),Lx(0),Ly(0),Lz(0),comm(COMM)
|
||||
{
|
||||
|
||||
@ -38,6 +39,12 @@ void ScaLBL_StokesModel::ReadParams(string filename,int num_iter){
|
||||
tolerance = 1.0e-8;
|
||||
Fx = Fy = 0.0;
|
||||
Fz = 1.0e-5;
|
||||
//Stokes solver also needs the following parameters for slipping velocity BC
|
||||
epsilon0 = 8.85e-12;//electric permittivity of vaccum; unit:[C/(V*m)]
|
||||
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
||||
epsilonR = 78.4;//default dielectric constant of water
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
UseSlippingVelBC = false;
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
// Read domain parameters
|
||||
@ -85,12 +92,18 @@ void ScaLBL_StokesModel::ReadParams(string filename,int num_iter){
|
||||
if (stokes_db->keyExists( "flux" )){
|
||||
flux = stokes_db->getScalar<double>( "flux" );
|
||||
}
|
||||
if (stokes_db->keyExists( "UseElectroosmoticVelocityBC" )){
|
||||
UseSlippingVelBC = stokes_db->getScalar<bool>( "UseElectroosmoticVelocityBC" );
|
||||
}
|
||||
if (electric_db->keyExists( "epsilonR" )){
|
||||
epsilonR = electric_db->getScalar<double>( "epsilonR" );
|
||||
}
|
||||
|
||||
// Re-calculate model parameters due to parameter read
|
||||
mu=(tau-0.5)/3.0;
|
||||
time_conv = (h*h*1.0e-12)*mu/nu_phys;//time conversion factor from physical to LB unit; [sec/lt]
|
||||
den_scale = rho_phys/rho0*(h*h*h*1.0e-18);//scale factor for density
|
||||
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
}
|
||||
|
||||
void ScaLBL_StokesModel::ReadParams(string filename){
|
||||
@ -101,7 +114,6 @@ void ScaLBL_StokesModel::ReadParams(string filename){
|
||||
domain_db = db->getDatabase( "Domain" );
|
||||
stokes_db = db->getDatabase( "Stokes" );
|
||||
|
||||
|
||||
//---------------------- Default model parameters --------------------------//
|
||||
rho_phys = 1000.0; //by default use water density; unit [kg/m^3]
|
||||
nu_phys = 1.004e-6;//by default use water kinematic viscosity at 20C; unit [m^2/sec]
|
||||
@ -114,6 +126,12 @@ void ScaLBL_StokesModel::ReadParams(string filename){
|
||||
tolerance = 1.0e-8;
|
||||
Fx = Fy = 0.0;
|
||||
Fz = 1.0e-5;
|
||||
//Stokes solver also needs the following parameters for slipping velocity BC
|
||||
epsilon0 = 8.85e-12;//electric permittivity of vaccum; unit:[C/(V*m)]
|
||||
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
||||
epsilonR = 78.4;//default dielectric constant of water
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
UseSlippingVelBC = false;
|
||||
//--------------------------------------------------------------------------//
|
||||
|
||||
// Read domain parameters
|
||||
@ -161,12 +179,18 @@ void ScaLBL_StokesModel::ReadParams(string filename){
|
||||
if (stokes_db->keyExists( "flux" )){
|
||||
flux = stokes_db->getScalar<double>( "flux" );
|
||||
}
|
||||
if (stokes_db->keyExists( "UseElectroosmoticVelocityBC" )){
|
||||
UseSlippingVelBC = stokes_db->getScalar<bool>( "UseElectroosmoticVelocityBC" );
|
||||
}
|
||||
if (electric_db->keyExists( "epsilonR" )){
|
||||
epsilonR = electric_db->getScalar<double>( "epsilonR" );
|
||||
}
|
||||
|
||||
// Re-calculate model parameters due to parameter read
|
||||
mu=(tau-0.5)/3.0;
|
||||
time_conv = (h*h*1.0e-12)*mu/nu_phys;//time conversion factor from physical to LB unit; [sec/lt]
|
||||
den_scale = rho_phys/rho0*(h*h*h*1.0e-18);//scale factor for density
|
||||
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
}
|
||||
|
||||
void ScaLBL_StokesModel::SetDomain(){
|
||||
@ -258,6 +282,157 @@ void ScaLBL_StokesModel::ReadInput(){
|
||||
if (rank == 0) cout << " Domain set." << endl;
|
||||
}
|
||||
|
||||
void ScaLBL_IonModel::AssignZetaPotentialSolid(double *zeta_potential_solid)
|
||||
{
|
||||
size_t NLABELS=0;
|
||||
signed char VALUE=0;
|
||||
double AFFINITY=0.f;
|
||||
|
||||
auto LabelList = ion_db->getVector<int>( "SolidLabels" );
|
||||
auto AffinityList = ion_db->getVector<double>( "ZetaPotentialSolidList" );
|
||||
|
||||
NLABELS=LabelList.size();
|
||||
if (NLABELS != AffinityList.size()){
|
||||
ERROR("Error: LB Stokes Solver: SolidLabels and ZetaPotentialSolidList must be the same length! \n");
|
||||
}
|
||||
|
||||
double label_count[NLABELS];
|
||||
double label_count_global[NLABELS];
|
||||
|
||||
for (size_t idx=0; idx<NLABELS; idx++) label_count[idx]=0;
|
||||
|
||||
// Assign the labels
|
||||
for (int k=0;k<Nz;k++){
|
||||
for (int j=0;j<Ny;j++){
|
||||
for (int i=0;i<Nx;i++){
|
||||
int n = k*Nx*Ny+j*Nx+i;
|
||||
VALUE=Mask->id[n];
|
||||
AFFINITY=0.f;
|
||||
// Assign the affinity from the paired list
|
||||
for (unsigned int idx=0; idx < NLABELS; idx++){
|
||||
if (VALUE == LabelList[idx]){
|
||||
AFFINITY=AffinityList[idx];//no need to convert unit for zeta potential (i.e. volt)
|
||||
label_count[idx] += 1.0;
|
||||
idx = NLABELS;
|
||||
}
|
||||
}
|
||||
zeta_potential_solid[n] = AFFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t idx=0; idx<NLABELS; idx++)
|
||||
label_count_global[idx]=Dm->Comm.sumReduce( label_count[idx]);
|
||||
|
||||
if (rank==0){
|
||||
printf("LB Stokes Solver: number of solid labels: %lu \n",NLABELS);
|
||||
for (unsigned int idx=0; idx<NLABELS; idx++){
|
||||
VALUE=LabelList[idx];
|
||||
AFFINITY=AffinityList[idx];
|
||||
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs);
|
||||
printf(" label=%d, zeta potential=%.3g [V], volume fraction=%.2g\n",VALUE,AFFINITY,volume_fraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_IonModel::AssignSolidGrad(double *solid_grad)
|
||||
{
|
||||
//TODO need to normalize the computed solid grad!!!
|
||||
double *Dst;
|
||||
Dst = new double [3*3*3];
|
||||
for (int kk=0; kk<3; kk++){
|
||||
for (int jj=0; jj<3; jj++){
|
||||
for (int ii=0; ii<3; ii++){
|
||||
int index = kk*9+jj*3+ii;
|
||||
Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
//implement a D3Q19 lattice
|
||||
double w_face = 1.0/18.0;
|
||||
double w_edge = 0.5*w_face;
|
||||
double w_corner = 0.0;
|
||||
//local
|
||||
Dst[13] = 0.f;
|
||||
//faces
|
||||
Dst[4] = w_face;
|
||||
Dst[10] = w_face;
|
||||
Dst[12] = w_face;
|
||||
Dst[14] = w_face;
|
||||
Dst[16] = w_face;
|
||||
Dst[22] = w_face;
|
||||
// corners
|
||||
Dst[0] = w_corner;
|
||||
Dst[2] = w_corner;
|
||||
Dst[6] = w_corner;
|
||||
Dst[8] = w_corner;
|
||||
Dst[18] = w_corner;
|
||||
Dst[20] = w_corner;
|
||||
Dst[24] = w_corner;
|
||||
Dst[26] = w_corner;
|
||||
// edges
|
||||
Dst[1] = w_edge;
|
||||
Dst[3] = w_edge;
|
||||
Dst[5] = w_edge;
|
||||
Dst[7] = w_edge;
|
||||
Dst[9] = w_edge;
|
||||
Dst[11] = w_edge;
|
||||
Dst[15] = w_edge;
|
||||
Dst[17] = w_edge;
|
||||
Dst[19] = w_edge;
|
||||
Dst[21] = w_edge;
|
||||
Dst[23] = w_edge;
|
||||
Dst[25] = w_edge;
|
||||
|
||||
for (int k=1; k<Nz-1; k++){
|
||||
for (int j=1; j<Ny-1; j++){
|
||||
for (int i=1; i<Nx-1; i++){
|
||||
int idx=Map(i,j,k);
|
||||
if (!(idx < 0)){
|
||||
double phi_x = 0.f;
|
||||
double phi_y = 0.f;
|
||||
double phi_z = 0.f;
|
||||
for (int kk=0; kk<3; kk++){
|
||||
for (int jj=0; jj<3; jj++){
|
||||
for (int ii=0; ii<3; ii++){
|
||||
|
||||
int index = kk*9+jj*3+ii;
|
||||
double weight= Dst[index];
|
||||
|
||||
int idi=i+ii-1;
|
||||
int idj=j+jj-1;
|
||||
int idk=k+kk-1;
|
||||
|
||||
if (idi < 0) idi=0;
|
||||
if (idj < 0) idj=0;
|
||||
if (idk < 0) idk=0;
|
||||
if (!(idi < Nx)) idi=Nx-1;
|
||||
if (!(idj < Ny)) idj=Ny-1;
|
||||
if (!(idk < Nz)) idk=Nz-1;
|
||||
|
||||
int nn = idk*Nx*Ny + idj*Nx + idi;
|
||||
double vec_x = double(ii-1);
|
||||
double vec_y = double(jj-1);
|
||||
double vec_z = double(kk-1);
|
||||
double GWNS = double(Mask->id[nn]);
|
||||
//Since the solid unit normal vector is wanted, treat
|
||||
//wet node as 0.0 and solid node as 1.0
|
||||
GWNS = (GWNS>0.0) ? 0.0:1.0;
|
||||
phi_x += GWNS*weight*vec_x;
|
||||
phi_y += GWNS*weight*vec_y;
|
||||
phi_z += GWNS*weight*vec_z;
|
||||
}
|
||||
}
|
||||
}
|
||||
solid_grad[idx+0*Np] = phi_x;
|
||||
solid_grad[idx+1*Np] = phi_y;
|
||||
solid_grad[idx+2*Np] = phi_z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_StokesModel::Create(){
|
||||
/*
|
||||
* This function creates the variables needed to run a LBM
|
||||
@ -301,6 +476,26 @@ void ScaLBL_StokesModel::Create(){
|
||||
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
||||
comm.barrier();
|
||||
|
||||
if (UseSlippingVelBC==true){
|
||||
ScaLBL_Comm->SetupBounceBackList(Map, Mask->id.data(), Np,1);
|
||||
comm.barrier();
|
||||
|
||||
//For slipping velocity BC, need zeta potential and solid unit normal vector
|
||||
ScaLBL_AllocateDeviceMemory((void **) &ZetaPotentialSolid, sizeof(double)*Nx*Ny*Nz);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &SolidGrad, sizeof(double)*Np); //unit normal vector of solid nodes
|
||||
|
||||
double *ZetaPotentialSolid_host;
|
||||
ZetaPotentialSolid_host = new double[Nx*Ny*Nz];
|
||||
AssignZetaPotentialSolid(ZetaPotentialSolid_host);
|
||||
double *SolidGrad_host;
|
||||
SolidGrad_host = new double[3*Np];
|
||||
AssignSolidGrad(SolidGrad_host);
|
||||
ScaLBL_CopyToDevice(ZetaPotentialSolid, ZetaPotentialSolid_host, Nx*Ny*Nz*sizeof(double));
|
||||
ScaLBL_CopyToDevice(SolidGrad, SolidGrad_host, 3*Np*sizeof(double));
|
||||
ScaLBL_Comm->Barrier();
|
||||
delete [] ZetaPotentialSolid_host;
|
||||
delete [] SolidGrad_host;
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_StokesModel::Initialize(){
|
||||
@ -324,6 +519,7 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
||||
timestep = 0;
|
||||
while (timestep < timestepMax) {
|
||||
//************************************************************************/
|
||||
//**************ODD TIMESTEP*************//
|
||||
timestep++;
|
||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
|
||||
ScaLBL_D3Q19_AAodd_StokesMRT(NeighborList, fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||
@ -344,8 +540,14 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
||||
}
|
||||
ScaLBL_D3Q19_AAodd_StokesMRT(NeighborList, fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||
0, ScaLBL_Comm->LastExterior(), Np);
|
||||
|
||||
if (UseSlippingVelBC==true){
|
||||
ScaLBL_Comm->SolidSlippingVelocityBCD3Q19(fq, ZetaPotentialSolid, ElectricField, SolidGrad,
|
||||
epslion_LB, 1.0/rlx_setA, rho0, den_scale, h, time_conv);
|
||||
}
|
||||
ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
|
||||
//**************EVEN TIMESTEP*************//
|
||||
timestep++;
|
||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
|
||||
ScaLBL_D3Q19_AAeven_StokesMRT(fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||
@ -366,6 +568,10 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
||||
}
|
||||
ScaLBL_D3Q19_AAeven_StokesMRT(fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||
0, ScaLBL_Comm->LastExterior(), Np);
|
||||
if (UseSlippingVelBC==true){
|
||||
ScaLBL_Comm->SolidSlippingVelocityBCD3Q19(fq, ZetaPotentialSolid, ElectricField, SolidGrad,
|
||||
epslion_LB, 1.0/rlx_setA, rho0, den_scale, h, time_conv);
|
||||
}
|
||||
ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
//************************************************************************/
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
double time_conv;
|
||||
double h;//image resolution
|
||||
double den_scale;//scale factor for density
|
||||
double epsilon0,epsilon0_LB,epsilonR,epsilon_LB;//Stokes solver also needs this for slipping velocity BC
|
||||
bool UseSlippingVelBC;
|
||||
|
||||
int Nx,Ny,Nz,N,Np;
|
||||
int rank,nprocx,nprocy,nprocz,nprocs;
|
||||
@ -70,6 +72,7 @@ public:
|
||||
double *fq;
|
||||
double *Velocity;
|
||||
double *Pressure;
|
||||
double *ZetaPotentialSolid;
|
||||
|
||||
//Minkowski Morphology;
|
||||
DoubleArray Velocity_x;
|
||||
|
Loading…
Reference in New Issue
Block a user