resolve merge conflicts
This commit is contained in:
@@ -70,49 +70,6 @@ extern "C" void ScaLBL_D3Q19_AAeven_Greyscale_IMRT(double *dist, int start, int
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAodd_Greyscale_IMRT(int *neighborList, double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz,
|
||||
double *Poros,double *Perm, double *Velocity,double Den,double *Pressure);
|
||||
// ION TRANSPORT MODEL
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *dist, double *Den, int start, int finish, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_IonConcentration(double *dist, double *Den, int start, int finish, int Np);
|
||||
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_Ion(int *neighborList, double *dist, double *Den, double *Velocity, double *ElectricField,
|
||||
double Di, int zi, double rlx, double Vt, int start, int finish, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Ion(double *dist, double *Den, double *Velocity, double *ElectricField,
|
||||
double Di, int zi, double rlx, double Vt, int start, int finish, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_Ion_Init(double *dist, double *Den, double DenInit, int Np);
|
||||
extern "C" void ScaLBL_D3Q7_Ion_Init_FromFile(double *dist, double *Den, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_Ion_ChargeDensity(double *Den, double *ChargeDensity, int IonValence, int ion_component, int start, int finish, int Np);
|
||||
|
||||
// LBM Poisson solver
|
||||
|
||||
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,
|
||||
int start, int finish, int Np);
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAeven_Poisson(int *Map, double *dist, double *Den_charge, double *Psi, double *ElectricField, double tau, double epsilon_LB,
|
||||
int start, int finish, 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);
|
||||
|
||||
//maybe deprecated
|
||||
//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)
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
extern "C" void ScaLBL_D3Q19_AAeven_Greyscale_MRT(double *dist, int start, int finish, int Np, double rlx, double rlx_eff, double Fx, double Fy, double Fz,
|
||||
double *Poros,double *Perm, double *Velocity,double Den,double *Pressure);
|
||||
@@ -129,6 +86,7 @@ extern "C" void ScaLBL_D3Q19_AAodd_GreyscaleColor(int *d_neighborList, int *Map,
|
||||
double *Phi, double *GreySolidGrad, double *Poros,double *Perm,double *Vel,double *Pressure,
|
||||
double rhoA, double rhoB, double tauA, double tauB, double tauA_eff,double tauB_eff, double alpha, double beta,
|
||||
double Fx, double Fy, double Fz, int strideY, int strideZ, int start, int finish, int Np);
|
||||
|
||||
// ION TRANSPORT MODEL
|
||||
|
||||
extern "C" void ScaLBL_D3Q7_AAodd_IonConcentration(int *neighborList, double *dist, double *Den, int start, int finish, int Np);
|
||||
|
||||
@@ -32,8 +32,8 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
|
||||
tauA = tauB = 1.0;
|
||||
rhoA = rhoB = 1.0;
|
||||
Fx = Fy = Fz = 0.0;
|
||||
gamma=1e-3;
|
||||
W=5;
|
||||
gamma=1e-3;//surface tension
|
||||
W=5.0;//interfacial thickness
|
||||
Restart=false;
|
||||
din=dout=1.0;
|
||||
flux=0.0;
|
||||
@@ -220,7 +220,7 @@ void ScaLBL_FreeLeeModel::Create(){
|
||||
//...........................................................................
|
||||
ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &dvcMap, sizeof(int)*Np);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &fq, 19*dist_mem_size);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &gqbar, 19*dist_mem_size);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &hq, 7*dist_mem_size);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &mu_phi, dist_mem_size);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &Den, dist_mem_size);
|
||||
@@ -239,10 +239,11 @@ void ScaLBL_FreeLeeModel::Create(){
|
||||
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;
|
||||
TmpMap[idx] = ScaLBL_Comm_WideHalo->Map(i,j,k);
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO The following check needs update!
|
||||
// check that TmpMap is valid
|
||||
for (int idx=0; idx<ScaLBL_Comm->LastExterior(); idx++){
|
||||
auto n = TmpMap[idx];
|
||||
@@ -264,21 +265,255 @@ void ScaLBL_FreeLeeModel::Create(){
|
||||
|
||||
// copy the neighbor list
|
||||
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
||||
// initialize phi based on PhaseLabel (include solid component labels)
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* AssignComponentLabels *
|
||||
********************************************************/
|
||||
void ScaLBL_FreeLeeModel::AssignComponentLabels()
|
||||
{
|
||||
double *phase;
|
||||
phase = new double[Nh];
|
||||
|
||||
size_t NLABELS=0;
|
||||
signed char VALUE=0;
|
||||
double AFFINITY=0.f;
|
||||
|
||||
auto LabelList = greyscaleColor_db->getVector<int>( "ComponentLabels" );
|
||||
auto AffinityList = greyscaleColor_db->getVector<double>( "ComponentAffinity" );
|
||||
|
||||
NLABELS=LabelList.size();
|
||||
if (NLABELS != AffinityList.size()){
|
||||
ERROR("Error: ComponentLabels and ComponentAffinity 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=1;k<Nzh-1;k++){
|
||||
for (int j=1;j<Nyh-1;j++){
|
||||
for (int i=1;i<Nxh-1;i++){
|
||||
int n = (k-1)*Nx*Ny+(j-1)*Nx+(i-1);
|
||||
int nh = k*Nxh*Nyh+j*Nxh+i;
|
||||
VALUE=id[n];
|
||||
// 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];
|
||||
label_count[idx] += 1.0;
|
||||
idx = NLABELS;
|
||||
//Mask->id[n] = 0; // set mask to zero since this is an immobile component
|
||||
}
|
||||
}
|
||||
// fluid labels are reserved
|
||||
if (VALUE == 1) AFFINITY=1.0;
|
||||
else if (VALUE == 2) AFFINITY=-1.0;
|
||||
phase[n] = AFFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set Dm to match Mask
|
||||
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i];
|
||||
|
||||
for (size_t idx=0; idx<NLABELS; idx++)
|
||||
label_count_global[idx] = sumReduce( Dm->Comm, label_count[idx]);
|
||||
|
||||
if (rank==0){
|
||||
printf("Number of component labels: %lu \n",NLABELS);
|
||||
for (unsigned int idx=0; idx<NLABELS; idx++){
|
||||
VALUE=LabelList[idx];
|
||||
AFFINITY=AffinityList[idx];
|
||||
double volume_fraction = double(label_count_global[idx])/double((Nx-2)*(Ny-2)*(Nz-2)*nprocs);
|
||||
printf(" label=%d, affinity=%f, volume fraction==%f\n",VALUE,AFFINITY,volume_fraction);
|
||||
}
|
||||
}
|
||||
|
||||
//compute color gradient and laplacian of phase field
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//copy all data to device
|
||||
ScaLBL_CopyToDevice(Phi, phase, N*sizeof(double));
|
||||
ScaLBL_DeviceBarrier();
|
||||
MPI_Barrier(ScaLBL_Comm->MPI_COMM_SCALBL);
|
||||
delete [] phase;
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::AssignChemPotential_ColorGrad()
|
||||
{
|
||||
double *SolidPotential_host = new double [Nx*Ny*Nz];
|
||||
double *GreySolidGrad_host = new double [3*Np];
|
||||
|
||||
size_t NLABELS=0;
|
||||
signed char VALUE=0;
|
||||
double AFFINITY=0.f;
|
||||
|
||||
auto LabelList = greyscaleColor_db->getVector<int>( "GreySolidLabels" );
|
||||
auto AffinityList = greyscaleColor_db->getVector<double>( "GreySolidAffinity" );
|
||||
|
||||
NLABELS=LabelList.size();
|
||||
if (NLABELS != AffinityList.size()){
|
||||
ERROR("Error: GreySolidLabels and GreySolidAffinity must be the same length! \n");
|
||||
}
|
||||
|
||||
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=id[n];
|
||||
AFFINITY=0.f;//all nodes except the specified grey nodes have grey-solid affinity = 0.0
|
||||
// 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];
|
||||
idx = NLABELS;
|
||||
//Mask->id[n] = 0; // set mask to zero since this is an immobile component
|
||||
}
|
||||
}
|
||||
SolidPotential_host[n] = AFFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate grey-solid color-gradient
|
||||
double *Dst;
|
||||
Dst = new double [3*3*3];
|
||||
for (int kk=0; kk<3; kk++){
|
||||
for (int jj=0; jj<3; jj++){
|
||||
for (int ii=0; ii<3; ii++){
|
||||
int index = kk*9+jj*3+ii;
|
||||
Dst[index] = sqrt(double(ii-1)*double(ii-1) + double(jj-1)*double(jj-1)+ double(kk-1)*double(kk-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
double w_face = 1.f;
|
||||
double w_edge = 0.5;
|
||||
double w_corner = 0.f;
|
||||
//local
|
||||
Dst[13] = 0.f;
|
||||
//faces
|
||||
Dst[4] = w_face;
|
||||
Dst[10] = w_face;
|
||||
Dst[12] = w_face;
|
||||
Dst[14] = w_face;
|
||||
Dst[16] = w_face;
|
||||
Dst[22] = w_face;
|
||||
// corners
|
||||
Dst[0] = w_corner;
|
||||
Dst[2] = w_corner;
|
||||
Dst[6] = w_corner;
|
||||
Dst[8] = w_corner;
|
||||
Dst[18] = w_corner;
|
||||
Dst[20] = w_corner;
|
||||
Dst[24] = w_corner;
|
||||
Dst[26] = w_corner;
|
||||
// edges
|
||||
Dst[1] = w_edge;
|
||||
Dst[3] = w_edge;
|
||||
Dst[5] = w_edge;
|
||||
Dst[7] = w_edge;
|
||||
Dst[9] = w_edge;
|
||||
Dst[11] = w_edge;
|
||||
Dst[15] = w_edge;
|
||||
Dst[17] = w_edge;
|
||||
Dst[19] = w_edge;
|
||||
Dst[21] = w_edge;
|
||||
Dst[23] = w_edge;
|
||||
Dst[25] = w_edge;
|
||||
|
||||
for (int k=1; k<Nz-1; k++){
|
||||
for (int j=1; j<Ny-1; j++){
|
||||
for (int i=1; i<Nx-1; i++){
|
||||
int idx=Map(i,j,k);
|
||||
if (!(idx < 0)){
|
||||
double phi_x = 0.f;
|
||||
double phi_y = 0.f;
|
||||
double phi_z = 0.f;
|
||||
for (int kk=0; kk<3; kk++){
|
||||
for (int jj=0; jj<3; jj++){
|
||||
for (int ii=0; ii<3; ii++){
|
||||
|
||||
int index = kk*9+jj*3+ii;
|
||||
double weight= Dst[index];
|
||||
|
||||
int idi=i+ii-1;
|
||||
int idj=j+jj-1;
|
||||
int idk=k+kk-1;
|
||||
|
||||
if (idi < 0) idi=0;
|
||||
if (idj < 0) idj=0;
|
||||
if (idk < 0) idk=0;
|
||||
if (!(idi < Nx)) idi=Nx-1;
|
||||
if (!(idj < Ny)) idj=Ny-1;
|
||||
if (!(idk < Nz)) idk=Nz-1;
|
||||
|
||||
int nn = idk*Nx*Ny + idj*Nx + idi;
|
||||
double vec_x = double(ii-1);
|
||||
double vec_y = double(jj-1);
|
||||
double vec_z = double(kk-1);
|
||||
double GWNS=SolidPotential_host[nn];
|
||||
phi_x += GWNS*weight*vec_x;
|
||||
phi_y += GWNS*weight*vec_y;
|
||||
phi_z += GWNS*weight*vec_z;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Averages->SDs(i,j,k)<2.0){
|
||||
GreySolidGrad_host[idx+0*Np] = phi_x;
|
||||
GreySolidGrad_host[idx+1*Np] = phi_y;
|
||||
GreySolidGrad_host[idx+2*Np] = phi_z;
|
||||
}
|
||||
else{
|
||||
GreySolidGrad_host[idx+0*Np] = 0.0;
|
||||
GreySolidGrad_host[idx+1*Np] = 0.0;
|
||||
GreySolidGrad_host[idx+2*Np] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rank==0){
|
||||
printf("Number of Grey-solid labels: %lu \n",NLABELS);
|
||||
for (unsigned int idx=0; idx<NLABELS; idx++){
|
||||
VALUE=LabelList[idx];
|
||||
AFFINITY=AffinityList[idx];
|
||||
printf(" grey-solid label=%d, grey-solid affinity=%f\n",VALUE,AFFINITY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ScaLBL_CopyToDevice(GreySolidGrad, GreySolidGrad_host, 3*Np*sizeof(double));
|
||||
ScaLBL_DeviceBarrier();
|
||||
delete [] SolidPotential_host;
|
||||
delete [] GreySolidGrad_host;
|
||||
delete [] Dst;
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Initialize(){
|
||||
|
||||
if (rank==0) printf ("Initializing distributions \n");
|
||||
ScaLBL_D3Q19_Init(fq, Np);
|
||||
/*
|
||||
* This function initializes model
|
||||
*/
|
||||
if (rank==0) printf ("Initializing phase field, chemical potential and color gradient\n");
|
||||
AssignComponentLabels_ChemPotential_ColorGrad();//initialize phase field Phi
|
||||
|
||||
//if (rank==0) printf ("Initializing chemical potential and color gradient \n");
|
||||
//AssignChemPotential_ColorGrad();
|
||||
|
||||
if (rank==0) printf ("Initializing distributions for momentum transport\n");
|
||||
ScaLBL_D3Q19_FreeLeeModel_Init(gqbar, mu_phi, ColorGrad, Fx, Fy, Fz, Np);
|
||||
|
||||
if (rank==0) printf ("Initializing density field and distributions for phase-field transport\n");
|
||||
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
|
||||
if (Restart == true){
|
||||
//TODO need to revise this function
|
||||
if (rank==0){
|
||||
printf("Reading restart file! \n");
|
||||
}
|
||||
@@ -292,7 +527,7 @@ void ScaLBL_FreeLeeModel::Initialize(){
|
||||
cDen = new double[2*Np];
|
||||
cDist = new double[19*Np];
|
||||
ScaLBL_CopyToHost(TmpMap, dvcMap, Np*sizeof(int));
|
||||
ScaLBL_CopyToHost(cPhi, Phi, N*sizeof(double));
|
||||
//ScaLBL_CopyToHost(cPhi, Phi, N*sizeof(double));
|
||||
|
||||
ifstream File(LocalRestartFile,ios::binary);
|
||||
int idx;
|
||||
@@ -333,14 +568,13 @@ void ScaLBL_FreeLeeModel::Initialize(){
|
||||
ScaLBL_CopyToDevice(Den,cDen,2*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(fq,cDist,19*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(Phi,cPhi,N*sizeof(double));
|
||||
ScaLBL_DeviceBarrier();
|
||||
|
||||
ScaLBL_Comm->Barrier();
|
||||
comm.barrier();
|
||||
}
|
||||
|
||||
if (rank==0) printf ("Initializing phase field \n");
|
||||
//ScaLBL_PhaseField_Init(dvcMap, Phi, Den, hq, Bq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
//ScaLBL_PhaseField_Init(dvcMap, Phi, Den, hq, Bq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
if (rank==0) printf ("Initializing phase and density fields on device from Restart\n");
|
||||
ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
}
|
||||
|
||||
// establish reservoirs for external bC
|
||||
if (BoundaryCondition == 1 || BoundaryCondition == 2 || BoundaryCondition == 3 || BoundaryCondition == 4 ){
|
||||
@@ -382,27 +616,30 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
PROFILE_START("Update");
|
||||
// *************ODD TIMESTEP*************
|
||||
timestep++;
|
||||
/* // Compute the Phase indicator field
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// Compute the Phase indicator field
|
||||
// Read for hq, Bq happens in this routine (requires communication)
|
||||
ScaLBL_Comm->BiSendD3Q7AA(hq,Bq); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAodd_PhaseField(NeighborList, dvcMap, hq, Bq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->BiRecvD3Q7AA(hq,Bq); //WRITE INTO OPPOSITE
|
||||
//ScaLBL_Comm->SendD3Q7AA(hq); //READ FROM NORMAL
|
||||
ScaLBL_Comm->SendD3Q7AA(hq); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAodd_PhaseField(NeighborList, dvcMap, hq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q7AA(hq); //WRITE INTO OPPOSITE
|
||||
ScaLBL_DeviceBarrier();
|
||||
ScaLBL_D3Q7_AAodd_PhaseField(NeighborList, dvcMap, hq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_D3Q7_AAodd_PhaseField(NeighborList, dvcMap, hq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
|
||||
// Perform the collision operation
|
||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FROM NORMAL
|
||||
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FROM NORMAL
|
||||
if (BoundaryCondition > 0 && BoundaryCondition < 5){
|
||||
//TODO to be revised
|
||||
ScaLBL_Comm->Color_BC_z(dvcMap, Phi, Den, inletA, inletB);
|
||||
ScaLBL_Comm->Color_BC_Z(dvcMap, Phi, Den, outletA, outletB);
|
||||
}
|
||||
// Halo exchange for phase field
|
||||
ScaLBL_Comm_Regular->SendHalo(Phi);
|
||||
ScaLBL_Comm_WideHalo->Send(Phi);
|
||||
|
||||
ScaLBL_D3Q19_AAodd_Color(NeighborList, dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm_Regular->RecvHalo(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm_WideHalo->Recv(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_DeviceBarrier();
|
||||
// Set BCs
|
||||
if (BoundaryCondition == 3){
|
||||
@@ -417,7 +654,7 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
||||
}
|
||||
ScaLBL_D3Q19_AAodd_Color(NeighborList, dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_DeviceBarrier();
|
||||
MPI_Barrier(ScaLBL_Comm->MPI_COMM_SCALBL);
|
||||
@@ -425,24 +662,24 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
// *************EVEN TIMESTEP*************
|
||||
timestep++;
|
||||
// Compute the Phase indicator field
|
||||
ScaLBL_Comm->BiSendD3Q7AA(hq,Bq); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAeven_PhaseField(dvcMap, hq, Bq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->BiRecvD3Q7AA(hq,Bq); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->SendD3Q7AA(hq); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAeven_PhaseField(dvcMap, hq, Den, Phi, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q7AA(hq); //WRITE INTO OPPOSITE
|
||||
ScaLBL_DeviceBarrier();
|
||||
ScaLBL_D3Q7_AAeven_PhaseField(dvcMap, hq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_D3Q7_AAeven_PhaseField(dvcMap, hq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
|
||||
// Perform the collision operation
|
||||
ScaLBL_Comm->SendD3Q19AA(fq); //READ FORM NORMAL
|
||||
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FORM NORMAL
|
||||
// Halo exchange for phase field
|
||||
if (BoundaryCondition > 0 && BoundaryCondition < 5){
|
||||
ScaLBL_Comm->Color_BC_z(dvcMap, Phi, Den, inletA, inletB);
|
||||
ScaLBL_Comm->Color_BC_Z(dvcMap, Phi, Den, outletA, outletB);
|
||||
}
|
||||
ScaLBL_Comm_Regular->SendHalo(Phi);
|
||||
ScaLBL_Comm_WideHalo->Send(Phi);
|
||||
ScaLBL_D3Q19_AAeven_Color(dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm_Regular->RecvHalo(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(fq); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm_WideHalo->Recv(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_DeviceBarrier();
|
||||
// Set boundary conditions
|
||||
if (BoundaryCondition == 3){
|
||||
@@ -459,7 +696,6 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
}
|
||||
ScaLBL_D3Q19_AAeven_Color(dvcMap, fq, hq, Bq, Den, Phi, Velocity, rhoA, rhoB, tauA, tauB,
|
||||
alpha, beta, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
*/
|
||||
ScaLBL_Comm->Barrier();
|
||||
//************************************************************************
|
||||
PROFILE_STOP("Update");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ScaLBL_Multiphys_Controller::ScaLBL_Multiphys_Controller(int RANK, int NP, const Utilities::MPI& COMM):
|
||||
rank(RANK),nprocs(NP),Restart(0),timestepMax(0),num_iter_Stokes(0),num_iter_Ion(0),
|
||||
analysis_interval(0),visualization_interval(0),tolerance(0),comm(COMM)
|
||||
analysis_interval(0),visualization_interval(0),tolerance(0),time_conv_max(0),comm(COMM)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ void ScaLBL_Multiphys_Controller::ReadParams(string filename){
|
||||
analysis_interval = 500;
|
||||
visualization_interval = 10000;
|
||||
tolerance = 1.0e-6;
|
||||
time_conv_max = 0.0;
|
||||
|
||||
// load input parameters
|
||||
if (study_db->keyExists( "timestepMax" )){
|
||||
@@ -135,3 +136,12 @@ vector<int> ScaLBL_Multiphys_Controller::getIonNumIter_PNP_coupling(double Stoke
|
||||
}
|
||||
return num_iter_ion;
|
||||
}
|
||||
|
||||
void ScaLBL_Multiphys_Controller::getTimeConvMax_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv){
|
||||
//Return maximum of the time converting factor from Stokes and ion solvers
|
||||
vector<double> TimeConv;
|
||||
|
||||
TimeConv.assign(IonTimeConv.begin(),IonTimeConv.end());
|
||||
TimeConv.insert(TimeConv.begin(),StokesTimeConv);
|
||||
time_conv_max = *max_element(TimeConv.begin(),TimeConv.end());
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
int getStokesNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv);
|
||||
vector<int> getIonNumIter_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv);
|
||||
//void getIonNumIter_PNP_coupling(double StokesTimeConv,vector<double> &IonTimeConv,vector<int> &IonTimeMax);
|
||||
void getTimeConvMax_PNP_coupling(double StokesTimeConv,const vector<double> &IonTimeConv);
|
||||
|
||||
bool Restart;
|
||||
int timestepMax;
|
||||
@@ -35,6 +36,7 @@ public:
|
||||
int analysis_interval;
|
||||
int visualization_interval;
|
||||
double tolerance;
|
||||
double time_conv_max;
|
||||
//double SchmidtNum;//Schmidt number = kinematic_viscosity/mass_diffusivity
|
||||
|
||||
int rank,nprocs;
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
ScaLBL_Poisson::ScaLBL_Poisson(int RANK, int NP, const Utilities::MPI& COMM):
|
||||
rank(RANK), nprocs(NP),timestep(0),timestepMax(0),tau(0),k2_inv(0),tolerance(0),h(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),
|
||||
chargeDen_dummy(0),WriteLog(0),
|
||||
nprocx(0),nprocy(0),nprocz(0),BoundaryCondition(0),BoundaryConditionSolid(0),Lx(0),Ly(0),Lz(0),comm(COMM)
|
||||
chargeDen_dummy(0),WriteLog(0),nprocx(0),nprocy(0),nprocz(0),
|
||||
BoundaryConditionInlet(0),BoundaryConditionOutlet(0),BoundaryConditionSolid(0),Lx(0),Ly(0),Lz(0),
|
||||
Vin0(0),freqIn(0),t0_In(0),Vin_Type(0),Vout0(0),freqOut(0),t0_Out(0),Vout_Type(0),
|
||||
TestPeriodic(0),TestPeriodicTime(0),TestPeriodicTimeConv(0),TestPeriodicSaveInterval(0),
|
||||
comm(COMM)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -33,10 +36,12 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
||||
epsilonR = 78.4;//default dielectric constant of water
|
||||
epsilon_LB = epsilon0_LB*epsilonR;//electric permittivity
|
||||
analysis_interval = 1000;
|
||||
Vin = 1.0; //Boundary-z (inlet) electric potential
|
||||
Vout = 1.0; //Boundary-Z (outlet) electric potential
|
||||
chargeDen_dummy = 1.0e-3;//For debugging;unit=[C/m^3]
|
||||
WriteLog = false;
|
||||
TestPeriodic = false;
|
||||
TestPeriodicTime = 1.0;//unit: [sec]
|
||||
TestPeriodicTimeConv = 0.01; //unit [sec/lt]
|
||||
TestPeriodicSaveInterval = 0.1; //unit [sec]
|
||||
|
||||
// LB-Poisson Model parameters
|
||||
if (electric_db->keyExists( "timestepMax" )){
|
||||
@@ -57,6 +62,18 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
||||
if (electric_db->keyExists( "WriteLog" )){
|
||||
WriteLog = electric_db->getScalar<bool>( "WriteLog" );
|
||||
}
|
||||
if (electric_db->keyExists( "TestPeriodic" )){
|
||||
TestPeriodic = electric_db->getScalar<bool>( "TestPeriodic" );
|
||||
}
|
||||
if (electric_db->keyExists( "TestPeriodicTime" )){
|
||||
TestPeriodicTime = electric_db->getScalar<double>( "TestPeriodicTime" );
|
||||
}
|
||||
if (electric_db->keyExists( "TestPeriodicTimeConv" )){
|
||||
TestPeriodicTimeConv = electric_db->getScalar<double>( "TestPeriodicTimeConv" );
|
||||
}
|
||||
if (electric_db->keyExists( "TestPeriodicSaveInterval" )){
|
||||
TestPeriodicSaveInterval = electric_db->getScalar<double>( "TestPeriodicSaveInterval" );
|
||||
}
|
||||
|
||||
// Read solid boundary condition specific to Poisson equation
|
||||
BoundaryConditionSolid = 1;
|
||||
@@ -65,10 +82,15 @@ void ScaLBL_Poisson::ReadParams(string filename){
|
||||
}
|
||||
// Read boundary condition for electric potential
|
||||
// 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" );
|
||||
// BC = 1: fixed electric potential
|
||||
// BC = 2: sine/cosine periodic electric potential (need extra input parameters)
|
||||
BoundaryConditionInlet = 0;
|
||||
BoundaryConditionOutlet = 0;
|
||||
if (electric_db->keyExists( "BC_Inlet" )){
|
||||
BoundaryConditionInlet = electric_db->getScalar<int>( "BC_Inlet" );
|
||||
}
|
||||
if (electric_db->keyExists( "BC_Outlet" )){
|
||||
BoundaryConditionOutlet = electric_db->getScalar<int>( "BC_Outlet" );
|
||||
}
|
||||
|
||||
// Read domain parameters
|
||||
@@ -117,8 +139,17 @@ void ScaLBL_Poisson::SetDomain(){
|
||||
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = 1; // initialize this way
|
||||
//Averages = std::shared_ptr<TwoPhase> ( new TwoPhase(Dm) ); // TwoPhase analysis object
|
||||
comm.barrier();
|
||||
Dm->BoundaryCondition = BoundaryCondition;
|
||||
Mask->BoundaryCondition = BoundaryCondition;
|
||||
if (BoundaryConditionInlet==0 && BoundaryConditionOutlet==0){
|
||||
Dm->BoundaryCondition = 0;
|
||||
Mask->BoundaryCondition = 0;
|
||||
}
|
||||
else if (BoundaryConditionInlet>0 && BoundaryConditionOutlet>0){
|
||||
Dm->BoundaryCondition = 1;
|
||||
Mask->BoundaryCondition = 1;
|
||||
}
|
||||
else {//i.e. non-periodic and periodic BCs are mixed
|
||||
ERROR("Error: check the type of inlet and outlet boundary condition! Mixed periodic and non-periodic BCs are found!\n");
|
||||
}
|
||||
Dm->CommInit();
|
||||
comm.barrier();
|
||||
|
||||
@@ -343,15 +374,91 @@ void ScaLBL_Poisson::Create(){
|
||||
|
||||
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" );
|
||||
}
|
||||
//set up default boundary input parameters
|
||||
Vin0 = Vout0 = 1.0; //unit: [V]
|
||||
freqIn = freqOut = 50.0; //unit: [Hz]
|
||||
t0_In = t0_Out = 0.0; //unit: [sec]
|
||||
Vin_Type = Vout_Type = 1; //1->sin; 2->cos
|
||||
Vin = 1.0; //Boundary-z (inlet) electric potential
|
||||
Vout = 1.0; //Boundary-Z (outlet) electric potential
|
||||
|
||||
if (BoundaryConditionInlet>0){
|
||||
switch (BoundaryConditionInlet){
|
||||
case 1:
|
||||
if (electric_db->keyExists( "Vin" )){
|
||||
Vin = electric_db->getScalar<double>( "Vin" );
|
||||
}
|
||||
if (rank==0) printf("LB-Poisson Solver: inlet boundary; fixed electric potential Vin = %.3g [V]\n",Vin);
|
||||
break;
|
||||
case 2:
|
||||
if (electric_db->keyExists( "Vin0" )){//voltage amplitude; unit: Volt
|
||||
Vin0 = electric_db->getScalar<double>( "Vin0" );
|
||||
}
|
||||
if (electric_db->keyExists( "freqIn" )){//unit: Hz
|
||||
freqIn = electric_db->getScalar<double>( "freqIn" );
|
||||
}
|
||||
if (electric_db->keyExists( "t0_In" )){//timestep shift, unit: lt
|
||||
t0_In = electric_db->getScalar<double>( "t0_In" );
|
||||
}
|
||||
if (electric_db->keyExists( "Vin_Type" )){
|
||||
//type=1 -> sine
|
||||
//tyep=2 -> cosine
|
||||
Vin_Type = electric_db->getScalar<int>( "Vin_Type" );
|
||||
if (Vin_Type>2 || Vin_Type<=0) ERROR("Error: user-input Vin_Type is currently not supported! \n");
|
||||
}
|
||||
if (rank==0){
|
||||
if (Vin_Type==1){
|
||||
printf("LB-Poisson Solver: inlet boundary; periodic electric potential Vin = %.3g*Sin[2*pi*%.3g*(t+%.3g)] [V]\n",Vin0,freqIn,t0_In);
|
||||
printf(" V0 = %.3g [V], frequency = %.3g [Hz], timestep shift = %.3g [sec] \n",Vin0,freqIn,t0_In);
|
||||
}
|
||||
else if (Vin_Type==2){
|
||||
printf("LB-Poisson Solver: inlet boundary; periodic electric potential Vin = %.3g*Cos[2*pi*%.3g*(t+%.3g)] [V] \n",Vin0,freqIn,t0_In);
|
||||
printf(" V0 = %.3g [V], frequency = %.3g [Hz], timestep shift = %.3g [sec] \n",Vin0,freqIn,t0_In);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (BoundaryConditionOutlet>0){
|
||||
switch (BoundaryConditionOutlet){
|
||||
case 1:
|
||||
if (electric_db->keyExists( "Vout" )){
|
||||
Vout = electric_db->getScalar<double>( "Vout" );
|
||||
}
|
||||
if (rank==0) printf("LB-Poisson Solver: outlet boundary; fixed electric potential Vout = %.3g [V] \n",Vout);
|
||||
break;
|
||||
case 2:
|
||||
if (electric_db->keyExists( "Vout0" )){//voltage amplitude; unit: Volt
|
||||
Vout0 = electric_db->getScalar<double>( "Vout0" );
|
||||
}
|
||||
if (electric_db->keyExists( "freqOut" )){//unit: Hz
|
||||
freqOut = electric_db->getScalar<double>( "freqOut" );
|
||||
}
|
||||
if (electric_db->keyExists( "t0_Out" )){//timestep shift, unit: lt
|
||||
t0_Out = electric_db->getScalar<double>( "t0_Out" );
|
||||
}
|
||||
if (electric_db->keyExists( "Vout_Type" )){
|
||||
//type=1 -> sine
|
||||
//tyep=2 -> cosine
|
||||
Vout_Type = electric_db->getScalar<int>( "Vout_Type" );
|
||||
if (Vout_Type>2 || Vin_Type<=0) ERROR("Error: user-input Vout_Type is currently not supported! \n");
|
||||
}
|
||||
if (rank==0){
|
||||
if (Vout_Type==1){
|
||||
printf("LB-Poisson Solver: outlet boundary; periodic electric potential Vout = %.3g*Sin[2*pi*%.3g*(t+%.3g)] [V]\n",Vout0,freqOut,t0_Out);
|
||||
printf(" V0 = %.3g [V], frequency = %.3g [Hz], timestep shift = %.3g [sec] \n",Vout0,freqOut,t0_Out);
|
||||
}
|
||||
else if (Vout_Type==2){
|
||||
printf("LB-Poisson Solver: outlet boundary; periodic electric potential Vout = %.3g*Cos[2*pi*%.3g*(t+%.3g)] [V]\n",Vout0,freqOut,t0_Out);
|
||||
printf(" V0 = %.3g [V], frequency = %.3g [Hz], timestep shift = %.3g [sec] \n",Vout0,freqOut,t0_Out);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
//By default only periodic BC is applied and Vin=Vout=1.0, i.e. there is no potential gradient along Z-axis
|
||||
if (BoundaryConditionInlet==2) Vin = getBoundaryVoltagefromPeriodicBC(Vin0,freqIn,t0_In,Vin_Type,0);
|
||||
if (BoundaryConditionOutlet==2) Vout = getBoundaryVoltagefromPeriodicBC(Vout0,freqOut,t0_Out,Vout_Type,0);
|
||||
double slope = (Vout-Vin)/(Nz-2);
|
||||
double psi_linearized;
|
||||
for (int k=0;k<Nz;k++){
|
||||
@@ -375,10 +482,15 @@ void ScaLBL_Poisson::Potential_Init(double *psi_init){
|
||||
}
|
||||
}
|
||||
|
||||
double ScaLBL_Poisson::getBoundaryVoltagefromPeriodicBC(double V0, double freq, double t0, int V_type, int time_step){
|
||||
return V0*(V_type==1)*sin(2.0*M_PI*freq*time_conv*(time_step+t0/time_conv))+V0*(V_type==2)*cos(2.0*M_PI*freq*time_conv*(time_step+t0/time_conv));
|
||||
}
|
||||
|
||||
void ScaLBL_Poisson::Initialize(){
|
||||
void ScaLBL_Poisson::Initialize(double time_conv_from_Study){
|
||||
/*
|
||||
* This function initializes model
|
||||
* "time_conv_from_Study" is the phys to LB time conversion factor, unit=[sec/lt]
|
||||
* which is used for periodic voltage input for inlet and outlet boundaries
|
||||
*/
|
||||
if (rank==0) printf ("LB-Poisson Solver: initializing D3Q7 distributions\n");
|
||||
//NOTE the initialization involves two steps:
|
||||
@@ -386,6 +498,7 @@ void ScaLBL_Poisson::Initialize(){
|
||||
//2. Initialize electric potential for pore nodes
|
||||
double *psi_host;
|
||||
psi_host = new double [Nx*Ny*Nz];
|
||||
time_conv = time_conv_from_Study;
|
||||
AssignSolidBoundary(psi_host);//step1
|
||||
Potential_Init(psi_host);//step2
|
||||
ScaLBL_CopyToDevice(Psi, psi_host, Nx*Ny*Nz*sizeof(double));
|
||||
@@ -405,7 +518,7 @@ void ScaLBL_Poisson::Initialize(){
|
||||
//}
|
||||
}
|
||||
|
||||
void ScaLBL_Poisson::Run(double *ChargeDensity){
|
||||
void ScaLBL_Poisson::Run(double *ChargeDensity, int timestep_from_Study){
|
||||
|
||||
//.......create and start timer............
|
||||
//double starttime,stoptime,cputime;
|
||||
@@ -420,13 +533,13 @@ void ScaLBL_Poisson::Run(double *ChargeDensity){
|
||||
// *************ODD TIMESTEP*************//
|
||||
timestep++;
|
||||
|
||||
SolveElectricPotentialAAodd();//update electric potential
|
||||
SolveElectricPotentialAAodd(timestep_from_Study);//update electric potential
|
||||
SolvePoissonAAodd(ChargeDensity);//perform collision
|
||||
ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
|
||||
// *************EVEN TIMESTEP*************//
|
||||
timestep++;
|
||||
SolveElectricPotentialAAeven();//update electric potential
|
||||
SolveElectricPotentialAAeven(timestep_from_Study);//update electric potential
|
||||
SolvePoissonAAeven(ChargeDensity);//perform collision
|
||||
ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
//************************************************************************/
|
||||
@@ -506,29 +619,65 @@ void ScaLBL_Poisson::getConvergenceLog(int timestep,double error){
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_Poisson::SolveElectricPotentialAAodd(){
|
||||
void ScaLBL_Poisson::SolveElectricPotentialAAodd(int timestep_from_Study){
|
||||
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FROM NORMAL
|
||||
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->Barrier();
|
||||
// Set boundary conditions
|
||||
if (BoundaryCondition == 1){
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
if (BoundaryConditionInlet > 0){
|
||||
switch (BoundaryConditionInlet){
|
||||
case 1:
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
break;
|
||||
case 2:
|
||||
Vin = getBoundaryVoltagefromPeriodicBC(Vin0,freqIn,t0_In,Vin_Type,timestep_from_Study);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (BoundaryConditionOutlet > 0){
|
||||
switch (BoundaryConditionOutlet){
|
||||
case 1:
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
break;
|
||||
case 2:
|
||||
Vout = getBoundaryVoltagefromPeriodicBC(Vout0,freqOut,t0_Out,Vout_Type,timestep_from_Study);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-------------------------//
|
||||
ScaLBL_D3Q7_AAodd_Poisson_ElectricPotential(NeighborList, dvcMap, fq, Psi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
}
|
||||
|
||||
void ScaLBL_Poisson::SolveElectricPotentialAAeven(){
|
||||
void ScaLBL_Poisson::SolveElectricPotentialAAeven(int timestep_from_Study){
|
||||
ScaLBL_Comm->SendD3Q7AA(fq, 0); //READ FORM NORMAL
|
||||
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->Barrier();
|
||||
// Set boundary conditions
|
||||
if (BoundaryCondition == 1){
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
if (BoundaryConditionInlet > 0){
|
||||
switch (BoundaryConditionInlet){
|
||||
case 1:
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
break;
|
||||
case 2:
|
||||
Vin = getBoundaryVoltagefromPeriodicBC(Vin0,freqIn,t0_In,Vin_Type,timestep_from_Study);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_z(NeighborList, fq, Vin, timestep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (BoundaryConditionOutlet > 0){
|
||||
switch (BoundaryConditionOutlet){
|
||||
case 1:
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
break;
|
||||
case 2:
|
||||
Vout = getBoundaryVoltagefromPeriodicBC(Vout0,freqOut,t0_Out,Vout_Type,timestep_from_Study);
|
||||
ScaLBL_Comm->D3Q7_Poisson_Potential_BC_Z(NeighborList, fq, Vout, timestep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//-------------------------//
|
||||
ScaLBL_D3Q7_AAeven_Poisson_ElectricPotential(dvcMap, fq, Psi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
|
||||
#include "common/ScaLBL.h"
|
||||
#include "common/Communication.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "analysis/Minkowski.h"
|
||||
#include "ProfilerApp.h"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#ifndef ScaLBL_POISSON_INC
|
||||
#define ScaLBL_POISSON_INC
|
||||
|
||||
@@ -30,8 +32,8 @@ public:
|
||||
void SetDomain();
|
||||
void ReadInput();
|
||||
void Create();
|
||||
void Initialize();
|
||||
void Run(double *ChargeDensity);
|
||||
void Initialize(double time_conv_from_Study);
|
||||
void Run(double *ChargeDensity,int timestep_from_Study);
|
||||
void getElectricPotential(DoubleArray &ReturnValues);
|
||||
void getElectricPotential_debug(int timestep);
|
||||
void getElectricField(DoubleArray &Values_x, DoubleArray &Values_y, DoubleArray &Values_z);
|
||||
@@ -41,7 +43,8 @@ public:
|
||||
//bool Restart,pBC;
|
||||
int timestep,timestepMax;
|
||||
int analysis_interval;
|
||||
int BoundaryCondition;
|
||||
int BoundaryConditionInlet;
|
||||
int BoundaryConditionOutlet;
|
||||
int BoundaryConditionSolid;
|
||||
double tau;
|
||||
double tolerance;
|
||||
@@ -50,11 +53,18 @@ public:
|
||||
double Vin, Vout;
|
||||
double chargeDen_dummy;//for debugging
|
||||
bool WriteLog;
|
||||
double Vin0,freqIn,t0_In,Vin_Type;
|
||||
double Vout0,freqOut,t0_Out,Vout_Type;
|
||||
bool TestPeriodic;
|
||||
double TestPeriodicTime;//unit: [sec]
|
||||
double TestPeriodicTimeConv; //unit [sec/lt]
|
||||
double TestPeriodicSaveInterval; //unit [sec]
|
||||
|
||||
int Nx,Ny,Nz,N,Np;
|
||||
int rank,nprocx,nprocy,nprocz,nprocs;
|
||||
double Lx,Ly,Lz;
|
||||
double h;//image resolution
|
||||
double time_conv;//phys to LB time converting factor; unit=[sec/lt]
|
||||
|
||||
std::shared_ptr<Domain> Dm; // this domain is for analysis
|
||||
std::shared_ptr<Domain> Mask; // this domain is for lbm
|
||||
@@ -91,12 +101,13 @@ private:
|
||||
void AssignSolidBoundary(double *poisson_solid);
|
||||
void Potential_Init(double *psi_init);
|
||||
void ElectricField_LB_to_Phys(DoubleArray &Efield_reg);
|
||||
void SolveElectricPotentialAAodd();
|
||||
void SolveElectricPotentialAAeven();
|
||||
void SolveElectricPotentialAAodd(int timestep_from_Study);
|
||||
void SolveElectricPotentialAAeven(int timestep_from_Study);
|
||||
//void SolveElectricField();
|
||||
void SolvePoissonAAodd(double *ChargeDensity);
|
||||
void SolvePoissonAAeven(double *ChargeDensity);
|
||||
void getConvergenceLog(int timestep,double error);
|
||||
double getBoundaryVoltagefromPeriodicBC(double V0,double freq,double t0,int V_type,int time_step);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
ADD_LBPM_EXECUTABLE( lbpm_color_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_permeability_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_greyscale_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_electrokinetic_SingleFluid_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_greyscaleColor_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_electrokinetic_SingleFluid_simulator )
|
||||
#ADD_LBPM_EXECUTABLE( lbpm_BGK_simulator )
|
||||
#ADD_LBPM_EXECUTABLE( lbpm_color_macro_simulator )
|
||||
ADD_LBPM_EXECUTABLE( lbpm_dfh_simulator )
|
||||
|
||||
@@ -66,7 +66,7 @@ int main(int argc, char **argv)
|
||||
PoissonSolver.SetDomain();
|
||||
PoissonSolver.ReadInput();
|
||||
PoissonSolver.Create();
|
||||
PoissonSolver.Initialize();
|
||||
PoissonSolver.Initialize(0);
|
||||
|
||||
int timestep=0;
|
||||
double error = 1.0;
|
||||
@@ -74,7 +74,7 @@ int main(int argc, char **argv)
|
||||
while (timestep < Study.timestepMax && error > Study.tolerance){
|
||||
|
||||
timestep++;
|
||||
PoissonSolver.Run(IonModel.ChargeDensity);//solve Poisson equtaion to get steady-state electrical potental
|
||||
PoissonSolver.Run(IonModel.ChargeDensity,0);//solve Poisson equtaion to get steady-state electrical potental
|
||||
IonModel.Run(IonModel.FluidVelocityDummy,PoissonSolver.ElectricField); //solve for ion transport and electric potential
|
||||
|
||||
timestep++;//AA operations
|
||||
|
||||
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
|
||||
PoissonSolver.SetDomain();
|
||||
PoissonSolver.ReadInput();
|
||||
PoissonSolver.Create();
|
||||
PoissonSolver.Initialize();
|
||||
PoissonSolver.Initialize(0);
|
||||
|
||||
|
||||
int timestep=0;
|
||||
@@ -94,7 +94,7 @@ int main(int argc, char **argv)
|
||||
while (timestep < Study.timestepMax && error > Study.tolerance){
|
||||
|
||||
timestep++;
|
||||
PoissonSolver.Run(IonModel.ChargeDensity);//solve Poisson equtaion to get steady-state electrical potental
|
||||
PoissonSolver.Run(IonModel.ChargeDensity,0);//solve Poisson equtaion to get steady-state electrical potental
|
||||
StokesModel.Run_Lite(IonModel.ChargeDensity, PoissonSolver.ElectricField);// Solve the N-S equations to get velocity
|
||||
IonModel.Run(StokesModel.Velocity,PoissonSolver.ElectricField); //solve for ion transport and electric potential
|
||||
|
||||
|
||||
@@ -51,14 +51,37 @@ int main(int argc, char **argv)
|
||||
PoissonSolver.SetDomain();
|
||||
PoissonSolver.ReadInput();
|
||||
PoissonSolver.Create();
|
||||
PoissonSolver.Initialize();
|
||||
if (PoissonSolver.TestPeriodic==true){
|
||||
PoissonSolver.Initialize(PoissonSolver.TestPeriodicTimeConv);
|
||||
}
|
||||
else {
|
||||
PoissonSolver.Initialize(0);
|
||||
}
|
||||
|
||||
//Initialize dummy charge density for test
|
||||
PoissonSolver.DummyChargeDensity();
|
||||
|
||||
PoissonSolver.Run(PoissonSolver.ChargeDensityDummy);
|
||||
PoissonSolver.getElectricPotential_debug(1);
|
||||
PoissonSolver.getElectricField_debug(1);
|
||||
if (PoissonSolver.TestPeriodic==true){
|
||||
if (rank==0) printf("Testing periodic voltage input is enabled. Total test time is %.3g[s], saving data every %.3g[s]; user-specified time resolution is %.3g[s/lt]\n",
|
||||
PoissonSolver.TestPeriodicTime,PoissonSolver.TestPeriodicSaveInterval,PoissonSolver.TestPeriodicTimeConv);
|
||||
int timestep = 0;
|
||||
int timeMax = int(PoissonSolver.TestPeriodicTime/PoissonSolver.TestPeriodicTimeConv);
|
||||
int timeSave = int(PoissonSolver.TestPeriodicSaveInterval/PoissonSolver.TestPeriodicTimeConv);
|
||||
while (timestep<timeMax){
|
||||
timestep++;
|
||||
PoissonSolver.Run(PoissonSolver.ChargeDensityDummy,timestep);
|
||||
if (timestep%timeSave==0){
|
||||
if (rank==0) printf(" Time = %.3g[s]; saving electric potential and field\n",timestep*PoissonSolver.TestPeriodicTimeConv);
|
||||
PoissonSolver.getElectricPotential_debug(timestep);
|
||||
PoissonSolver.getElectricField_debug(timestep);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
PoissonSolver.Run(PoissonSolver.ChargeDensityDummy,1);
|
||||
PoissonSolver.getElectricPotential_debug(1);
|
||||
PoissonSolver.getElectricField_debug(1);
|
||||
}
|
||||
|
||||
if (rank==0) printf("Maximum timestep is reached and the simulation is completed\n");
|
||||
if (rank==0) printf("*************************************************************\n");
|
||||
|
||||
@@ -79,20 +79,22 @@ int main(int argc, char **argv)
|
||||
|
||||
IonModel.timestepMax = Study.getIonNumIter_PNP_coupling(StokesModel.time_conv,IonModel.time_conv);
|
||||
IonModel.Initialize();
|
||||
// Get maximal time converting factor based on Sotkes and Ion solvers
|
||||
Study.getTimeConvMax_PNP_coupling(StokesModel.time_conv,IonModel.time_conv);
|
||||
|
||||
// Initialize LB-Poisson model
|
||||
PoissonSolver.ReadParams(filename);
|
||||
PoissonSolver.SetDomain();
|
||||
PoissonSolver.ReadInput();
|
||||
PoissonSolver.Create();
|
||||
PoissonSolver.Initialize();
|
||||
PoissonSolver.Initialize(Study.time_conv_max);
|
||||
|
||||
|
||||
int timestep=0;
|
||||
while (timestep < Study.timestepMax){
|
||||
|
||||
timestep++;
|
||||
PoissonSolver.Run(IonModel.ChargeDensity);//solve Poisson equtaion to get steady-state electrical potental
|
||||
PoissonSolver.Run(IonModel.ChargeDensity,timestep);//solve Poisson equtaion to get steady-state electrical potental
|
||||
StokesModel.Run_Lite(IonModel.ChargeDensity, PoissonSolver.ElectricField);// Solve the N-S equations to get velocity
|
||||
IonModel.Run(StokesModel.Velocity,PoissonSolver.ElectricField); //solve for ion transport and electric potential
|
||||
|
||||
|
||||
Reference in New Issue
Block a user