fix miscellaneous bugs and update the data structure of electric potential
This commit is contained in:
@@ -2053,3 +2053,36 @@ void ScaLBL_Communicator::PrintD3Q19(){
|
|||||||
delete [] TempBuffer;
|
delete [] TempBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScaLBL_Communicator::D3Q7_Poisson_Potential_BC_z(int *neighborList, double *fq, double Vin, int time){
|
||||||
|
if (kproc == 0) {
|
||||||
|
if (time%2==0){
|
||||||
|
ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(dvcSendList_z, fq, Vin, sendCount_z, N);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(neighborList, dvcSendList_z, fq, Vin, sendCount_z, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaLBL_Communicator::D3Q7_Poisson_Potential_BC_Z(int *neighborList, double *fq, double Vout, int time){
|
||||||
|
if (kproc == nprocz-1){
|
||||||
|
if (time%2==0){
|
||||||
|
ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(dvcSendList_Z, fq, Vout, sendCount_Z, N);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(neighborList, dvcSendList_Z, fq, Vout, sendCount_Z, N);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaLBL_Communicator::Poisson_D3Q7_BC_z(int *Map, double *Psi, double Vin){
|
||||||
|
if (kproc == 0) {
|
||||||
|
ScaLBL_Poisson_D3Q7_BC_z(dvcSendList_z, Map, Psi, Vin, sendCount_z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaLBL_Communicator::Poisson_D3Q7_BC_Z(int *Map, double *Psi, double Vout){
|
||||||
|
if (kproc == nprocz-1){
|
||||||
|
ScaLBL_Poisson_D3Q7_BC_Z(dvcSendList_Z, Map, Psi, Vout, sendCount_Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,11 +46,8 @@ extern "C" void ScaLBL_UnpackDenD3Q7(int *list, int count, double *recvbuf, int
|
|||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_Init(double *Dist, int Np);
|
extern "C" void ScaLBL_D3Q19_Init(double *Dist, int Np);
|
||||||
|
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np);
|
extern "C" void ScaLBL_D3Q19_Momentum(double *dist, double *vel, int Np);
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_Momentum_Phys(double *dist, double *vel, double h, double time_conv, int Np);
|
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *press, int Np);
|
extern "C" void ScaLBL_D3Q19_Pressure(double *dist, double *press, int Np);
|
||||||
|
|
||||||
// BGK MODEL
|
// BGK MODEL
|
||||||
@@ -95,21 +92,30 @@ extern "C" void ScaLBL_IonConcentration_Phys(double *Den, double h, int ion_comp
|
|||||||
|
|
||||||
// LBM Poisson solver
|
// LBM Poisson solver
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList,int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
||||||
int start, int finish, int Np);
|
int start, int finish, int Np);
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
||||||
int start, int finish, int Np);
|
int start, int finish, int Np);
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_Poisson_Init(double *dist, int Np);
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(int *neighborList,int *Map, double *dist, double *Psi, int start, int finish, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(int *Map, double *dist, double *Psi, int start, int finish, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_Poisson_Init(int *Map, double *dist, double *Psi, int start, int finish, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_Poisson_getElectricField(double *dist, double *ElectricField, double tau, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_Poisson_ElectricField(int *neighborList, int *Map, signed char *ID, double *Psi, double *ElectricField, int SolidBC,
|
||||||
|
int strideY, int strideZ,int start, int finish, int Np);
|
||||||
|
|
||||||
// LBM Stokes Model (adapted from MRT model)
|
// LBM Stokes Model (adapted from MRT model)
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
||||||
double Gx, double Gy, double Gz, double Ex, double Ey, double Ez, int start, int finish, int Np);
|
double Gx, double Gy, double Gz,double rho0, double den_scale, double h, double time_conv, int start, int finish, int Np);
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
||||||
double Gx, double Gy, double Gz, double Ex, double Ey, double Ez, int start, int finish, int Np);
|
double Gx, double Gy, double Gz, double rho0, double den_scale, double h, double time_conv,int start, int finish, int Np);
|
||||||
|
|
||||||
// MRT MODEL
|
// MRT MODEL
|
||||||
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
|
extern "C" void ScaLBL_D3Q19_AAeven_MRT(double *dist, int start, int finish, int Np, double rlx_setA, double rlx_setB, double Fx,
|
||||||
@@ -190,6 +196,18 @@ 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_Neumann_D3Q7(double *dist,double *BoundaryValue,int *BounceBackDist_list,int *BounceBackSolid_list,int N);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(int *d_neighborList, int *list, double *dist, double Vin, int count, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(int *d_neighborList, int *list, double *dist, double Vout, int count, int Np);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_Poisson_D3Q7_BC_z(int *list, int *Map, double *Psi, double Vin, int count);
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_Poisson_D3Q7_BC_Z(int *list, int *Map, double *Psi, double Vout, int count);
|
||||||
|
|
||||||
class ScaLBL_Communicator{
|
class ScaLBL_Communicator{
|
||||||
public:
|
public:
|
||||||
//......................................................................................
|
//......................................................................................
|
||||||
@@ -249,6 +267,10 @@ public:
|
|||||||
void D3Q19_Reflection_BC_z(double *fq);
|
void D3Q19_Reflection_BC_z(double *fq);
|
||||||
void D3Q19_Reflection_BC_Z(double *fq);
|
void D3Q19_Reflection_BC_Z(double *fq);
|
||||||
double D3Q19_Flux_BC_z(int *neighborList, double *fq, double flux, int time);
|
double D3Q19_Flux_BC_z(int *neighborList, double *fq, double flux, int time);
|
||||||
|
void D3Q7_Poisson_Potential_BC_z(int *neighborList, double *fq, double Vin, int time);
|
||||||
|
void D3Q7_Poisson_Potential_BC_Z(int *neighborList, double *fq, double Vout, int time);
|
||||||
|
void Poisson_D3Q7_BC_z(int *Map, double *Psi, double Vin);
|
||||||
|
void Poisson_D3Q7_BC_Z(int *Map, double *Psi, double Vout);
|
||||||
|
|
||||||
// Debugging and unit testing functions
|
// Debugging and unit testing functions
|
||||||
void PrintD3Q19();
|
void PrintD3Q19();
|
||||||
|
|||||||
107
cpu/D3Q7BC.cpp
107
cpu/D3Q7BC.cpp
@@ -30,3 +30,110 @@ extern "C" void ScaLBL_Solid_Neumann_D3Q7(double *dist,double *BoundaryValue,int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_z(int *list, double *dist, double Vin, int count, int Np){
|
||||||
|
for (int idx=0; idx<count; idx++){
|
||||||
|
int n = list[idx];
|
||||||
|
double f0 = dist[n];
|
||||||
|
double f1 = dist[2*Np+n];
|
||||||
|
double f2 = dist[1*Np+n];
|
||||||
|
double f3 = dist[4*Np+n];
|
||||||
|
double f4 = dist[3*Np+n];
|
||||||
|
double f6 = dist[5*Np+n];
|
||||||
|
//...................................................
|
||||||
|
double f5 = Vin - (f0+f1+f2+f3+f4+f6);
|
||||||
|
dist[6*Np+n] = f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_Potential_BC_Z(int *list, double *dist, double Vout, int count, int Np){
|
||||||
|
for (int idx=0; idx<count; idx++){
|
||||||
|
int n = list[idx];
|
||||||
|
double f0 = dist[n];
|
||||||
|
double f1 = dist[2*Np+n];
|
||||||
|
double f2 = dist[1*Np+n];
|
||||||
|
double f3 = dist[4*Np+n];
|
||||||
|
double f4 = dist[3*Np+n];
|
||||||
|
double f5 = dist[6*Np+n];
|
||||||
|
//...................................................
|
||||||
|
double f6 = Vout - (f0+f1+f2+f3+f4+f5);
|
||||||
|
dist[5*Np+n] = f6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_z(int *d_neighborList, int *list, double *dist, double Vin, int count, int Np){
|
||||||
|
int nread,nr5;
|
||||||
|
for (int idx=0; idx<count; idx++){
|
||||||
|
int n = list[idx];
|
||||||
|
double f0 = dist[n];
|
||||||
|
|
||||||
|
nread = d_neighborList[n];
|
||||||
|
double f1 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+2*Np];
|
||||||
|
double f3 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+Np];
|
||||||
|
double f2 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+3*Np];
|
||||||
|
double f4 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+5*Np];
|
||||||
|
double f6 = dist[nread];
|
||||||
|
|
||||||
|
// Unknown distributions
|
||||||
|
nr5 = d_neighborList[n+4*Np];
|
||||||
|
double f5 = Vin - (f0+f1+f2+f3+f4+f6);
|
||||||
|
dist[nr5] = f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_Potential_BC_Z(int *d_neighborList, int *list, double *dist, double Vout, int count, int Np){
|
||||||
|
int nread,nr6;
|
||||||
|
for (int idx=0; idx<count; idx++){
|
||||||
|
int n = list[idx];
|
||||||
|
double f0 = dist[n];
|
||||||
|
|
||||||
|
nread = d_neighborList[n];
|
||||||
|
double f1 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+2*Np];
|
||||||
|
double f3 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+4*Np];
|
||||||
|
double f5 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+Np];
|
||||||
|
double f2 = dist[nread];
|
||||||
|
|
||||||
|
nread = d_neighborList[n+3*Np];
|
||||||
|
double f4 = dist[nread];
|
||||||
|
|
||||||
|
// unknown distributions
|
||||||
|
nr6 = d_neighborList[n+5*Np];
|
||||||
|
double f6 = Vout - (f0+f1+f2+f3+f4+f5);
|
||||||
|
dist[nr6] = f6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_Poisson_D3Q7_BC_z(int *list, int *Map, double *Psi, double Vin, int count)
|
||||||
|
{
|
||||||
|
int idx,n,nm;
|
||||||
|
|
||||||
|
for (idx=0; idx<count; idx++){
|
||||||
|
n = list[idx];
|
||||||
|
nm = Map[n];
|
||||||
|
Psi[nm] = Vin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_Poisson_D3Q7_BC_Z(int *list, int *Map, double *Psi, double Vout, int count)
|
||||||
|
{
|
||||||
|
int idx,n,nm;
|
||||||
|
|
||||||
|
for (idx=0; idx<count; idx++){
|
||||||
|
n = list[idx];
|
||||||
|
nm = Map[n];
|
||||||
|
Psi[nm] = Vout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
350
cpu/Poisson.cpp
350
cpu/Poisson.cpp
@@ -1,19 +1,110 @@
|
|||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(int *neighborList,int *Map, double *dist, double *Psi, int start, int finish, int Np){
|
||||||
int start, int finish, int Np){
|
|
||||||
int n;
|
int n;
|
||||||
double psi;//electric potential
|
double psi;//electric potential
|
||||||
double Ex,Ey,Ez;//electrical field
|
double fq;
|
||||||
|
int nread;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (n=start; n<finish; n++){
|
||||||
|
|
||||||
|
// q=0
|
||||||
|
fq = dist[n];
|
||||||
|
psi = fq;
|
||||||
|
|
||||||
|
// q=1
|
||||||
|
nread = neighborList[n];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=2
|
||||||
|
nread = neighborList[n+Np];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=3
|
||||||
|
nread = neighborList[n+2*Np];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q = 4
|
||||||
|
nread = neighborList[n+3*Np];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=5
|
||||||
|
nread = neighborList[n+4*Np];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q = 6
|
||||||
|
nread = neighborList[n+5*Np];
|
||||||
|
fq = dist[nread];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
idx=Map[n];
|
||||||
|
Psi[idx] = psi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(int *Map, double *dist, double *Psi, int start, int finish, int Np){
|
||||||
|
int n;
|
||||||
|
double psi;//electric potential
|
||||||
|
double fq;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (n=start; n<finish; n++){
|
||||||
|
|
||||||
|
// q=0
|
||||||
|
fq = dist[n];
|
||||||
|
psi = fq;
|
||||||
|
|
||||||
|
// q=1
|
||||||
|
fq = dist[2*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=2
|
||||||
|
fq = dist[1*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=3
|
||||||
|
fq = dist[4*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=4
|
||||||
|
fq = dist[3*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=5
|
||||||
|
fq = dist[6*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
// q=6
|
||||||
|
fq = dist[5*Np+n];
|
||||||
|
psi += fq;
|
||||||
|
|
||||||
|
idx=Map[n];
|
||||||
|
Psi[idx] = psi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,int start, int finish, int Np){
|
||||||
|
int n;
|
||||||
|
double psi;//electric potential
|
||||||
|
double Ex,Ey,Ez;//electric field
|
||||||
double rho_e;//local charge density
|
double rho_e;//local charge density
|
||||||
double f0,f1,f2,f3,f4,f5,f6;
|
double f0,f1,f2,f3,f4,f5,f6;
|
||||||
int nr1,nr2,nr3,nr4,nr5,nr6;
|
int nr1,nr2,nr3,nr4,nr5,nr6;
|
||||||
double rlx=1.0/tau;
|
double rlx=1.0/tau;
|
||||||
|
int idx;
|
||||||
|
|
||||||
for (n=start; n<finish; n++){
|
for (n=start; n<finish; n++){
|
||||||
|
|
||||||
//Load data
|
//Load data
|
||||||
rho_e = Den_charge[n];
|
rho_e = Den_charge[n];
|
||||||
rho_e = gamma*rho_e/epsilon_LB;
|
rho_e = gamma*rho_e/epsilon_LB;
|
||||||
|
idx=Map[n];
|
||||||
|
psi = Psi[idx];
|
||||||
|
|
||||||
// q=0
|
// q=0
|
||||||
f0 = dist[n];
|
f0 = dist[n];
|
||||||
@@ -40,53 +131,63 @@ extern "C" void ScaLBL_D3Q7_AAodd_Poisson(int *neighborList, double *dist, doubl
|
|||||||
nr6 = neighborList[n+5*Np];
|
nr6 = neighborList[n+5*Np];
|
||||||
f6 = dist[nr6];
|
f6 = dist[nr6];
|
||||||
|
|
||||||
psi = f0+f2+f1+f4+f3+f6+f5;
|
//Ex = (f1-f2)*rlx*4.5;//NOTE the unit of electric field here is V/lu
|
||||||
Ex = (f1-f2)*rlx*4.5;//NOTE the unit of electric field here is V/lu
|
//Ey = (f3-f4)*rlx*4.5;
|
||||||
Ey = (f3-f4)*rlx*4.5;
|
//Ez = (f5-f6)*rlx*4.5;
|
||||||
Ez = (f5-f6)*rlx*4.5;
|
//Ex = (f1-f2)*rlx*4.0;//NOTE the unit of electric field here is V/lu
|
||||||
ElectricField[n+0*Np] = Ex;
|
//Ey = (f3-f4)*rlx*4.0;
|
||||||
ElectricField[n+1*Np] = Ey;
|
//Ez = (f5-f6)*rlx*4.0;
|
||||||
ElectricField[n+2*Np] = Ez;
|
//ElectricField[n+0*Np] = Ex;
|
||||||
Psi[n] = psi;
|
//ElectricField[n+1*Np] = Ey;
|
||||||
|
//ElectricField[n+2*Np] = Ez;
|
||||||
|
|
||||||
// q = 0
|
// q = 0
|
||||||
dist[n] = f0*(1.0-rlx) + 0.3333333333333333*(rlx*psi+rho_e);
|
//dist[n] = f0*(1.0-rlx) + 0.3333333333333333*(rlx*psi+rho_e);
|
||||||
|
dist[n] = f0*(1.0-rlx) + 0.25*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 1
|
// q = 1
|
||||||
dist[nr2] = f1*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr2] = f1*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr2] = f1*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 2
|
// q = 2
|
||||||
dist[nr1] = f2*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr1] = f2*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr1] = f2*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 3
|
// q = 3
|
||||||
dist[nr4] = f3*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr4] = f3*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr4] = f3*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 4
|
// q = 4
|
||||||
dist[nr3] = f4*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr3] = f4*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr3] = f4*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 5
|
// q = 5
|
||||||
dist[nr6] = f5*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr6] = f5*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr6] = f5*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 6
|
// q = 6
|
||||||
dist[nr5] = f6*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[nr5] = f6*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[nr5] = f6*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
//........................................................................
|
//........................................................................
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,
|
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,double gamma,int start, int finish, int Np){
|
||||||
int start, int finish, int Np){
|
|
||||||
int n;
|
int n;
|
||||||
double psi;//electric potential
|
double psi;//electric potential
|
||||||
double Ex,Ey,Ez;//electrical field
|
double Ex,Ey,Ez;//electric field
|
||||||
double rho_e;//local charge density
|
double rho_e;//local charge density
|
||||||
double f0,f1,f2,f3,f4,f5,f6;
|
double f0,f1,f2,f3,f4,f5,f6;
|
||||||
double rlx=1.0/tau;
|
double rlx=1.0/tau;
|
||||||
|
int idx;
|
||||||
|
|
||||||
for (n=start; n<finish; n++){
|
for (n=start; n<finish; n++){
|
||||||
|
|
||||||
//Load data
|
//Load data
|
||||||
rho_e = Den_charge[n];
|
rho_e = Den_charge[n];
|
||||||
rho_e = gamma*rho_e/epsilon_LB;
|
rho_e = gamma*rho_e/epsilon_LB;
|
||||||
|
idx=Map[n];
|
||||||
|
psi = Psi[idx];
|
||||||
|
|
||||||
f0 = dist[n];
|
f0 = dist[n];
|
||||||
f1 = dist[2*Np+n];
|
f1 = dist[2*Np+n];
|
||||||
@@ -97,49 +198,208 @@ extern "C" void ScaLBL_D3Q7_AAeven_Poisson(double *dist, double *Den_charge, dou
|
|||||||
f6 = dist[5*Np+n];
|
f6 = dist[5*Np+n];
|
||||||
|
|
||||||
|
|
||||||
psi = f0+f2+f1+f4+f3+f6+f5;
|
//Ex = (f1-f2)*rlx*4.5;//NOTE the unit of electric field here is V/lu
|
||||||
Ex = (f1-f2)*rlx*4.5;//NOTE the unit of electric field here is V/lu
|
//Ey = (f3-f4)*rlx*4.5;
|
||||||
Ey = (f3-f4)*rlx*4.5;
|
//Ez = (f5-f6)*rlx*4.5;
|
||||||
Ez = (f5-f6)*rlx*4.5;
|
//Ex = (f1-f2)*rlx*4.0;//NOTE the unit of electric field here is V/lu
|
||||||
ElectricField[n+0*Np] = Ex;
|
//Ey = (f3-f4)*rlx*4.0;
|
||||||
ElectricField[n+1*Np] = Ey;
|
//Ez = (f5-f6)*rlx*4.0;
|
||||||
ElectricField[n+2*Np] = Ez;
|
//ElectricField[n+0*Np] = Ex;
|
||||||
Psi[n] = psi;
|
//ElectricField[n+1*Np] = Ey;
|
||||||
|
//ElectricField[n+2*Np] = Ez;
|
||||||
|
|
||||||
// q = 0
|
// q = 0
|
||||||
dist[n] = f0*(1.0-rlx) + 0.3333333333333333*(rlx*psi+rho_e);
|
//dist[n] = f0*(1.0-rlx) + 0.3333333333333333*(rlx*psi+rho_e);
|
||||||
|
dist[n] = f0*(1.0-rlx) + 0.25*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 1
|
// q = 1
|
||||||
dist[1*Np+n] = f1*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[1*Np+n] = f1*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[1*Np+n] = f1*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 2
|
// q = 2
|
||||||
dist[2*Np+n] = f2*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[2*Np+n] = f2*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[2*Np+n] = f2*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 3
|
// q = 3
|
||||||
dist[3*Np+n] = f3*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[3*Np+n] = f3*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[3*Np+n] = f3*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 4
|
// q = 4
|
||||||
dist[4*Np+n] = f4*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[4*Np+n] = f4*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[4*Np+n] = f4*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 5
|
// q = 5
|
||||||
dist[5*Np+n] = f5*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[5*Np+n] = f5*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[5*Np+n] = f5*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
|
|
||||||
// q = 6
|
// q = 6
|
||||||
dist[6*Np+n] = f6*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
//dist[6*Np+n] = f6*(1.0-rlx) + 0.1111111111111111*(rlx*psi+rho_e);
|
||||||
|
dist[6*Np+n] = f6*(1.0-rlx) + 0.125*(rlx*psi+rho_e);
|
||||||
//........................................................................
|
//........................................................................
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q7_Poisson_Init(double *dist, int Np)
|
extern "C" void ScaLBL_D3Q7_Poisson_Init(int *Map, double *dist, double *Psi, int start, int finish, int Np)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
for (n=0; n<Np; n++){
|
int ijk;
|
||||||
dist[0*Np+n] = 0.3333333333333333;
|
for (n=start; n<finish; n++){
|
||||||
dist[1*Np+n] = 0.1111111111111111;
|
ijk = Map[n];
|
||||||
dist[2*Np+n] = 0.1111111111111111;
|
//dist[0*Np+n] = 0.3333333333333333*Psi[n];
|
||||||
dist[3*Np+n] = 0.1111111111111111;
|
//dist[1*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
dist[4*Np+n] = 0.1111111111111111;
|
//dist[2*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
dist[5*Np+n] = 0.1111111111111111;
|
//dist[3*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
dist[6*Np+n] = 0.1111111111111111;
|
//dist[4*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
|
//dist[5*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
|
//dist[6*Np+n] = 0.1111111111111111*Psi[n];
|
||||||
|
//dist[0*Np+n] = 0.25*Psi[n];
|
||||||
|
//dist[1*Np+n] = 0.125*Psi[n];
|
||||||
|
//dist[2*Np+n] = 0.125*Psi[n];
|
||||||
|
//dist[3*Np+n] = 0.125*Psi[n];
|
||||||
|
//dist[4*Np+n] = 0.125*Psi[n];
|
||||||
|
//dist[5*Np+n] = 0.125*Psi[n];
|
||||||
|
//dist[6*Np+n] = 0.125*Psi[n];
|
||||||
|
|
||||||
|
dist[0*Np+n] = 0.25*Psi[ijk];
|
||||||
|
dist[1*Np+n] = 0.125*Psi[ijk];
|
||||||
|
dist[2*Np+n] = 0.125*Psi[ijk];
|
||||||
|
dist[3*Np+n] = 0.125*Psi[ijk];
|
||||||
|
dist[4*Np+n] = 0.125*Psi[ijk];
|
||||||
|
dist[5*Np+n] = 0.125*Psi[ijk];
|
||||||
|
dist[6*Np+n] = 0.125*Psi[ijk];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_Poisson_getElectricField(double *dist, double *ElectricField, double tau, int Np){
|
||||||
|
int n;
|
||||||
|
// distributions
|
||||||
|
double f1,f2,f3,f4,f5,f6;
|
||||||
|
double Ex,Ey,Ez;
|
||||||
|
double rlx=1.0/tau;
|
||||||
|
|
||||||
|
for (n=0; n<Np; n++){
|
||||||
|
//........................................................................
|
||||||
|
// Registers to store the distributions
|
||||||
|
//........................................................................
|
||||||
|
f1 = dist[Np+n];
|
||||||
|
f2 = dist[2*Np+n];
|
||||||
|
f3 = dist[3*Np+n];
|
||||||
|
f4 = dist[4*Np+n];
|
||||||
|
f5 = dist[5*Np+n];
|
||||||
|
f6 = dist[6*Np+n];
|
||||||
|
//.................Compute the Electric Field...................................
|
||||||
|
//Ex = (f1-f2)*rlx*4.5;//NOTE the unit of electric field here is V/lu
|
||||||
|
//Ey = (f3-f4)*rlx*4.5;
|
||||||
|
//Ez = (f5-f6)*rlx*4.5;
|
||||||
|
Ex = (f1-f2)*rlx*4.0;//NOTE the unit of electric field here is V/lu
|
||||||
|
Ey = (f3-f4)*rlx*4.0;
|
||||||
|
Ez = (f5-f6)*rlx*4.0;
|
||||||
|
//..................Write the Electric Field.....................................
|
||||||
|
ElectricField[0*Np+n] = Ex;
|
||||||
|
ElectricField[1*Np+n] = Ey;
|
||||||
|
ElectricField[2*Np+n] = Ez;
|
||||||
|
//........................................................................
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void ScaLBL_D3Q7_Poisson_ElectricField(int *neighborList, int *Map, signed char *ID, double *Psi, double *ElectricField, int SolidBC,
|
||||||
|
int strideY, int strideZ,int start, int finish, int Np){
|
||||||
|
|
||||||
|
int n,nn;
|
||||||
|
int ijk;
|
||||||
|
int id;
|
||||||
|
// distributions
|
||||||
|
double m1,m2,m3,m4,m5,m6,m7,m8,m9;
|
||||||
|
double m10,m11,m12,m13,m14,m15,m16,m17,m18;
|
||||||
|
double nx,ny,nz;
|
||||||
|
|
||||||
|
for (n=start; n<finish; n++){
|
||||||
|
|
||||||
|
// Get the 1D index based on regular data layout
|
||||||
|
ijk = Map[n];
|
||||||
|
// COMPUTE THE COLOR GRADIENT
|
||||||
|
//........................................................................
|
||||||
|
//.................Read Phase Indicator Values............................
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m1 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 1
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m2 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 2
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m3 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 3
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m4 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 4
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideZ; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m5 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 5
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideZ; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m6 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 6
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideY-1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m7 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 7
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideY+1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m8 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 8
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideY-1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m9 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 9
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideY+1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m10 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 10
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideZ-1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m11 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 11
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideZ+1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m12 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 12
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideZ-1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m13 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 13
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideZ+1; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m14 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 14
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideZ-strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m15 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 15
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideZ+strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m16 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 16
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk+strideZ-strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m17 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 17
|
||||||
|
//........................................................................
|
||||||
|
nn = ijk-strideZ+strideY; // neighbor index (get convention)
|
||||||
|
id = ID[nn];
|
||||||
|
m18 = SolidBC==1 ? Psi[nn] : Psi[nn]*(id>0)+Psi[ijk]*(id<=0);// get neighbor for phi - 18
|
||||||
|
//............Compute the Color Gradient...................................
|
||||||
|
nx = -1.f/18.f*(m1-m2+0.5*(m7-m8+m9-m10+m11-m12+m13-m14));
|
||||||
|
ny = -1.f/18.f*(m3-m4+0.5*(m7-m8-m9+m10+m15-m16+m17-m18));
|
||||||
|
nz = -1.f/18.f*(m5-m6+0.5*(m11-m12-m13+m14+m15-m16-m17+m18));
|
||||||
|
|
||||||
|
ElectricField[n] = nx;
|
||||||
|
ElectricField[Np+n] = ny;
|
||||||
|
ElectricField[2*Np+n] = nz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
162
cpu/Stokes.cpp
162
cpu/Stokes.cpp
@@ -1,7 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB, double Gx, double Gy, double Gz,double rho0, double den_scale, double h, double time_conv, int start, int finish, int Np)
|
||||||
double Gx, double Gy, double Gz, double Ex_const, double Ey_const, double Ez_const, int start, int finish, int Np)
|
|
||||||
{
|
{
|
||||||
double fq;
|
double fq;
|
||||||
// conserved momemnts
|
// conserved momemnts
|
||||||
@@ -32,13 +31,13 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
|
|||||||
|
|
||||||
//Load data
|
//Load data
|
||||||
rhoE = ChargeDensity[n];
|
rhoE = ChargeDensity[n];
|
||||||
Ex = ElectricField[n+0*Np]+Ex_const;
|
Ex = ElectricField[n+0*Np];
|
||||||
Ey = ElectricField[n+1*Np]+Ey_const;
|
Ey = ElectricField[n+1*Np];
|
||||||
Ez = ElectricField[n+2*Np]+Ez_const;
|
Ez = ElectricField[n+2*Np];
|
||||||
//compute total body force, including input body force (Gx,Gy,Gz)
|
//compute total body force, including input body force (Gx,Gy,Gz)
|
||||||
Fx = Gx + rhoE*Ex;
|
Fx = Gx + rhoE*Ex*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;//the extra factors at the end necessarily convert unit from phys to LB
|
||||||
Fy = Gy + rhoE*Ey;
|
Fy = Gy + rhoE*Ey*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;
|
||||||
Fz = Gz + rhoE*Ez;
|
Fz = Gz + rhoE*Ez*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;
|
||||||
|
|
||||||
// q=0
|
// q=0
|
||||||
fq = dist[n];
|
fq = dist[n];
|
||||||
@@ -311,9 +310,9 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
|
|||||||
m18 -= fq;
|
m18 -= fq;
|
||||||
|
|
||||||
// write the velocity
|
// write the velocity
|
||||||
ux = jx / rho;
|
ux = jx / rho0;
|
||||||
uy = jy / rho;
|
uy = jy / rho0;
|
||||||
uz = jz / rho;
|
uz = jz / rho0;
|
||||||
Velocity[n] = ux;
|
Velocity[n] = ux;
|
||||||
Velocity[Np+n] = uy;
|
Velocity[Np+n] = uy;
|
||||||
Velocity[2*Np+n] = uz;
|
Velocity[2*Np+n] = uz;
|
||||||
@@ -326,18 +325,18 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
|
|||||||
|
|
||||||
//..............incorporate external force................................................
|
//..............incorporate external force................................................
|
||||||
//..............carry out relaxation process...............................................
|
//..............carry out relaxation process...............................................
|
||||||
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
|
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) - m1);
|
||||||
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
|
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0) - m2);
|
||||||
m4 = m4 + rlx_setB*((-0.6666666666666666*jx) - m4);
|
m4 = m4 + rlx_setB*((-0.6666666666666666*jx) - m4);
|
||||||
m6 = m6 + rlx_setB*((-0.6666666666666666*jy) - m6);
|
m6 = m6 + rlx_setB*((-0.6666666666666666*jy) - m6);
|
||||||
m8 = m8 + rlx_setB*((-0.6666666666666666*jz) - m8);
|
m8 = m8 + rlx_setB*((-0.6666666666666666*jz) - m8);
|
||||||
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho) - m9);
|
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho0) - m9);
|
||||||
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
||||||
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho) - m11);
|
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho0) - m11);
|
||||||
m12 = m12 + rlx_setA*(-0.5*((jy*jy-jz*jz)/rho) - m12);
|
m12 = m12 + rlx_setA*(-0.5*((jy*jy-jz*jz)/rho0) - m12);
|
||||||
m13 = m13 + rlx_setA*((jx*jy/rho) - m13);
|
m13 = m13 + rlx_setA*((jx*jy/rho0) - m13);
|
||||||
m14 = m14 + rlx_setA*((jy*jz/rho) - m14);
|
m14 = m14 + rlx_setA*((jy*jz/rho0) - m14);
|
||||||
m15 = m15 + rlx_setA*((jx*jz/rho) - m15);
|
m15 = m15 + rlx_setA*((jx*jz/rho0) - m15);
|
||||||
m16 = m16 + rlx_setB*( - m16);
|
m16 = m16 + rlx_setB*( - m16);
|
||||||
m17 = m17 + rlx_setB*( - m17);
|
m17 = m17 + rlx_setB*( - m17);
|
||||||
m18 = m18 + rlx_setB*( - m18);
|
m18 = m18 + rlx_setB*( - m18);
|
||||||
@@ -454,8 +453,7 @@ extern "C" void ScaLBL_D3Q19_AAeven_StokesMRT(double *dist, double *Velocity, do
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB,
|
extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, double *Velocity, double *ChargeDensity, double *ElectricField, double rlx_setA, double rlx_setB, double Gx, double Gy, double Gz, double rho0, double den_scale, double h, double time_conv,int start, int finish, int Np)
|
||||||
double Gx, double Gy, double Gz, double Ex_const, double Ey_const, double Ez_const, int start, int finish, int Np)
|
|
||||||
{
|
{
|
||||||
double fq;
|
double fq;
|
||||||
// conserved momemnts
|
// conserved momemnts
|
||||||
@@ -487,13 +485,13 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
|
|||||||
|
|
||||||
//Load data
|
//Load data
|
||||||
rhoE = ChargeDensity[n];
|
rhoE = ChargeDensity[n];
|
||||||
Ex = ElectricField[n+0*Np]+Ex_const;
|
Ex = ElectricField[n+0*Np];
|
||||||
Ey = ElectricField[n+1*Np]+Ey_const;
|
Ey = ElectricField[n+1*Np];
|
||||||
Ez = ElectricField[n+2*Np]+Ez_const;
|
Ez = ElectricField[n+2*Np];
|
||||||
//compute total body force, including input body force (Gx,Gy,Gz)
|
//compute total body force, including input body force (Gx,Gy,Gz)
|
||||||
Fx = Gx + rhoE*Ex;
|
Fx = Gx + rhoE*Ex*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;
|
||||||
Fy = Gy + rhoE*Ey;
|
Fy = Gy + rhoE*Ey*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;
|
||||||
Fz = Gz + rhoE*Ez;
|
Fz = Gz + rhoE*Ez*(time_conv*time_conv)/(h*h*1.0e-12)/den_scale;
|
||||||
|
|
||||||
// q=0
|
// q=0
|
||||||
fq = dist[n];
|
fq = dist[n];
|
||||||
@@ -803,27 +801,27 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
|
|||||||
m18 -= fq;
|
m18 -= fq;
|
||||||
|
|
||||||
// write the velocity
|
// write the velocity
|
||||||
ux = jx / rho;
|
ux = jx / rho0;
|
||||||
uy = jy / rho;
|
uy = jy / rho0;
|
||||||
uz = jz / rho;
|
uz = jz / rho0;
|
||||||
Velocity[n] = ux;
|
Velocity[n] = ux;
|
||||||
Velocity[Np+n] = uy;
|
Velocity[Np+n] = uy;
|
||||||
Velocity[2*Np+n] = uz;
|
Velocity[2*Np+n] = uz;
|
||||||
|
|
||||||
//..............incorporate external force................................................
|
//..............incorporate external force................................................
|
||||||
//..............carry out relaxation process...............................................
|
//..............carry out relaxation process...............................................
|
||||||
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho - 11*rho) - m1);
|
m1 = m1 + rlx_setA*((19*(jx*jx+jy*jy+jz*jz)/rho0 - 11*rho) - m1);
|
||||||
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho) - m2);
|
m2 = m2 + rlx_setA*((3*rho - 5.5*(jx*jx+jy*jy+jz*jz)/rho0) - m2);
|
||||||
m4 = m4 + rlx_setB*((-0.6666666666666666*jx) - m4);
|
m4 = m4 + rlx_setB*((-0.6666666666666666*jx) - m4);
|
||||||
m6 = m6 + rlx_setB*((-0.6666666666666666*jy) - m6);
|
m6 = m6 + rlx_setB*((-0.6666666666666666*jy) - m6);
|
||||||
m8 = m8 + rlx_setB*((-0.6666666666666666*jz) - m8);
|
m8 = m8 + rlx_setB*((-0.6666666666666666*jz) - m8);
|
||||||
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho) - m9);
|
m9 = m9 + rlx_setA*(((2*jx*jx-jy*jy-jz*jz)/rho0) - m9);
|
||||||
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
m10 = m10 + rlx_setA*(-0.5*((2*jx*jx-jy*jy-jz*jz)/rho) - m10);
|
||||||
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho) - m11);
|
m11 = m11 + rlx_setA*(((jy*jy-jz*jz)/rho0) - m11);
|
||||||
m12 = m12 + rlx_setA*(-0.5*((jy*jy-jz*jz)/rho) - m12);
|
m12 = m12 + rlx_setA*(-0.5*((jy*jy-jz*jz)/rho0) - m12);
|
||||||
m13 = m13 + rlx_setA*((jx*jy/rho) - m13);
|
m13 = m13 + rlx_setA*((jx*jy/rho0) - m13);
|
||||||
m14 = m14 + rlx_setA*((jy*jz/rho) - m14);
|
m14 = m14 + rlx_setA*((jy*jz/rho0) - m14);
|
||||||
m15 = m15 + rlx_setA*((jx*jz/rho) - m15);
|
m15 = m15 + rlx_setA*((jx*jz/rho0) - m15);
|
||||||
m16 = m16 + rlx_setB*( - m16);
|
m16 = m16 + rlx_setB*( - m16);
|
||||||
m17 = m17 + rlx_setB*( - m17);
|
m17 = m17 + rlx_setB*( - m17);
|
||||||
m18 = m18 + rlx_setB*( - m18);
|
m18 = m18 + rlx_setB*( - m18);
|
||||||
@@ -955,47 +953,47 @@ extern "C" void ScaLBL_D3Q19_AAodd_StokesMRT(int *neighborList, double *dist, do
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ScaLBL_D3Q19_Momentum_Phys(double *dist, double *vel, double h, double time_conv, int Np)
|
//extern "C" void ScaLBL_D3Q19_Momentum_Phys(double *dist, double *vel, double h, double time_conv, int Np)
|
||||||
{
|
//{
|
||||||
//h: resolution [um/lu]
|
// //h: resolution [um/lu]
|
||||||
//time_conv: time conversion factor [sec/lt]
|
// //time_conv: time conversion factor [sec/lt]
|
||||||
int n;
|
// int n;
|
||||||
// distributions
|
// // distributions
|
||||||
double f1,f2,f3,f4,f5,f6,f7,f8,f9;
|
// double f1,f2,f3,f4,f5,f6,f7,f8,f9;
|
||||||
double f10,f11,f12,f13,f14,f15,f16,f17,f18;
|
// double f10,f11,f12,f13,f14,f15,f16,f17,f18;
|
||||||
double vx,vy,vz;
|
// double vx,vy,vz;
|
||||||
|
//
|
||||||
for (n=0; n<Np; n++){
|
// for (n=0; n<Np; n++){
|
||||||
//........................................................................
|
// //........................................................................
|
||||||
// Registers to store the distributions
|
// // Registers to store the distributions
|
||||||
//........................................................................
|
// //........................................................................
|
||||||
f2 = dist[2*Np+n];
|
// f2 = dist[2*Np+n];
|
||||||
f4 = dist[4*Np+n];
|
// f4 = dist[4*Np+n];
|
||||||
f6 = dist[6*Np+n];
|
// f6 = dist[6*Np+n];
|
||||||
f8 = dist[8*Np+n];
|
// f8 = dist[8*Np+n];
|
||||||
f10 = dist[10*Np+n];
|
// f10 = dist[10*Np+n];
|
||||||
f12 = dist[12*Np+n];
|
// f12 = dist[12*Np+n];
|
||||||
f14 = dist[14*Np+n];
|
// f14 = dist[14*Np+n];
|
||||||
f16 = dist[16*Np+n];
|
// f16 = dist[16*Np+n];
|
||||||
f18 = dist[18*Np+n];
|
// f18 = dist[18*Np+n];
|
||||||
//........................................................................
|
// //........................................................................
|
||||||
f1 = dist[Np+n];
|
// f1 = dist[Np+n];
|
||||||
f3 = dist[3*Np+n];
|
// f3 = dist[3*Np+n];
|
||||||
f5 = dist[5*Np+n];
|
// f5 = dist[5*Np+n];
|
||||||
f7 = dist[7*Np+n];
|
// f7 = dist[7*Np+n];
|
||||||
f9 = dist[9*Np+n];
|
// f9 = dist[9*Np+n];
|
||||||
f11 = dist[11*Np+n];
|
// f11 = dist[11*Np+n];
|
||||||
f13 = dist[13*Np+n];
|
// f13 = dist[13*Np+n];
|
||||||
f15 = dist[15*Np+n];
|
// f15 = dist[15*Np+n];
|
||||||
f17 = dist[17*Np+n];
|
// f17 = dist[17*Np+n];
|
||||||
//.................Compute the velocity...................................
|
// //.................Compute the velocity...................................
|
||||||
vx = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
|
// vx = f1-f2+f7-f8+f9-f10+f11-f12+f13-f14;
|
||||||
vy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
|
// vy = f3-f4+f7-f8-f9+f10+f15-f16+f17-f18;
|
||||||
vz = f5-f6+f11-f12-f13+f14+f15-f16-f17+f18;
|
// vz = f5-f6+f11-f12-f13+f14+f15-f16-f17+f18;
|
||||||
//..................Write the velocity.....................................
|
// //..................Write the velocity.....................................
|
||||||
vel[0*Np+n] = vx*(h*1.0e-6)/time_conv;
|
// vel[0*Np+n] = vx*(h*1.0e-6)/time_conv;
|
||||||
vel[1*Np+n] = vy*(h*1.0e-6)/time_conv;
|
// vel[1*Np+n] = vy*(h*1.0e-6)/time_conv;
|
||||||
vel[2*Np+n] = vz*(h*1.0e-6)/time_conv;
|
// vel[2*Np+n] = vz*(h*1.0e-6)/time_conv;
|
||||||
//........................................................................
|
// //........................................................................
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@@ -364,11 +364,16 @@ void ScaLBL_IonModel::Initialize(){
|
|||||||
|
|
||||||
void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){
|
void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){
|
||||||
|
|
||||||
|
//Input parameter:
|
||||||
|
//1. Velocity is from StokesModel
|
||||||
|
//2. ElectricField is from Poisson model
|
||||||
|
|
||||||
//LB-related parameter
|
//LB-related parameter
|
||||||
vector<double> rlx(tau.begin(),tau.end());
|
vector<double> rlx(tau.begin(),tau.end());
|
||||||
for (double item : rlx){
|
for (double item : rlx){
|
||||||
item = 1.0/item;
|
item = 1.0/item;
|
||||||
}
|
}
|
||||||
|
|
||||||
//.......create and start timer............
|
//.......create and start timer............
|
||||||
//double starttime,stoptime,cputime;
|
//double starttime,stoptime,cputime;
|
||||||
//ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
//ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
@@ -462,7 +467,9 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaLBL_IonModel::getIonConcentration(){
|
//TODO this ruin the ion concentration on device
|
||||||
|
//need to do something similar to electric field
|
||||||
|
void ScaLBL_IonModel::getIonConcentration(int timestep){
|
||||||
for (int ic=0; ic<number_ion_species; ic++){
|
for (int ic=0; ic<number_ion_species; ic++){
|
||||||
ScaLBL_IonConcentration_Phys(Ci, h, ic, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
ScaLBL_IonConcentration_Phys(Ci, h, ic, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
ScaLBL_IonConcentration_Phys(Ci, h, ic, 0, ScaLBL_Comm->LastExterior(), Np);
|
ScaLBL_IonConcentration_Phys(Ci, h, ic, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
@@ -474,7 +481,7 @@ void ScaLBL_IonModel::getIonConcentration(){
|
|||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
|
||||||
FILE *OUTFILE;
|
FILE *OUTFILE;
|
||||||
sprintf(LocalRankFilename,"Ion%02i.%05i.raw",ic+1,rank);
|
sprintf(LocalRankFilename,"Ion%02i_Time_%i.%05i.raw",ic+1,timestep,rank);
|
||||||
OUTFILE = fopen(LocalRankFilename,"wb");
|
OUTFILE = fopen(LocalRankFilename,"wb");
|
||||||
fwrite(PhaseField.data(),8,N,OUTFILE);
|
fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||||
fclose(OUTFILE);
|
fclose(OUTFILE);
|
||||||
@@ -482,3 +489,23 @@ void ScaLBL_IonModel::getIonConcentration(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void ScaLBL_IonModel::getIonConcentration(){
|
||||||
|
// for (int ic=0; ic<number_ion_species; ic++){
|
||||||
|
// ScaLBL_IonConcentration_Phys(Ci, h, ic, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
// ScaLBL_IonConcentration_Phys(Ci, h, ic, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
|
// for (int ic=0; ic<number_ion_species; ic++){
|
||||||
|
// ScaLBL_Comm->RegularLayout(Map,&Ci[ic*Np],PhaseField);
|
||||||
|
// ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
//
|
||||||
|
// FILE *OUTFILE;
|
||||||
|
// sprintf(LocalRankFilename,"Ion%02i.%05i.raw",ic+1,rank);
|
||||||
|
// OUTFILE = fopen(LocalRankFilename,"wb");
|
||||||
|
// fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||||
|
// fclose(OUTFILE);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public:
|
|||||||
void Create();
|
void Create();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Run(double *Velocity, double *ElectricField);
|
void Run(double *Velocity, double *ElectricField);
|
||||||
void getIonConcentration();
|
void getIonConcentration(int timestep);
|
||||||
|
|
||||||
//bool Restart,pBC;
|
//bool Restart,pBC;
|
||||||
int timestep,timestepMax;
|
int timestep,timestepMax;
|
||||||
@@ -40,6 +40,7 @@ public:
|
|||||||
double kb,electron_charge,T,Vt;
|
double kb,electron_charge,T,Vt;
|
||||||
double k2_inv;
|
double k2_inv;
|
||||||
double tolerance;
|
double tolerance;
|
||||||
|
double Ex,Ey,Ez;
|
||||||
|
|
||||||
int number_ion_species;
|
int number_ion_species;
|
||||||
vector<double> IonDiffusivity;//User input unit [m^2/sec]
|
vector<double> IonDiffusivity;//User input unit [m^2/sec]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
ScaLBL_Poisson::ScaLBL_Poisson(int RANK, int NP, MPI_Comm COMM):
|
ScaLBL_Poisson::ScaLBL_Poisson(int RANK, int NP, MPI_Comm COMM):
|
||||||
rank(RANK), nprocs(NP),timestep(0),timestepMax(0),tau(0),k2_inv(0),gamma(0),tolerance(0),h(0),
|
rank(RANK), nprocs(NP),timestep(0),timestepMax(0),tau(0),k2_inv(0),gamma(0),tolerance(0),h(0),
|
||||||
epsilon0(0),epsilon0_LB(0),epsilonR(0),epsilon_LB(0),Nx(0),Ny(0),Nz(0),N(0),Np(0),analysis_interval(0),
|
epsilon0(0),epsilon0_LB(0),epsilonR(0),epsilon_LB(0),Vin(0),Vout(0),Nx(0),Ny(0),Nz(0),N(0),Np(0),analysis_interval(0),
|
||||||
nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),BoundaryConditionSolid(0),Lx(0),Ly(0),Lz(0),comm(COMM)
|
nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),BoundaryConditionSolid(0),Lx(0),Ly(0),Lz(0),comm(COMM)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -22,17 +22,20 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
|||||||
domain_db = db->getDatabase( "Domain" );
|
domain_db = db->getDatabase( "Domain" );
|
||||||
electric_db = db->getDatabase( "Poisson" );
|
electric_db = db->getDatabase( "Poisson" );
|
||||||
|
|
||||||
k2_inv = 4.5;//speed of sound for D3Q7 lattice
|
//k2_inv = 4.5;//speed of sound for D3Q7 lattice
|
||||||
gamma = 0.3;//time step of LB-Poisson equation
|
k2_inv = 4.0;//speed of sound for D3Q7 lattice
|
||||||
|
gamma = 1.0;//time step of LB-Poisson equation
|
||||||
tau = 0.5+k2_inv*gamma;
|
tau = 0.5+k2_inv*gamma;
|
||||||
timestepMax = 100000;
|
timestepMax = 100000;
|
||||||
tolerance = 1.0e-6;//stopping criterion for obtaining steady-state electricla potential
|
tolerance = 1.0e-6;//stopping criterion for obtaining steady-state electricla potential
|
||||||
h = 1.0;//resolution; unit: um/lu
|
h = 1.0;//resolution; unit: um/lu
|
||||||
epsilon0 = 8.85e-12;//electrical permittivity of vaccum; unit:[C/(V*m)]
|
epsilon0 = 8.85e-12;//electric permittivity of vaccum; unit:[C/(V*m)]
|
||||||
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
||||||
epsilonR = 78.4;//default dielectric constant of water
|
epsilonR = 78.4;//default dielectric constant of water
|
||||||
epsilon_LB = epsilon0_LB*epsilonR;//electrical permittivity
|
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||||
analysis_interval = 1000;
|
analysis_interval = 1000;
|
||||||
|
Vin = 1.0; //Boundary-z (inlet) electric potential
|
||||||
|
Vout = 1.0; //Boundary-Z (outlet) electric potential
|
||||||
|
|
||||||
// LB-Poisson Model parameters
|
// LB-Poisson Model parameters
|
||||||
if (electric_db->keyExists( "timestepMax" )){
|
if (electric_db->keyExists( "timestepMax" )){
|
||||||
@@ -56,20 +59,23 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
|||||||
if (electric_db->keyExists( "BC_Solid" )){
|
if (electric_db->keyExists( "BC_Solid" )){
|
||||||
BoundaryConditionSolid = electric_db->getScalar<int>( "BC_Solid" );
|
BoundaryConditionSolid = electric_db->getScalar<int>( "BC_Solid" );
|
||||||
}
|
}
|
||||||
|
// Read boundary condition for electric potentiona
|
||||||
|
// BC = 0: normal periodic BC
|
||||||
|
// BC = 1: fixed inlet and outlet potential
|
||||||
|
BoundaryCondition = 0;
|
||||||
|
if (electric_db->keyExists( "BC" )){
|
||||||
|
BoundaryCondition = electric_db->getScalar<int>( "BC" );
|
||||||
|
}
|
||||||
|
|
||||||
// Read domain parameters
|
// Read domain parameters
|
||||||
if (domain_db->keyExists( "voxel_length" )){//default unit: um/lu
|
if (domain_db->keyExists( "voxel_length" )){//default unit: um/lu
|
||||||
h = domain_db->getScalar<double>( "voxel_length" );
|
h = domain_db->getScalar<double>( "voxel_length" );
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundaryCondition = 0;
|
|
||||||
if (domain_db->keyExists( "BC" )){
|
|
||||||
BoundaryCondition = domain_db->getScalar<int>( "BC" );
|
|
||||||
}
|
|
||||||
|
|
||||||
//Re-calcualte model parameters if user updates input
|
//Re-calcualte model parameters if user updates input
|
||||||
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
epsilon0_LB = epsilon0*(h*1.0e-6);//unit:[C/(V*lu)]
|
||||||
epsilon_LB = epsilon0_LB*epsilonR;//electrical permittivity
|
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||||
tau = 0.5+k2_inv*gamma;
|
tau = 0.5+k2_inv*gamma;
|
||||||
|
|
||||||
if (rank==0) printf("***********************************************************************************\n");
|
if (rank==0) printf("***********************************************************************************\n");
|
||||||
@@ -202,13 +208,13 @@ void ScaLBL_Poisson::AssignSolidBoundary(double *poisson_solid)
|
|||||||
AFFINITY=0.f;
|
AFFINITY=0.f;
|
||||||
// Assign the affinity from the paired list
|
// Assign the affinity from the paired list
|
||||||
for (unsigned int idx=0; idx < NLABELS; idx++){
|
for (unsigned int idx=0; idx < NLABELS; idx++){
|
||||||
//printf("idx=%i, value=%i, %i, \n",idx, VALUE,LabelList[idx]);
|
|
||||||
if (VALUE == LabelList[idx]){
|
if (VALUE == LabelList[idx]){
|
||||||
AFFINITY=AffinityList[idx];
|
AFFINITY=AffinityList[idx];
|
||||||
//NOTE need to convert the user input phys unit to LB unit
|
//NOTE need to convert the user input phys unit to LB unit
|
||||||
if (BoundaryConditionSolid==2){
|
if (BoundaryConditionSolid==2){
|
||||||
//for BCS=1, i.e. Dirichlet-type, no need for unit conversion
|
//for BCS=1, i.e. Dirichlet-type, no need for unit conversion
|
||||||
AFFINITY = AFFINITY*(h*h*1.0e-12);
|
//TODO maybe there is a factor of gamm missing here ?
|
||||||
|
AFFINITY = AFFINITY*(h*h*1.0e-12)/epsilon_LB;
|
||||||
}
|
}
|
||||||
label_count[idx] += 1.0;
|
label_count[idx] += 1.0;
|
||||||
idx = NLABELS;
|
idx = NLABELS;
|
||||||
@@ -244,7 +250,6 @@ void ScaLBL_Poisson::AssignSolidBoundary(double *poisson_solid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScaLBL_Poisson::Create(){
|
void ScaLBL_Poisson::Create(){
|
||||||
/*
|
/*
|
||||||
* This function creates the variables needed to run a LBM
|
* This function creates the variables needed to run a LBM
|
||||||
@@ -260,6 +265,7 @@ void ScaLBL_Poisson::Create(){
|
|||||||
// Create a communicator for the device (will use optimized layout)
|
// Create a communicator for the device (will use optimized layout)
|
||||||
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original
|
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original
|
||||||
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||||
|
ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||||
|
|
||||||
int Npad=(Np/16 + 2)*16;
|
int Npad=(Np/16 + 2)*16;
|
||||||
if (rank==0) printf ("LB-Poisson Solver: Set up memory efficient layout \n");
|
if (rank==0) printf ("LB-Poisson Solver: Set up memory efficient layout \n");
|
||||||
@@ -277,37 +283,125 @@ void ScaLBL_Poisson::Create(){
|
|||||||
int neighborSize=18*(Np*sizeof(int));
|
int neighborSize=18*(Np*sizeof(int));
|
||||||
//...........................................................................
|
//...........................................................................
|
||||||
ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize);
|
ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize);
|
||||||
|
ScaLBL_AllocateDeviceMemory((void **) &dvcMap, sizeof(int)*Np);
|
||||||
|
ScaLBL_AllocateDeviceMemory((void **) &dvcID, sizeof(signed char)*Nx*Ny*Nz);
|
||||||
ScaLBL_AllocateDeviceMemory((void **) &fq, 7*dist_mem_size);
|
ScaLBL_AllocateDeviceMemory((void **) &fq, 7*dist_mem_size);
|
||||||
ScaLBL_AllocateDeviceMemory((void **) &Psi, sizeof(double)*Np);
|
ScaLBL_AllocateDeviceMemory((void **) &Psi, sizeof(double)*Nx*Ny*Nz);
|
||||||
ScaLBL_AllocateDeviceMemory((void **) &ElectricField, 3*sizeof(double)*Np);
|
ScaLBL_AllocateDeviceMemory((void **) &ElectricField, 3*sizeof(double)*Np);
|
||||||
ScaLBL_AllocateDeviceMemory((void **) &PoissonSolid, sizeof(double)*Nx*Ny*Nz);
|
//ScaLBL_AllocateDeviceMemory((void **) &PoissonSolid, sizeof(double)*Nx*Ny*Nz);
|
||||||
//...........................................................................
|
//...........................................................................
|
||||||
|
|
||||||
// Update GPU data structures
|
// Update GPU data structures
|
||||||
if (rank==0) printf ("LB-Poisson Solver: Setting up device map and neighbor list \n");
|
if (rank==0) printf ("LB-Poisson Solver: Setting up device map and neighbor list \n");
|
||||||
|
fflush(stdout);
|
||||||
|
int *TmpMap;
|
||||||
|
TmpMap=new int[Np];
|
||||||
|
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))
|
||||||
|
TmpMap[idx] = k*Nx*Ny+j*Nx+i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check that TmpMap is valid
|
||||||
|
for (int idx=0; idx<ScaLBL_Comm->LastExterior(); idx++){
|
||||||
|
auto n = TmpMap[idx];
|
||||||
|
if (n > Nx*Ny*Nz){
|
||||||
|
printf("Bad value! idx=%i \n", n);
|
||||||
|
TmpMap[idx] = Nx*Ny*Nz-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int idx=ScaLBL_Comm->FirstInterior(); idx<ScaLBL_Comm->LastInterior(); idx++){
|
||||||
|
auto n = TmpMap[idx];
|
||||||
|
if ( n > Nx*Ny*Nz ){
|
||||||
|
printf("Bad value! idx=%i \n",n);
|
||||||
|
TmpMap[idx] = Nx*Ny*Nz-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScaLBL_CopyToDevice(dvcMap, TmpMap, sizeof(int)*Np);
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
|
delete [] TmpMap;
|
||||||
// copy the neighbor list
|
// copy the neighbor list
|
||||||
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
||||||
ScaLBL_DeviceBarrier();
|
ScaLBL_DeviceBarrier();
|
||||||
MPI_Barrier(comm);
|
MPI_Barrier(comm);
|
||||||
|
delete [] neighborList;
|
||||||
|
// copy node ID
|
||||||
|
ScaLBL_CopyToDevice(dvcID, Mask->id, sizeof(signed char)*Nx*Ny*Nz);
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
|
|
||||||
//Initialize solid boundary for electrical potential
|
//Initialize solid boundary for electric potential
|
||||||
ScaLBL_Comm->SetupBounceBackList(Map, Mask->id, Np);
|
ScaLBL_Comm->SetupBounceBackList(Map, Mask->id, Np);
|
||||||
MPI_Barrier(comm);
|
MPI_Barrier(comm);
|
||||||
|
|
||||||
double *PoissonSolid_host;
|
//double *PoissonSolid_host;
|
||||||
PoissonSolid_host = new double[Nx*Ny*Nz];
|
//PoissonSolid_host = new double[Nx*Ny*Nz];
|
||||||
AssignSolidBoundary(PoissonSolid_host);
|
//AssignSolidBoundary(PoissonSolid_host);
|
||||||
ScaLBL_CopyToDevice(PoissonSolid, PoissonSolid_host, Nx*Ny*Nz*sizeof(double));
|
//ScaLBL_CopyToDevice(PoissonSolid, PoissonSolid_host, Nx*Ny*Nz*sizeof(double));
|
||||||
ScaLBL_DeviceBarrier();
|
//ScaLBL_DeviceBarrier();
|
||||||
delete [] PoissonSolid_host;
|
//delete [] PoissonSolid_host;
|
||||||
}
|
}
|
||||||
|
// Method 1
|
||||||
|
// Psi - size N
|
||||||
|
// ID_dvc - size N
|
||||||
|
// Method 2
|
||||||
|
// Psi - size Np
|
||||||
|
// PoissonSolid size N
|
||||||
|
|
||||||
|
void ScaLBL_Poisson::Potential_Init(double *psi_init){
|
||||||
|
|
||||||
|
if (BoundaryCondition==1){
|
||||||
|
if (electric_db->keyExists( "Vin" )){
|
||||||
|
Vin = electric_db->getScalar<double>( "Vin" );
|
||||||
|
}
|
||||||
|
if (electric_db->keyExists( "Vout" )){
|
||||||
|
Vout = electric_db->getScalar<double>( "Vout" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//By default only periodic BC is applied and Vin=Vout=1.0, i.e. there is no potential gradient along Z-axis
|
||||||
|
double slope = (Vout-Vin)/(Nz-2);
|
||||||
|
double psi_linearized;
|
||||||
|
for (int k=0;k<Nz;k++){
|
||||||
|
if (k==0 || k==1){
|
||||||
|
psi_linearized = Vin;
|
||||||
|
}
|
||||||
|
else if (k==Nz-1 || k==Nz-2){
|
||||||
|
psi_linearized = Vout;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
psi_linearized = slope*(k-1)+Vin;
|
||||||
|
}
|
||||||
|
for (int j=0;j<Ny;j++){
|
||||||
|
for (int i=0;i<Nx;i++){
|
||||||
|
int n = k*Nx*Ny+j*Nx+i;
|
||||||
|
if (Mask->id[n]>0){
|
||||||
|
psi_init[n] = psi_linearized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScaLBL_Poisson::Initialize(){
|
void ScaLBL_Poisson::Initialize(){
|
||||||
/*
|
/*
|
||||||
* This function initializes model
|
* This function initializes model
|
||||||
*/
|
*/
|
||||||
if (rank==0) printf ("LB-Poisson Solver: initializing D3Q7 distributions\n");
|
if (rank==0) printf ("LB-Poisson Solver: initializing D3Q7 distributions\n");
|
||||||
ScaLBL_D3Q7_Poisson_Init(fq, Np);
|
//NOTE the initialization involves two steps:
|
||||||
|
//1. assign solid boundary value (surface potential or surface change density)
|
||||||
|
//2. Initialize electric potential for pore nodes
|
||||||
|
double *psi_host;
|
||||||
|
psi_host = new double [Nx*Ny*Nz];
|
||||||
|
AssignSolidBoundary(psi_host);//step1
|
||||||
|
Potential_Init(psi_host);//step2
|
||||||
|
ScaLBL_CopyToDevice(Psi, psi_host, Nx*Ny*Nz*sizeof(double));
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
|
ScaLBL_D3Q7_Poisson_Init(dvcMap, fq, Psi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
ScaLBL_D3Q7_Poisson_Init(dvcMap, fq, Psi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
delete [] psi_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaLBL_Poisson::Run(double *ChargeDensity){
|
void ScaLBL_Poisson::Run(double *ChargeDensity){
|
||||||
@@ -325,30 +419,83 @@ void ScaLBL_Poisson::Run(double *ChargeDensity){
|
|||||||
// *************ODD TIMESTEP*************//
|
// *************ODD TIMESTEP*************//
|
||||||
timestep++;
|
timestep++;
|
||||||
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FROM NORMAL
|
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FROM NORMAL
|
||||||
ScaLBL_D3Q7_AAodd_Poisson(NeighborList, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(NeighborList, dvcMap, fq, Psi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
ScaLBL_Comm->RecvD3Q7AA(fq, 0); //WRITE INTO OPPOSITE
|
ScaLBL_Comm->RecvD3Q7AA(fq, 0); //WRITE INTO OPPOSITE
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
// Set boundary conditions
|
// Set boundary conditions
|
||||||
/* ... */
|
if (BoundaryCondition == 1){
|
||||||
ScaLBL_D3Q7_AAodd_Poisson(NeighborList, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, 0, ScaLBL_Comm->LastExterior(), Np);
|
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||||
ScaLBL_Comm->SolidDirichletD3Q7(fq, PoissonSolid);
|
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||||
|
}
|
||||||
|
//-------------------------//
|
||||||
|
ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(NeighborList, dvcMap, fq, Psi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
|
||||||
|
//compute electric field
|
||||||
|
ScaLBL_Comm_Regular->SendHalo(Psi);
|
||||||
|
ScaLBL_D3Q7_Poisson_ElectricField(NeighborList, dvcMap, dvcID, Psi, ElectricField, BoundaryConditionSolid,
|
||||||
|
Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
ScaLBL_Comm_Regular->RecvHalo(Psi);
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
|
if (BoundaryCondition == 1){
|
||||||
|
ScaLBL_Comm->Poisson_D3Q7_BC_z(dvcMap,Psi,Vin);
|
||||||
|
ScaLBL_Comm->Poisson_D3Q7_BC_Z(dvcMap,Psi,Vout);
|
||||||
|
}
|
||||||
|
ScaLBL_D3Q7_Poisson_ElectricField(NeighborList, dvcMap, dvcID, Psi, ElectricField, BoundaryConditionSolid, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
|
||||||
|
//perform collision
|
||||||
|
ScaLBL_D3Q7_AAodd_Poisson(NeighborList, dvcMap, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
ScaLBL_D3Q7_AAodd_Poisson(NeighborList, dvcMap, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
if (BoundaryConditionSolid==1){
|
||||||
|
ScaLBL_Comm->SolidDirichletD3Q7(fq, Psi);
|
||||||
|
}
|
||||||
|
else if (BoundaryConditionSolid==2){
|
||||||
|
ScaLBL_Comm->SolidNeumannD3Q7(fq, Psi);
|
||||||
|
}
|
||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
|
||||||
// *************EVEN TIMESTEP*************//
|
// *************EVEN TIMESTEP*************//
|
||||||
timestep++;
|
timestep++;
|
||||||
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FORM NORMAL
|
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FORM NORMAL
|
||||||
ScaLBL_D3Q7_AAeven_Poisson(fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(dvcMap, fq, Psi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
ScaLBL_Comm->RecvD3Q7AA(fq, 0); //WRITE INTO OPPOSITE
|
ScaLBL_Comm->RecvD3Q7AA(fq, 0); //WRITE INTO OPPOSITE
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
// Set boundary conditions
|
// Set boundary conditions
|
||||||
/* ... */
|
if (BoundaryCondition == 1){
|
||||||
ScaLBL_D3Q7_AAeven_Poisson(fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, 0, ScaLBL_Comm->LastExterior(), Np);
|
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||||
ScaLBL_Comm->SolidDirichletD3Q7(fq, PoissonSolid);
|
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||||
|
}
|
||||||
|
//-------------------------//
|
||||||
|
ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(dvcMap, fq, Psi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
|
||||||
|
//compute electric field
|
||||||
|
ScaLBL_Comm_Regular->SendHalo(Psi);
|
||||||
|
ScaLBL_D3Q7_Poisson_ElectricField(NeighborList, dvcMap, dvcID, Psi, ElectricField, BoundaryConditionSolid,
|
||||||
|
Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
ScaLBL_Comm_Regular->RecvHalo(Psi);
|
||||||
|
ScaLBL_DeviceBarrier();
|
||||||
|
if (BoundaryCondition == 1){
|
||||||
|
ScaLBL_Comm->Poisson_D3Q7_BC_z(dvcMap,Psi,Vin);
|
||||||
|
ScaLBL_Comm->Poisson_D3Q7_BC_Z(dvcMap,Psi,Vout);
|
||||||
|
}
|
||||||
|
ScaLBL_D3Q7_Poisson_ElectricField(NeighborList, dvcMap, dvcID, Psi, ElectricField, BoundaryConditionSolid, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
|
||||||
|
//perform collision
|
||||||
|
ScaLBL_D3Q7_AAeven_Poisson(dvcMap, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
|
ScaLBL_D3Q7_AAeven_Poisson(dvcMap, fq, ChargeDensity, Psi, ElectricField, tau, epsilon_LB, gamma, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||||
|
if (BoundaryConditionSolid==1){
|
||||||
|
ScaLBL_Comm->SolidDirichletD3Q7(fq, Psi);
|
||||||
|
}
|
||||||
|
else if (BoundaryConditionSolid==2){
|
||||||
|
ScaLBL_Comm->SolidNeumannD3Q7(fq, Psi);
|
||||||
|
}
|
||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
//************************************************************************/
|
//************************************************************************/
|
||||||
|
|
||||||
// Check convergence of steady-state solution
|
// Check convergence of steady-state solution
|
||||||
if (timestep%analysis_interval==0){
|
if (timestep%analysis_interval==0){
|
||||||
|
|
||||||
ScaLBL_Comm->RegularLayout(Map,Psi,Psi_host);
|
//ScaLBL_Comm->RegularLayout(Map,Psi,Psi_host);
|
||||||
|
ScaLBL_CopyToHost(Psi_host.data(),Psi,sizeof(double)*Nx*Ny*Nz);
|
||||||
double count_loc=0;
|
double count_loc=0;
|
||||||
double count;
|
double count;
|
||||||
double psi_avg;
|
double psi_avg;
|
||||||
@@ -393,14 +540,180 @@ void ScaLBL_Poisson::Run(double *ChargeDensity){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaLBL_Poisson::getElectricalPotential(){
|
void ScaLBL_Poisson::getElectricPotential(int timestep){
|
||||||
|
|
||||||
DoubleArray PhaseField(Nx,Ny,Nz);
|
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
ScaLBL_Comm->RegularLayout(Map,Psi,PhaseField);
|
//ScaLBL_Comm->RegularLayout(Map,Psi,PhaseField);
|
||||||
|
ScaLBL_CopyToHost(PhaseField.data(),Psi,sizeof(double)*Nx*Ny*Nz);
|
||||||
//ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
//ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
FILE *OUTFILE;
|
FILE *OUTFILE;
|
||||||
sprintf(LocalRankFilename,"Electrical_Potential.%05i.raw",rank);
|
sprintf(LocalRankFilename,"Electric_Potential_Time_%i.%05i.raw",timestep,rank);
|
||||||
OUTFILE = fopen(LocalRankFilename,"wb");
|
OUTFILE = fopen(LocalRankFilename,"wb");
|
||||||
fwrite(PhaseField.data(),8,N,OUTFILE);
|
fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||||
fclose(OUTFILE);
|
fclose(OUTFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScaLBL_Poisson::getElectricField(int timestep){
|
||||||
|
|
||||||
|
//ScaLBL_D3Q7_Poisson_getElectricField(fq,ElectricField,tau,Np);
|
||||||
|
//ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
|
||||||
|
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
|
ScaLBL_Comm->RegularLayout(Map,&ElectricField[0*Np],PhaseField);
|
||||||
|
ElectricField_LB_to_Phys(PhaseField);
|
||||||
|
FILE *EX;
|
||||||
|
sprintf(LocalRankFilename,"ElectricField_X_Time_%i.%05i.raw",timestep,rank);
|
||||||
|
EX = fopen(LocalRankFilename,"wb");
|
||||||
|
fwrite(PhaseField.data(),8,N,EX);
|
||||||
|
fclose(EX);
|
||||||
|
|
||||||
|
ScaLBL_Comm->RegularLayout(Map,&ElectricField[1*Np],PhaseField);
|
||||||
|
ElectricField_LB_to_Phys(PhaseField);
|
||||||
|
FILE *EY;
|
||||||
|
sprintf(LocalRankFilename,"ElectricField_Y_Time_%i.%05i.raw",timestep,rank);
|
||||||
|
EY = fopen(LocalRankFilename,"wb");
|
||||||
|
fwrite(PhaseField.data(),8,N,EY);
|
||||||
|
fclose(EY);
|
||||||
|
|
||||||
|
ScaLBL_Comm->RegularLayout(Map,&ElectricField[2*Np],PhaseField);
|
||||||
|
ElectricField_LB_to_Phys(PhaseField);
|
||||||
|
FILE *EZ;
|
||||||
|
sprintf(LocalRankFilename,"ElectricField_Z_Time_%i.%05i.raw",timestep,rank);
|
||||||
|
EZ = fopen(LocalRankFilename,"wb");
|
||||||
|
fwrite(PhaseField.data(),8,N,EZ);
|
||||||
|
fclose(EZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ScaLBL_Poisson::ElectricField_LB_to_Phys(DoubleArray &Efield_reg){
|
||||||
|
for (int k=0;k<Nz;k++){
|
||||||
|
for (int j=0;j<Ny;j++){
|
||||||
|
for (int i=0;i<Nx;i++){
|
||||||
|
int idx=Map(i,j,k);
|
||||||
|
if (!(idx < 0)){
|
||||||
|
Efield_reg(i,j,k) = Efield_reg(i,j,k)/(h*1.0e-6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//void ScaLBL_Poisson::getElectricPotential(){
|
||||||
|
//
|
||||||
|
// DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
|
// ScaLBL_Comm->RegularLayout(Map,Psi,PhaseField);
|
||||||
|
// //ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
// FILE *OUTFILE;
|
||||||
|
// sprintf(LocalRankFilename,"Electric_Potential.%05i.raw",rank);
|
||||||
|
// OUTFILE = fopen(LocalRankFilename,"wb");
|
||||||
|
// fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||||
|
// fclose(OUTFILE);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//old version where Psi is of size Np
|
||||||
|
//void ScaLBL_Poisson::AssignSolidBoundary(double *poisson_solid)
|
||||||
|
//{
|
||||||
|
// size_t NLABELS=0;
|
||||||
|
// signed char VALUE=0;
|
||||||
|
// double AFFINITY=0.f;
|
||||||
|
//
|
||||||
|
// auto LabelList = electric_db->getVector<int>( "SolidLabels" );
|
||||||
|
// auto AffinityList = electric_db->getVector<double>( "SolidValues" );
|
||||||
|
//
|
||||||
|
// NLABELS=LabelList.size();
|
||||||
|
// if (NLABELS != AffinityList.size()){
|
||||||
|
// ERROR("Error: LB-Poisson Solver: SolidLabels and SolidValues must be the same length! \n");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// double label_count[NLABELS];
|
||||||
|
// double label_count_global[NLABELS];
|
||||||
|
// // Assign the labels
|
||||||
|
//
|
||||||
|
// for (size_t idx=0; idx<NLABELS; idx++) label_count[idx]=0;
|
||||||
|
//
|
||||||
|
// 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++){
|
||||||
|
// //printf("idx=%i, value=%i, %i, \n",idx, VALUE,LabelList[idx]);
|
||||||
|
// if (VALUE == LabelList[idx]){
|
||||||
|
// AFFINITY=AffinityList[idx];
|
||||||
|
// //NOTE need to convert the user input phys unit to LB unit
|
||||||
|
// if (BoundaryConditionSolid==2){
|
||||||
|
// //for BCS=1, i.e. Dirichlet-type, no need for unit conversion
|
||||||
|
// //TODO maybe there is a factor of gamm missing here ?
|
||||||
|
// AFFINITY = AFFINITY*(h*h*1.0e-12)/epsilon_LB;
|
||||||
|
// }
|
||||||
|
// label_count[idx] += 1.0;
|
||||||
|
// idx = NLABELS;
|
||||||
|
// //Mask->id[n] = 0; // set mask to zero since this is an immobile component
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// poisson_solid[n] = AFFINITY;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (size_t idx=0; idx<NLABELS; idx++)
|
||||||
|
// label_count_global[idx]=sumReduce( Dm->Comm, label_count[idx]);
|
||||||
|
//
|
||||||
|
// if (rank==0){
|
||||||
|
// printf("LB-Poisson Solver: number of Poisson 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);
|
||||||
|
// switch (BoundaryConditionSolid){
|
||||||
|
// case 1:
|
||||||
|
// printf(" label=%d, surface potential=%.3g [V], volume fraction=%.2g\n",VALUE,AFFINITY,volume_fraction);
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// printf(" label=%d, surface charge density=%.3g [C/m^2], volume fraction=%.2g\n",VALUE,AFFINITY,volume_fraction);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// printf(" label=%d, surface potential=%.3g [V], volume fraction=%.2g\n",VALUE,AFFINITY,volume_fraction);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
// old version where Psi is of size Np
|
||||||
|
//void ScaLBL_Poisson::Potential_Init(double *psi_init){
|
||||||
|
//
|
||||||
|
// if (BoundaryCondition==1){
|
||||||
|
// if (electric_db->keyExists( "Vin" )){
|
||||||
|
// Vin = electric_db->getScalar<double>( "Vin" );
|
||||||
|
// }
|
||||||
|
// if (electric_db->keyExists( "Vout" )){
|
||||||
|
// Vout = electric_db->getScalar<double>( "Vout" );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// //By default only periodic BC is applied and Vin=Vout=1.0, i.e. there is no potential gradient along Z-axis
|
||||||
|
// double slope = (Vout-Vin)/(Nz-2);
|
||||||
|
// double psi_linearized;
|
||||||
|
// for (int k=0;k<Nz;k++){
|
||||||
|
// if (k==0 || k==1){
|
||||||
|
// psi_linearized = Vin;
|
||||||
|
// }
|
||||||
|
// else if (k==Nz-1 || k==Nz-2){
|
||||||
|
// psi_linearized = Vout;
|
||||||
|
// }
|
||||||
|
// else{
|
||||||
|
// psi_linearized = slope*(k-1)+Vin;
|
||||||
|
// }
|
||||||
|
// for (int j=0;j<Ny;j++){
|
||||||
|
// for (int i=0;i<Nx;i++){
|
||||||
|
// int idx = Map(i,j,k);
|
||||||
|
// if (!(idx < 0)){
|
||||||
|
// psi_init[idx] = psi_linearized;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ public:
|
|||||||
void Create();
|
void Create();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Run(double *ChargeDensity);
|
void Run(double *ChargeDensity);
|
||||||
void getElectricalPotential();
|
void getElectricPotential(int timestep);
|
||||||
|
void getElectricField(int timestep);
|
||||||
|
|
||||||
//bool Restart,pBC;
|
//bool Restart,pBC;
|
||||||
int timestep,timestepMax;
|
int timestep,timestepMax;
|
||||||
@@ -39,6 +40,7 @@ public:
|
|||||||
double tolerance;
|
double tolerance;
|
||||||
double k2_inv,gamma;
|
double k2_inv,gamma;
|
||||||
double epsilon0,epsilon0_LB,epsilonR,epsilon_LB;
|
double epsilon0,epsilon0_LB,epsilonR,epsilon_LB;
|
||||||
|
double Vin, Vout;
|
||||||
|
|
||||||
int Nx,Ny,Nz,N,Np;
|
int Nx,Ny,Nz,N,Np;
|
||||||
int rank,nprocx,nprocy,nprocz,nprocs;
|
int rank,nprocx,nprocy,nprocz,nprocs;
|
||||||
@@ -48,6 +50,7 @@ public:
|
|||||||
std::shared_ptr<Domain> Dm; // this domain is for analysis
|
std::shared_ptr<Domain> Dm; // this domain is for analysis
|
||||||
std::shared_ptr<Domain> Mask; // this domain is for lbm
|
std::shared_ptr<Domain> Mask; // this domain is for lbm
|
||||||
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm;
|
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm;
|
||||||
|
std::shared_ptr<ScaLBL_Communicator> ScaLBL_Comm_Regular;
|
||||||
// input database
|
// input database
|
||||||
std::shared_ptr<Database> db;
|
std::shared_ptr<Database> db;
|
||||||
std::shared_ptr<Database> domain_db;
|
std::shared_ptr<Database> domain_db;
|
||||||
@@ -57,10 +60,12 @@ public:
|
|||||||
DoubleArray Distance;
|
DoubleArray Distance;
|
||||||
DoubleArray Psi_host;
|
DoubleArray Psi_host;
|
||||||
int *NeighborList;
|
int *NeighborList;
|
||||||
|
int *dvcMap;
|
||||||
|
signed char *dvcID;
|
||||||
double *fq;
|
double *fq;
|
||||||
double *Psi;
|
double *Psi;
|
||||||
double *ElectricField;
|
double *ElectricField;
|
||||||
double *PoissonSolid;
|
//double *PoissonSolid;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MPI_Comm comm;
|
MPI_Comm comm;
|
||||||
@@ -73,4 +78,6 @@ private:
|
|||||||
//int rank,nprocs;
|
//int rank,nprocs;
|
||||||
void LoadParams(std::shared_ptr<Database> db0);
|
void LoadParams(std::shared_ptr<Database> db0);
|
||||||
void AssignSolidBoundary(double *poisson_solid);
|
void AssignSolidBoundary(double *poisson_solid);
|
||||||
|
void Potential_Init(double *psi_init);
|
||||||
|
void ElectricField_LB_to_Phys(DoubleArray &Efield_reg);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
ScaLBL_StokesModel::ScaLBL_StokesModel(int RANK, int NP, MPI_Comm COMM):
|
ScaLBL_StokesModel::ScaLBL_StokesModel(int RANK, int NP, MPI_Comm COMM):
|
||||||
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tau(0),
|
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),time_conv(0),tolerance(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),
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -27,17 +27,17 @@ void ScaLBL_StokesModel::ReadParams(string filename,int num_iter){
|
|||||||
//-------------------------------------------------------------------//
|
//-------------------------------------------------------------------//
|
||||||
|
|
||||||
//---------------------- Default model parameters --------------------------//
|
//---------------------- 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]
|
nu_phys = 1.004e-6;//by default use water kinematic viscosity at 20C; unit [m^2/sec]
|
||||||
h = 1.0;//image resolution;[um]
|
h = 1.0;//image resolution;[um]
|
||||||
tau = 1.0;
|
tau = 1.0;
|
||||||
mu = (tau-0.5)/3.0;//LB kinematic viscosity;unit [lu^2/lt]
|
mu = (tau-0.5)/3.0;//LB kinematic viscosity;unit [lu^2/lt]
|
||||||
time_conv = h*h*mu/nu_phys;//time conversion factor from physical to LB unit; [sec/lt]
|
time_conv = h*h*mu/nu_phys;//time conversion factor from physical to LB unit; [sec/lt]
|
||||||
|
rho0 = 1.0;//LB density
|
||||||
|
den_scale = rho_phys/rho0*(h*h*h*1.0e-18);//scale factor for density
|
||||||
tolerance = 1.0e-8;
|
tolerance = 1.0e-8;
|
||||||
Fx = Fy = 0.0;
|
Fx = Fy = 0.0;
|
||||||
Fz = 1.0e-5;
|
Fz = 1.0e-5;
|
||||||
//Body electric field [V/lu]
|
|
||||||
Ex = Ey = 0.0;
|
|
||||||
Ez = 1.0e-3;
|
|
||||||
//--------------------------------------------------------------------------//
|
//--------------------------------------------------------------------------//
|
||||||
|
|
||||||
// Read domain parameters
|
// Read domain parameters
|
||||||
@@ -59,19 +59,20 @@ void ScaLBL_StokesModel::ReadParams(string filename,int num_iter){
|
|||||||
if (stokes_db->keyExists( "tau" )){
|
if (stokes_db->keyExists( "tau" )){
|
||||||
tau = stokes_db->getScalar<double>( "tau" );
|
tau = stokes_db->getScalar<double>( "tau" );
|
||||||
}
|
}
|
||||||
|
if (stokes_db->keyExists( "rho0" )){
|
||||||
|
rho0 = stokes_db->getScalar<double>( "rho0" );
|
||||||
|
}
|
||||||
if (stokes_db->keyExists( "nu_phys" )){
|
if (stokes_db->keyExists( "nu_phys" )){
|
||||||
nu_phys = stokes_db->getScalar<double>( "nu_phys" );
|
nu_phys = stokes_db->getScalar<double>( "nu_phys" );
|
||||||
}
|
}
|
||||||
|
if (stokes_db->keyExists( "rho_phys" )){
|
||||||
|
rho_phys = stokes_db->getScalar<double>( "rho_phys" );
|
||||||
|
}
|
||||||
if (stokes_db->keyExists( "F" )){
|
if (stokes_db->keyExists( "F" )){
|
||||||
Fx = stokes_db->getVector<double>( "F" )[0];
|
Fx = stokes_db->getVector<double>( "F" )[0];
|
||||||
Fy = stokes_db->getVector<double>( "F" )[1];
|
Fy = stokes_db->getVector<double>( "F" )[1];
|
||||||
Fz = stokes_db->getVector<double>( "F" )[2];
|
Fz = stokes_db->getVector<double>( "F" )[2];
|
||||||
}
|
}
|
||||||
if (stokes_db->keyExists( "ElectricField" )){//NOTE user-input has physical unit [V/m]
|
|
||||||
Ex = stokes_db->getVector<double>( "ElectricField" )[0];
|
|
||||||
Ey = stokes_db->getVector<double>( "ElectricField" )[1];
|
|
||||||
Ez = stokes_db->getVector<double>( "ElectricField" )[2];
|
|
||||||
}
|
|
||||||
if (stokes_db->keyExists( "Restart" )){
|
if (stokes_db->keyExists( "Restart" )){
|
||||||
Restart = stokes_db->getScalar<bool>( "Restart" );
|
Restart = stokes_db->getScalar<bool>( "Restart" );
|
||||||
}
|
}
|
||||||
@@ -88,10 +89,7 @@ void ScaLBL_StokesModel::ReadParams(string filename,int num_iter){
|
|||||||
// Re-calculate model parameters due to parameter read
|
// Re-calculate model parameters due to parameter read
|
||||||
mu=(tau-0.5)/3.0;
|
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]
|
time_conv = (h*h*1.0e-12)*mu/nu_phys;//time conversion factor from physical to LB unit; [sec/lt]
|
||||||
// convert user-input electric field ([V/m]) from physical unit to LB unit
|
den_scale = rho_phys/rho0*(h*h*h*1.0e-18);//scale factor for density
|
||||||
Ex = Ex*(h*1.0e-6);//LB electric field: V/lu
|
|
||||||
Ey = Ey*(h*1.0e-6);
|
|
||||||
Ez = Ez*(h*1.0e-6);
|
|
||||||
|
|
||||||
if (rank==0) printf("*****************************************************\n");
|
if (rank==0) printf("*****************************************************\n");
|
||||||
if (rank==0) printf("LB Single-Fluid Navier-Stokes Solver: \n");
|
if (rank==0) printf("LB Single-Fluid Navier-Stokes Solver: \n");
|
||||||
@@ -246,7 +244,7 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
|||||||
while (timestep < timestepMax) {
|
while (timestep < timestepMax) {
|
||||||
//************************************************************************/
|
//************************************************************************/
|
||||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
|
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
|
||||||
ScaLBL_D3Q19_AAodd_StokesMRT(NeighborList, fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz, Ex, Ey, Ez,
|
ScaLBL_D3Q19_AAodd_StokesMRT(NeighborList, fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||||
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
||||||
// Set boundary conditions
|
// Set boundary conditions
|
||||||
@@ -262,12 +260,14 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
|||||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
||||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
||||||
}
|
}
|
||||||
ScaLBL_D3Q19_AAodd_StokesMRT(NeighborList, fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz, Ex, Ey, Ez, 0, ScaLBL_Comm->LastExterior(), Np);
|
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);
|
||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
|
||||||
timestep++;
|
timestep++;
|
||||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
|
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
|
||||||
ScaLBL_D3Q19_AAeven_StokesMRT(fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz, Ex, Ey, Ez, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
ScaLBL_D3Q19_AAeven_StokesMRT(fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz,rho0,den_scale,h,time_conv,
|
||||||
|
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||||
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
||||||
// Set boundary conditions
|
// Set boundary conditions
|
||||||
if (BoundaryCondition == 3){
|
if (BoundaryCondition == 3){
|
||||||
@@ -282,41 +282,87 @@ void ScaLBL_StokesModel::Run_Lite(double *ChargeDensity, double *ElectricField){
|
|||||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
||||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
||||||
}
|
}
|
||||||
ScaLBL_D3Q19_AAeven_StokesMRT(fq, Velocity, ChargeDensity, ElectricField, rlx_setA, rlx_setB, Fx, Fy, Fz, Ex, Ey, Ez, 0, ScaLBL_Comm->LastExterior(), Np);
|
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);
|
||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
//************************************************************************/
|
//************************************************************************/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaLBL_StokesModel::getVelocity(){
|
void ScaLBL_StokesModel::getVelocity(int timestep){
|
||||||
//get velocity in physical unit [m/sec]
|
//get velocity in physical unit [m/sec]
|
||||||
ScaLBL_D3Q19_Momentum_Phys(fq, Velocity, h, time_conv, Np);
|
ScaLBL_D3Q19_Momentum(fq, Velocity, Np);
|
||||||
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
|
||||||
DoubleArray PhaseField(Nx,Ny,Nz);
|
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
ScaLBL_Comm->RegularLayout(Map,&Velocity[0],PhaseField);
|
ScaLBL_Comm->RegularLayout(Map,&Velocity[0],PhaseField);
|
||||||
|
Velocity_LB_to_Phys(PhaseField);
|
||||||
FILE *VELX_FILE;
|
FILE *VELX_FILE;
|
||||||
sprintf(LocalRankFilename,"Velocity_X.%05i.raw",rank);
|
sprintf(LocalRankFilename,"Velocity_X_Time_%i.%05i.raw",timestep,rank);
|
||||||
VELX_FILE = fopen(LocalRankFilename,"wb");
|
VELX_FILE = fopen(LocalRankFilename,"wb");
|
||||||
fwrite(PhaseField.data(),8,N,VELX_FILE);
|
fwrite(PhaseField.data(),8,N,VELX_FILE);
|
||||||
fclose(VELX_FILE);
|
fclose(VELX_FILE);
|
||||||
|
|
||||||
ScaLBL_Comm->RegularLayout(Map,&Velocity[Np],PhaseField);
|
ScaLBL_Comm->RegularLayout(Map,&Velocity[Np],PhaseField);
|
||||||
|
Velocity_LB_to_Phys(PhaseField);
|
||||||
FILE *VELY_FILE;
|
FILE *VELY_FILE;
|
||||||
sprintf(LocalRankFilename,"Velocity_Y.%05i.raw",rank);
|
sprintf(LocalRankFilename,"Velocity_Y_Time_%i.%05i.raw",timestep,rank);
|
||||||
VELY_FILE = fopen(LocalRankFilename,"wb");
|
VELY_FILE = fopen(LocalRankFilename,"wb");
|
||||||
fwrite(PhaseField.data(),8,N,VELY_FILE);
|
fwrite(PhaseField.data(),8,N,VELY_FILE);
|
||||||
fclose(VELY_FILE);
|
fclose(VELY_FILE);
|
||||||
|
|
||||||
ScaLBL_Comm->RegularLayout(Map,&Velocity[2*Np],PhaseField);
|
ScaLBL_Comm->RegularLayout(Map,&Velocity[2*Np],PhaseField);
|
||||||
|
Velocity_LB_to_Phys(PhaseField);
|
||||||
FILE *VELZ_FILE;
|
FILE *VELZ_FILE;
|
||||||
sprintf(LocalRankFilename,"Velocity_Z.%05i.raw",rank);
|
sprintf(LocalRankFilename,"Velocity_Z_Time_%i.%05i.raw",timestep,rank);
|
||||||
VELZ_FILE = fopen(LocalRankFilename,"wb");
|
VELZ_FILE = fopen(LocalRankFilename,"wb");
|
||||||
fwrite(PhaseField.data(),8,N,VELZ_FILE);
|
fwrite(PhaseField.data(),8,N,VELZ_FILE);
|
||||||
fclose(VELZ_FILE);
|
fclose(VELZ_FILE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScaLBL_StokesModel::Velocity_LB_to_Phys(DoubleArray &Vel_reg){
|
||||||
|
for (int k=0;k<Nz;k++){
|
||||||
|
for (int j=0;j<Ny;j++){
|
||||||
|
for (int i=0;i<Nx;i++){
|
||||||
|
int idx=Map(i,j,k);
|
||||||
|
if (!(idx < 0)){
|
||||||
|
Vel_reg(i,j,k) = Vel_reg(i,j,k)*(h*1.0e-6)/time_conv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//void ScaLBL_StokesModel::getVelocity(){
|
||||||
|
// //get velocity in physical unit [m/sec]
|
||||||
|
// ScaLBL_D3Q19_Momentum_Phys(fq, Velocity, h, time_conv, Np);
|
||||||
|
// ScaLBL_DeviceBarrier(); MPI_Barrier(comm);
|
||||||
|
//
|
||||||
|
// DoubleArray PhaseField(Nx,Ny,Nz);
|
||||||
|
// ScaLBL_Comm->RegularLayout(Map,&Velocity[0],PhaseField);
|
||||||
|
// FILE *VELX_FILE;
|
||||||
|
// sprintf(LocalRankFilename,"Velocity_X.%05i.raw",rank);
|
||||||
|
// VELX_FILE = fopen(LocalRankFilename,"wb");
|
||||||
|
// fwrite(PhaseField.data(),8,N,VELX_FILE);
|
||||||
|
// fclose(VELX_FILE);
|
||||||
|
//
|
||||||
|
// ScaLBL_Comm->RegularLayout(Map,&Velocity[Np],PhaseField);
|
||||||
|
// FILE *VELY_FILE;
|
||||||
|
// sprintf(LocalRankFilename,"Velocity_Y.%05i.raw",rank);
|
||||||
|
// VELY_FILE = fopen(LocalRankFilename,"wb");
|
||||||
|
// fwrite(PhaseField.data(),8,N,VELY_FILE);
|
||||||
|
// fclose(VELY_FILE);
|
||||||
|
//
|
||||||
|
// ScaLBL_Comm->RegularLayout(Map,&Velocity[2*Np],PhaseField);
|
||||||
|
// FILE *VELZ_FILE;
|
||||||
|
// sprintf(LocalRankFilename,"Velocity_Z.%05i.raw",rank);
|
||||||
|
// VELZ_FILE = fopen(LocalRankFilename,"wb");
|
||||||
|
// fwrite(PhaseField.data(),8,N,VELZ_FILE);
|
||||||
|
// fclose(VELZ_FILE);
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
void ScaLBL_StokesModel::Run(){
|
void ScaLBL_StokesModel::Run(){
|
||||||
double rlx_setA=1.0/tau;
|
double rlx_setA=1.0/tau;
|
||||||
double rlx_setB = 8.f*(2.f-rlx_setA)/(8.f-rlx_setA);
|
double rlx_setB = 8.f*(2.f-rlx_setA)/(8.f-rlx_setA);
|
||||||
|
|||||||
@@ -30,19 +30,21 @@ public:
|
|||||||
void Run();
|
void Run();
|
||||||
void Run_Lite(double *ChargeDensity, double *ElectricField);
|
void Run_Lite(double *ChargeDensity, double *ElectricField);
|
||||||
void VelocityField();
|
void VelocityField();
|
||||||
void getVelocity();
|
void getVelocity(int timestep);
|
||||||
|
|
||||||
bool Restart,pBC;
|
bool Restart,pBC;
|
||||||
int timestep,timestepMax;
|
int timestep,timestepMax;
|
||||||
int BoundaryCondition;
|
int BoundaryCondition;
|
||||||
double tau,mu;
|
double tau,mu;
|
||||||
|
double rho0;
|
||||||
double Fx,Fy,Fz,flux;
|
double Fx,Fy,Fz,flux;
|
||||||
double Ex,Ey,Ez;
|
|
||||||
double din,dout;
|
double din,dout;
|
||||||
double tolerance;
|
double tolerance;
|
||||||
double nu_phys;
|
double nu_phys;
|
||||||
|
double rho_phys;
|
||||||
double time_conv;
|
double time_conv;
|
||||||
double h;//image resolution
|
double h;//image resolution
|
||||||
|
double den_scale;//scale factor for density
|
||||||
|
|
||||||
int Nx,Ny,Nz,N,Np;
|
int Nx,Ny,Nz,N,Np;
|
||||||
int rank,nprocx,nprocy,nprocz,nprocs;
|
int rank,nprocx,nprocy,nprocz,nprocs;
|
||||||
@@ -78,4 +80,5 @@ private:
|
|||||||
|
|
||||||
//int rank,nprocs;
|
//int rank,nprocs;
|
||||||
void LoadParams(std::shared_ptr<Database> db0);
|
void LoadParams(std::shared_ptr<Database> db0);
|
||||||
|
void Velocity_LB_to_Phys(DoubleArray &Vel_reg);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,14 +78,17 @@ int main(int argc, char **argv)
|
|||||||
while (timestep < Study.timestepMax){
|
while (timestep < Study.timestepMax){
|
||||||
|
|
||||||
timestep++;
|
timestep++;
|
||||||
if (rank==0) printf("timestep=%i; running Poisson solver\n",timestep);
|
//if (rank==0) printf("timestep=%i; running Poisson solver\n",timestep);
|
||||||
PoissonSolver.Run(IonModel.ChargeDensity);//solve Poisson equtaion to get steady-state electrical potental
|
PoissonSolver.Run(IonModel.ChargeDensity);//solve Poisson equtaion to get steady-state electrical potental
|
||||||
|
//PoissonSolver.getElectricPotential(timestep);
|
||||||
|
|
||||||
if (rank==0) printf("timestep=%i; running StokesModel\n",timestep);
|
//if (rank==0) printf("timestep=%i; running StokesModel\n",timestep);
|
||||||
StokesModel.Run_Lite(IonModel.ChargeDensity, PoissonSolver.ElectricField);// Solve the N-S equations to get velocity
|
StokesModel.Run_Lite(IonModel.ChargeDensity, PoissonSolver.ElectricField);// Solve the N-S equations to get velocity
|
||||||
|
//StokesModel.getVelocity(timestep);
|
||||||
|
|
||||||
if (rank==0) printf("timestep=%i; running Ion model\n",timestep);
|
//if (rank==0) printf("timestep=%i; running Ion model\n",timestep);
|
||||||
IonModel.Run(StokesModel.Velocity,PoissonSolver.ElectricField); //solve for ion transport and electric potential
|
IonModel.Run(StokesModel.Velocity,PoissonSolver.ElectricField); //solve for ion transport and electric potential
|
||||||
|
//IonModel.getIonConcentration(timestep);
|
||||||
|
|
||||||
|
|
||||||
timestep++;//AA operations
|
timestep++;//AA operations
|
||||||
@@ -94,9 +97,10 @@ int main(int argc, char **argv)
|
|||||||
//--------------------------------------------
|
//--------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
StokesModel.getVelocity();
|
StokesModel.getVelocity(timestep);
|
||||||
PoissonSolver.getElectricalPotential();
|
PoissonSolver.getElectricPotential(timestep);
|
||||||
IonModel.getIonConcentration();
|
PoissonSolver.getElectricField(timestep);
|
||||||
|
IonModel.getIonConcentration(timestep);
|
||||||
|
|
||||||
if (rank==0) printf("Maximum timestep is reached and the simulation is completed\n");
|
if (rank==0) printf("Maximum timestep is reached and the simulation is completed\n");
|
||||||
if (rank==0) printf("*************************************************************\n");
|
if (rank==0) printf("*************************************************************\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user