Merge branch 'FOM' of github.com:JamesEMcClure/LBPM-WIA into FOM
This commit is contained in:
@@ -9,6 +9,7 @@ color lattice boltzmann model
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
ScaLBL_ColorModel::ScaLBL_ColorModel(int RANK, int NP, const Utilities::MPI& COMM):
|
||||
rank(RANK), nprocs(NP), Restart(0), timestep(0), timestepMax(0),
|
||||
tauA(0), tauB(0), rhoA(0), rhoB(0), alpha(0), beta(0),
|
||||
@@ -692,20 +693,15 @@ void ScaLBL_ColorModel::Run(){
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_Comm->Barrier();
|
||||
comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
//.........................................
|
||||
|
||||
//************ MAIN ITERATION LOOP ***************************************/
|
||||
comm.barrier();
|
||||
PROFILE_START("Loop");
|
||||
//std::shared_ptr<Database> analysis_db;
|
||||
bool Regular = false;
|
||||
auto current_db = db->cloneDatabase();
|
||||
runAnalysis analysis( current_db, rank_info, ScaLBL_Comm, Dm, Np, Regular, Map );
|
||||
//analysis.createThreads( analysis_method, 4 );
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax ) {
|
||||
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
|
||||
PROFILE_START("Update");
|
||||
@@ -1038,10 +1034,10 @@ void ScaLBL_ColorModel::Run(){
|
||||
PROFILE_SAVE("lbpm_color_simulator",1);
|
||||
//************************************************************************
|
||||
ScaLBL_Comm->Barrier();
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
@@ -1242,6 +1238,7 @@ double ScaLBL_ColorModel::MorphOpenConnected(double target_volume_change){
|
||||
}
|
||||
return(volume_change);
|
||||
}
|
||||
|
||||
double ScaLBL_ColorModel::SeedPhaseField(const double seed_water_in_oil){
|
||||
srand(time(NULL));
|
||||
double mass_loss =0.f;
|
||||
@@ -1605,3 +1602,68 @@ void ScaLBL_ColorModel::WriteDebug(){
|
||||
fclose(CGZ_FILE);
|
||||
*/
|
||||
}
|
||||
|
||||
FlowAdaptor::FlowAdaptor(ScaLBL_ColorModel &M){
|
||||
Nx = M.Dm->Nx;
|
||||
Ny = M.Dm->Ny;
|
||||
Nz = M.Dm->Nz;
|
||||
timestep=-1;
|
||||
timestep_previous=-1;
|
||||
|
||||
phi.resize(Nx,Ny,Nz); phi.fill(0); // phase indicator field
|
||||
phi_t.resize(Nx,Ny,Nz); phi_t.fill(0); // time derivative for the phase indicator field
|
||||
}
|
||||
|
||||
FlowAdaptor::~FlowAdaptor(){
|
||||
|
||||
}
|
||||
|
||||
double FlowAdaptor::MoveInterface(ScaLBL_ColorModel &M){
|
||||
|
||||
double INTERFACE_CUTOFF = M.color_db->getWithDefault<double>( "move_interface_cutoff", 0.975 );
|
||||
double MOVE_INTERFACE_FACTOR = M.color_db->getWithDefault<double>( "move_interface_factor", 10.0 );
|
||||
|
||||
ScaLBL_CopyToHost( phi.data(), M.Phi, Nx*Ny*Nz* sizeof( double ) );
|
||||
/* compute the local derivative of phase indicator field */
|
||||
double beta = M.beta;
|
||||
double factor = 0.5/beta;
|
||||
double total_interface_displacement = 0.0;
|
||||
double total_interface_sites = 0.0;
|
||||
for (int n=0; n<Nx*Ny*Nz; n++){
|
||||
/* compute the distance to the interface */
|
||||
double value1 = M.Averages->Phi(n);
|
||||
double dist1 = factor*log((1.0+value1)/(1.0-value1));
|
||||
double value2 = phi(n);
|
||||
double dist2 = factor*log((1.0+value2)/(1.0-value2));
|
||||
phi_t(n) = value2;
|
||||
if (value1 < INTERFACE_CUTOFF && value1 > -1*INTERFACE_CUTOFF && value2 < INTERFACE_CUTOFF && value2 > -1*INTERFACE_CUTOFF ){
|
||||
/* time derivative of distance */
|
||||
double dxdt = 0.125*(dist2-dist1);
|
||||
/* extrapolate to move the distance further */
|
||||
double dist3 = dist2 + MOVE_INTERFACE_FACTOR*dxdt;
|
||||
/* compute the new phase interface */
|
||||
phi_t(n) = (2.f*(exp(-2.f*beta*(dist3)))/(1.f+exp(-2.f*beta*(dist3))) - 1.f);
|
||||
total_interface_displacement += fabs(MOVE_INTERFACE_FACTOR*dxdt);
|
||||
total_interface_sites += 1.0;
|
||||
}
|
||||
}
|
||||
ScaLBL_CopyToDevice( M.Phi, phi_t.data(), Nx*Ny*Nz* sizeof( double ) );
|
||||
|
||||
|
||||
/* ScaLBL_PhaseField_Init(dvcMap, Phi, Den, Aq, Bq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_PhaseField_Init(dvcMap, Phi, Den, Aq, Bq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
if (BoundaryCondition == 1 || BoundaryCondition == 2 || BoundaryCondition == 3 || BoundaryCondition == 4){
|
||||
if (Dm->kproc()==0){
|
||||
ScaLBL_SetSlice_z(Phi,1.0,Nx,Ny,Nz,0);
|
||||
ScaLBL_SetSlice_z(Phi,1.0,Nx,Ny,Nz,1);
|
||||
ScaLBL_SetSlice_z(Phi,1.0,Nx,Ny,Nz,2);
|
||||
}
|
||||
if (Dm->kproc() == nprocz-1){
|
||||
ScaLBL_SetSlice_z(Phi,-1.0,Nx,Ny,Nz,Nz-1);
|
||||
ScaLBL_SetSlice_z(Phi,-1.0,Nx,Ny,Nz,Nz-2);
|
||||
ScaLBL_SetSlice_z(Phi,-1.0,Nx,Ny,Nz,Nz-3);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
void Initialize();
|
||||
void Run();
|
||||
void WriteDebug();
|
||||
void getPhaseField(DoubleArray &f);
|
||||
|
||||
bool Restart,pBC;
|
||||
bool REVERSE_FLOW_DIRECTION;
|
||||
@@ -86,3 +87,16 @@ private:
|
||||
double MorphOpenConnected(double target_volume_change);
|
||||
};
|
||||
|
||||
class FlowAdaptor{
|
||||
public:
|
||||
FlowAdaptor(ScaLBL_ColorModel &M);
|
||||
~FlowAdaptor();
|
||||
double MoveInterface(ScaLBL_ColorModel &M);
|
||||
DoubleArray phi;
|
||||
DoubleArray phi_t;
|
||||
private:
|
||||
int Nx, Ny, Nz;
|
||||
int timestep;
|
||||
int timestep_previous;
|
||||
};
|
||||
|
||||
|
||||
@@ -490,14 +490,10 @@ void ScaLBL_DFHModel::Run(){
|
||||
|
||||
if (rank==0) printf("********************************************************\n");
|
||||
if (rank==0) printf("No. of timesteps: %i \n", timestepMax);
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_DeviceBarrier();
|
||||
comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
//.........................................
|
||||
//************ MAIN ITERATION LOOP ***************************************/
|
||||
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
bool Regular = true;
|
||||
PROFILE_START("Loop");
|
||||
runAnalysis analysis( analysis_db, rank_info, ScaLBL_Comm, Dm, Np, Regular, Map );
|
||||
@@ -589,10 +585,10 @@ void ScaLBL_DFHModel::Run(){
|
||||
//************************************************************************
|
||||
ScaLBL_DeviceBarrier();
|
||||
comm.barrier();
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
if (rank==0) printf("********************************************************\n");
|
||||
|
||||
@@ -10,8 +10,9 @@ color lattice boltzmann model
|
||||
#include <time.h>
|
||||
|
||||
ScaLBL_FreeLeeModel::ScaLBL_FreeLeeModel(int RANK, int NP, const Utilities::MPI& COMM):
|
||||
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tauA(0),tauB(0),rhoA(0),rhoB(0),W(0),gamma(0),
|
||||
rank(RANK), nprocs(NP), Restart(0),timestep(0),timestepMax(0),tauA(0),tauB(0),tauM(0),rhoA(0),rhoB(0),W(0),gamma(0),kappa(0),beta(0),
|
||||
Fx(0),Fy(0),Fz(0),flux(0),din(0),dout(0),inletA(0),inletB(0),outletA(0),outletB(0),
|
||||
tau(0),rho0(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)
|
||||
{
|
||||
|
||||
@@ -30,10 +31,15 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
|
||||
// set defaults
|
||||
timestepMax = 100000;
|
||||
tauA = tauB = 1.0;
|
||||
tauM = 1.0;//relaxation time for phase field
|
||||
rhoA = rhoB = 1.0;
|
||||
tau = 1.0;//only for single-fluid Lee model
|
||||
rho0 = 1.0;//only for single-fluid Lee model
|
||||
Fx = Fy = Fz = 0.0;
|
||||
gamma=1e-3;
|
||||
W=5;
|
||||
gamma=1e-3;//surface tension
|
||||
W=5.0;//interfacial thickness
|
||||
beta = 12.0*gamma/W;
|
||||
kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
|
||||
Restart=false;
|
||||
din=dout=1.0;
|
||||
flux=0.0;
|
||||
@@ -42,12 +48,21 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
|
||||
if (freelee_db->keyExists( "timestepMax" )){
|
||||
timestepMax = freelee_db->getScalar<int>( "timestepMax" );
|
||||
}
|
||||
if (freelee_db->keyExists( "tau" )){//only for single-fluid Lee model
|
||||
tau = freelee_db->getScalar<double>( "tau" );
|
||||
}
|
||||
if (freelee_db->keyExists( "tauA" )){
|
||||
tauA = freelee_db->getScalar<double>( "tauA" );
|
||||
}
|
||||
if (freelee_db->keyExists( "tauB" )){
|
||||
tauB = freelee_db->getScalar<double>( "tauB" );
|
||||
}
|
||||
if (freelee_db->keyExists( "tauM" )){
|
||||
tauM = freelee_db->getScalar<double>( "tauM" );
|
||||
}
|
||||
if (freelee_db->keyExists( "rho0" )){
|
||||
rho0 = freelee_db->getScalar<double>( "rho0" );
|
||||
}
|
||||
if (freelee_db->keyExists( "rhoA" )){
|
||||
rhoA = freelee_db->getScalar<double>( "rhoA" );
|
||||
}
|
||||
@@ -81,6 +96,9 @@ void ScaLBL_FreeLeeModel::ReadParams(string filename){
|
||||
inletB=0.f;
|
||||
outletA=0.f;
|
||||
outletB=1.f;
|
||||
//update secondary parameters
|
||||
beta = 12.0*gamma/W;
|
||||
kappa = 3.0*gamma*W/2.0;//beta and kappa are related to surface tension \gamma
|
||||
//if (BoundaryCondition==4) flux *= rhoA; // mass flux must adjust for density (see formulation for details)
|
||||
|
||||
BoundaryCondition = 0;
|
||||
@@ -184,9 +202,9 @@ void ScaLBL_FreeLeeModel::ReadInput(){
|
||||
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Create(){
|
||||
void ScaLBL_FreeLeeModel::Create_TwoFluid(){
|
||||
/*
|
||||
* This function creates the variables needed to run a LBM
|
||||
* This function creates the variables needed to run two-fluid Lee model
|
||||
*/
|
||||
//.........................................................
|
||||
// Initialize communication structures in averaging domain
|
||||
@@ -198,7 +216,7 @@ void ScaLBL_FreeLeeModel::Create(){
|
||||
// Create a communicator for the device (will use optimized layout)
|
||||
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original
|
||||
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||
ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||
//ScaLBL_Comm_Regular = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||
ScaLBL_Comm_WideHalo = std::shared_ptr<ScaLBLWideHalo_Communicator>(new ScaLBLWideHalo_Communicator(Mask,2));
|
||||
|
||||
// create the layout for the LBM
|
||||
@@ -220,7 +238,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,46 +257,301 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check that TmpMap is valid
|
||||
for (int idx=0; idx<ScaLBL_Comm->LastExterior(); idx++){
|
||||
auto n = TmpMap[idx];
|
||||
if (n > Nx*Ny*Nz){
|
||||
if (n > Nxh*Nyh*Nzh){
|
||||
printf("Bad value! idx=%i \n", n);
|
||||
TmpMap[idx] = Nx*Ny*Nz-1;
|
||||
TmpMap[idx] = Nxh*Nyh*Nzh-1;
|
||||
}
|
||||
}
|
||||
for (int idx=ScaLBL_Comm->FirstInterior(); idx<ScaLBL_Comm->LastInterior(); idx++){
|
||||
auto n = TmpMap[idx];
|
||||
if ( n > Nx*Ny*Nz ){
|
||||
if ( n > Nxh*Nyh*Nzh ){
|
||||
printf("Bad value! idx=%i \n",n);
|
||||
TmpMap[idx] = Nx*Ny*Nz-1;
|
||||
TmpMap[idx] = Nxh*Nyh*Nzh-1;
|
||||
}
|
||||
}
|
||||
// copy the device map
|
||||
ScaLBL_CopyToDevice(dvcMap, TmpMap, sizeof(int)*Np);
|
||||
ScaLBL_DeviceBarrier();
|
||||
delete [] TmpMap;
|
||||
|
||||
// copy the neighbor list
|
||||
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
||||
// initialize phi based on PhaseLabel (include solid component labels)
|
||||
comm.barrier();
|
||||
delete [] TmpMap;
|
||||
delete [] neighborList;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* AssignComponentLabels *
|
||||
********************************************************/
|
||||
|
||||
void ScaLBL_FreeLeeModel::Initialize(){
|
||||
|
||||
if (rank==0) printf ("Initializing distributions \n");
|
||||
ScaLBL_D3Q19_Init(fq, Np);
|
||||
void ScaLBL_FreeLeeModel::Create_SingleFluid(){
|
||||
/*
|
||||
* This function initializes model
|
||||
* This function creates the variables needed to run single-fluid Lee model
|
||||
*/
|
||||
//.........................................................
|
||||
// Initialize communication structures in averaging domain
|
||||
for (int i=0; i<Nx*Ny*Nz; i++) Dm->id[i] = Mask->id[i];
|
||||
Mask->CommInit();
|
||||
Np=Mask->PoreCount();
|
||||
//...........................................................................
|
||||
if (rank==0) printf ("Create ScaLBL_Communicator \n");
|
||||
// Create a communicator for the device (will use optimized layout)
|
||||
// ScaLBL_Communicator ScaLBL_Comm(Mask); // original
|
||||
ScaLBL_Comm = std::shared_ptr<ScaLBL_Communicator>(new ScaLBL_Communicator(Mask));
|
||||
|
||||
// create the layout for the LBM
|
||||
int Npad=(Np/16 + 2)*16;
|
||||
if (rank==0) printf ("Set up memory efficient layout, %i | %i | %i \n", Np, Npad, N);
|
||||
Map.resize(Nx,Ny,Nz); Map.fill(-2);
|
||||
auto neighborList= new int[18*Npad];
|
||||
Np = ScaLBL_Comm->MemoryOptimizedLayoutAA(Map,neighborList,Mask->id.data(),Np,1);
|
||||
comm.barrier();
|
||||
|
||||
//...........................................................................
|
||||
// MAIN VARIABLES ALLOCATED HERE
|
||||
//...........................................................................
|
||||
// LBM variables
|
||||
if (rank==0) printf ("Allocating distributions \n");
|
||||
//......................device distributions.................................
|
||||
dist_mem_size = Np*sizeof(double);
|
||||
neighborSize=18*(Np*sizeof(int));
|
||||
//...........................................................................
|
||||
ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &gqbar, 19*dist_mem_size);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &Pressure, sizeof(double)*Np);
|
||||
ScaLBL_AllocateDeviceMemory((void **) &Velocity, 3*sizeof(double)*Np);
|
||||
//...........................................................................
|
||||
// Update GPU data structures
|
||||
if (rank==0) printf ("Setting up device map and neighbor list \n");
|
||||
// copy the neighbor list
|
||||
ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize);
|
||||
comm.barrier();
|
||||
delete [] neighborList;
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::AssignComponentLabels_ChemPotential_ColorGrad()
|
||||
{
|
||||
double *phase;
|
||||
phase = new double[Nh];
|
||||
|
||||
size_t NLABELS=0;
|
||||
signed char VALUE=0;
|
||||
double AFFINITY=0.f;
|
||||
|
||||
auto LabelList = freelee_db->getVector<int>( "ComponentLabels" );
|
||||
auto AffinityList = freelee_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=0;k<Nzh;k++){
|
||||
for (int j=0;j<Nyh;j++){
|
||||
for (int i=0;i<Nxh;i++){
|
||||
|
||||
//idx for double-halo array 'phase'
|
||||
int nh = k*Nxh*Nyh+j*Nxh+i;
|
||||
|
||||
//idx for single-halo array Mask->id[n]
|
||||
int x=i-1;
|
||||
int y=j-1;
|
||||
int z=k-1;
|
||||
if (x<0) x=0;
|
||||
if (y<0) y=0;
|
||||
if (z<0) z=0;
|
||||
if (x>=Nx) x=Nx-1;
|
||||
if (y>=Ny) y=Ny-1;
|
||||
if (z>=Nz) z=Nz-1;
|
||||
int n = z*Nx*Ny+y*Nx+x;
|
||||
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[nh] = 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] = Dm->Comm.sumReduce(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
|
||||
double *ColorGrad_host, *mu_phi_host;
|
||||
ColorGrad_host = new double[3*Np];
|
||||
mu_phi_host = new double[Np];
|
||||
|
||||
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.0/18.0;
|
||||
double w_edge = 1.0/36.0;
|
||||
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;
|
||||
|
||||
double cs2_inv = 3.0;//inverse of c_s^2 for D3Q19 lattice
|
||||
int width = 2;//For better readability: make halo width explicity wherever possible
|
||||
for (int k=width; k<Nzh-width; k++){
|
||||
for (int j=width; j<Nyh-width; j++){
|
||||
for (int i=width; i<Nxh-width; i++){
|
||||
|
||||
//idx for double-halo array 'phase'
|
||||
int nh = k*Nxh*Nyh+j*Nxh+i;
|
||||
|
||||
int idx=Map(i-width+1,j-width+1,k-width+1);
|
||||
if (!(idx < 0)){
|
||||
double phi_x = 0.f;
|
||||
double phi_y = 0.f;
|
||||
double phi_z = 0.f;
|
||||
double phi_Lap = 0.f;//Laplacian of the phase field
|
||||
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 < Nxh)) idi=Nxh-1;
|
||||
if (!(idj < Nyh)) idj=Nyh-1;
|
||||
if (!(idk < Nzh)) idk=Nzh-1;
|
||||
|
||||
int nn = idk*Nxh*Nyh + idj*Nxh + idi;
|
||||
double vec_x = double(ii-1);
|
||||
double vec_y = double(jj-1);
|
||||
double vec_z = double(kk-1);
|
||||
double GWNS=phase[nn];
|
||||
double GWNS_local=phase[nh];
|
||||
phi_x += GWNS*weight*vec_x;
|
||||
phi_y += GWNS*weight*vec_y;
|
||||
phi_z += GWNS*weight*vec_z;
|
||||
phi_Lap += weight*(GWNS-GWNS_local);//Laplacian of the phase field
|
||||
}
|
||||
}
|
||||
}
|
||||
//store color gradient
|
||||
ColorGrad_host[idx+0*Np] = cs2_inv*phi_x;
|
||||
ColorGrad_host[idx+1*Np] = cs2_inv*phi_y;
|
||||
ColorGrad_host[idx+2*Np] = cs2_inv*phi_z;
|
||||
//compute chemical potential
|
||||
phi_Lap = 2.0*cs2_inv*phi_Lap;
|
||||
mu_phi_host[idx] = 4.0*beta*phase[nh]*(phase[nh]+1.0)*(phase[nh]-1.0) - kappa*phi_Lap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//copy all data to device
|
||||
ScaLBL_CopyToDevice(Phi, phase, Nh*sizeof(double));
|
||||
ScaLBL_CopyToDevice(ColorGrad, ColorGrad_host, 3*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(mu_phi, mu_phi_host, Np*sizeof(double));
|
||||
ScaLBL_Comm->Barrier();
|
||||
comm.barrier();
|
||||
|
||||
//debug
|
||||
//save the phase field and check it
|
||||
//FILE *OUTFILE;
|
||||
//sprintf(LocalRankFilename,"Phase_Init.%05i.raw",rank);
|
||||
//OUTFILE = fopen(LocalRankFilename,"wb");
|
||||
//fwrite(phase,8,Nh,OUTFILE);
|
||||
//fclose(OUTFILE);
|
||||
|
||||
|
||||
delete [] phase;
|
||||
delete [] ColorGrad_host;
|
||||
delete [] mu_phi_host;
|
||||
delete [] Dst;
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Initialize_TwoFluid(){
|
||||
/*
|
||||
* This function initializes two-fluid Lee 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 distributions for momentum transport\n");
|
||||
ScaLBL_D3Q19_FreeLeeModel_TwoFluid_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, ColorGrad, rhoA, rhoB, tauM, W, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_FreeLeeModel_PhaseField_Init(dvcMap, Phi, Den, hq, ColorGrad, rhoA, rhoB, tauM, W, 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 +565,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;
|
||||
@@ -331,18 +604,19 @@ void ScaLBL_FreeLeeModel::Initialize(){
|
||||
|
||||
// Copy the restart data to the GPU
|
||||
ScaLBL_CopyToDevice(Den,cDen,2*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(fq,cDist,19*Np*sizeof(double));
|
||||
ScaLBL_CopyToDevice(gqbar,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 and density fields on device from Restart\n");
|
||||
//TODO the following function is to be updated.
|
||||
//ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
//ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// establish reservoirs for external bC
|
||||
// TODO to be revised
|
||||
if (BoundaryCondition == 1 || BoundaryCondition == 2 || BoundaryCondition == 3 || BoundaryCondition == 4 ){
|
||||
if (Dm->kproc()==0){
|
||||
ScaLBL_SetSlice_z(Phi,1.0,Nx,Ny,Nz,0);
|
||||
@@ -358,7 +632,84 @@ void ScaLBL_FreeLeeModel::Initialize(){
|
||||
//ScaLBL_CopyToHost(Averages->Phi.data(),Phi,N*sizeof(double));
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Run(){
|
||||
void ScaLBL_FreeLeeModel::Initialize_SingleFluid(){
|
||||
/*
|
||||
* This function initializes single-fluid Lee model
|
||||
*/
|
||||
if (rank==0) printf ("Initializing distributions for momentum transport\n");
|
||||
ScaLBL_D3Q19_FreeLeeModel_SingleFluid_Init(gqbar, Fx, Fy, Fz, Np);
|
||||
|
||||
if (Restart == true){
|
||||
//TODO need to revise this function
|
||||
//remove the phase-related part
|
||||
|
||||
|
||||
|
||||
// if (rank==0){
|
||||
// printf("Reading restart file! \n");
|
||||
// }
|
||||
//
|
||||
// // Read in the restart file to CPU buffers
|
||||
// int *TmpMap;
|
||||
// TmpMap = new int[Np];
|
||||
//
|
||||
// double *cPhi, *cDist, *cDen;
|
||||
// cPhi = new double[N];
|
||||
// cDen = new double[2*Np];
|
||||
// cDist = new double[19*Np];
|
||||
// ScaLBL_CopyToHost(TmpMap, dvcMap, Np*sizeof(int));
|
||||
// //ScaLBL_CopyToHost(cPhi, Phi, N*sizeof(double));
|
||||
//
|
||||
// ifstream File(LocalRestartFile,ios::binary);
|
||||
// int idx;
|
||||
// double value,va,vb;
|
||||
// for (int n=0; n<Np; n++){
|
||||
// File.read((char*) &va, sizeof(va));
|
||||
// File.read((char*) &vb, sizeof(vb));
|
||||
// cDen[n] = va;
|
||||
// cDen[Np+n] = vb;
|
||||
// }
|
||||
// for (int n=0; n<Np; n++){
|
||||
// // Read the distributions
|
||||
// for (int q=0; q<19; q++){
|
||||
// File.read((char*) &value, sizeof(value));
|
||||
// cDist[q*Np+n] = value;
|
||||
// }
|
||||
// }
|
||||
// File.close();
|
||||
//
|
||||
// for (int n=0; n<ScaLBL_Comm->LastExterior(); n++){
|
||||
// va = cDen[n];
|
||||
// vb = cDen[Np + n];
|
||||
// value = (va-vb)/(va+vb);
|
||||
// idx = TmpMap[n];
|
||||
// if (!(idx < 0) && idx<N)
|
||||
// cPhi[idx] = value;
|
||||
// }
|
||||
// for (int n=ScaLBL_Comm->FirstInterior(); n<ScaLBL_Comm->LastInterior(); n++){
|
||||
// va = cDen[n];
|
||||
// vb = cDen[Np + n];
|
||||
// value = (va-vb)/(va+vb);
|
||||
// idx = TmpMap[n];
|
||||
// if (!(idx < 0) && idx<N)
|
||||
// cPhi[idx] = value;
|
||||
// }
|
||||
//
|
||||
// // Copy the restart data to the GPU
|
||||
// ScaLBL_CopyToDevice(Den,cDen,2*Np*sizeof(double));
|
||||
// ScaLBL_CopyToDevice(gqbar,cDist,19*Np*sizeof(double));
|
||||
// ScaLBL_CopyToDevice(Phi,cPhi,N*sizeof(double));
|
||||
// ScaLBL_Comm->Barrier();
|
||||
// comm.barrier();
|
||||
//
|
||||
// if (rank==0) printf ("Initializing phase and density fields on device from Restart\n");
|
||||
// //TODO the following function is to be updated.
|
||||
// //ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
// //ScaLBL_FreeLeeModel_PhaseField_InitFromRestart(Den, hq, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
}
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Run_TwoFluid(){
|
||||
int nprocs=nprocx*nprocy*nprocz;
|
||||
const RankInfoStruct rank_info(rank,nprocx,nprocy,nprocz);
|
||||
|
||||
@@ -368,98 +719,93 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_DeviceBarrier();
|
||||
comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
//.........................................
|
||||
|
||||
//************ MAIN ITERATION LOOP ***************************************/
|
||||
comm.barrier();
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
PROFILE_START("Loop");
|
||||
while (timestep < timestepMax ) {
|
||||
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
|
||||
PROFILE_START("Update");
|
||||
// *************ODD TIMESTEP*************
|
||||
timestep++;
|
||||
/* // 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_DeviceBarrier();
|
||||
ScaLBL_D3Q7_AAodd_PhaseField(NeighborList, dvcMap, hq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// Compute the Phase indicator field
|
||||
// Read for hq happens in this routine (requires communication)
|
||||
ScaLBL_Comm->SendD3Q7AA(hq,0); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q7AA(hq,0); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
ScaLBL_D3Q7_AAodd_FreeLeeModel_PhaseField(NeighborList, dvcMap, hq, Den, Phi, rhoA, rhoB, 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,
|
||||
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_DeviceBarrier();
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM,
|
||||
kappa, beta, W, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm_WideHalo->Recv(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
// Set BCs
|
||||
if (BoundaryCondition == 3){
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
if (BoundaryCondition == 4){
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 5){
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
|
||||
}
|
||||
ScaLBL_D3Q19_AAodd_Color(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);
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel(NeighborList, dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM,
|
||||
kappa, beta, W, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_Comm->Barrier();
|
||||
|
||||
// *************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_DeviceBarrier();
|
||||
ScaLBL_D3Q7_AAeven_PhaseField(dvcMap, hq, Bq, Den, Phi, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_Comm->SendD3Q7AA(hq,0); //READ FROM NORMAL
|
||||
ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(dvcMap, hq, Den, Phi, rhoA, rhoB, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q7AA(hq,0); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
ScaLBL_D3Q7_AAeven_FreeLeeModel_PhaseField(dvcMap, hq, Den, Phi, rhoA, rhoB, 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_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_DeviceBarrier();
|
||||
ScaLBL_Comm_WideHalo->Send(Phi);
|
||||
ScaLBL_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM,
|
||||
kappa, beta, W, Fx, Fy, Fz, Nx, Nx*Ny, ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm_WideHalo->Recv(Phi);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
// Set boundary conditions
|
||||
if (BoundaryCondition == 3){
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, fq, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 4){
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, fq, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, fq, dout, timestep);
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 5){
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(fq);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(fq);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
|
||||
}
|
||||
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_D3Q19_AAeven_FreeLeeModel(dvcMap, gqbar, hq, Den, Phi, mu_phi, Velocity, Pressure, ColorGrad, rhoA, rhoB, tauA, tauB, tauM,
|
||||
kappa, beta, W, Fx, Fy, Fz, Nx, Nx*Ny, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_Comm->Barrier();
|
||||
//************************************************************************
|
||||
PROFILE_STOP("Update");
|
||||
@@ -467,10 +813,10 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
PROFILE_STOP("Loop");
|
||||
PROFILE_SAVE("lbpm_color_simulator",1);
|
||||
//************************************************************************
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
@@ -484,33 +830,123 @@ void ScaLBL_FreeLeeModel::Run(){
|
||||
// ************************************************************************
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::Run_SingleFluid(){
|
||||
int nprocs=nprocx*nprocy*nprocz;
|
||||
const RankInfoStruct rank_info(rank,nprocx,nprocy,nprocz);
|
||||
|
||||
if (rank==0){
|
||||
printf("********************************************************\n");
|
||||
printf("No. of timesteps: %i \n", timestepMax);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::WriteDebug(){
|
||||
//.......create and start timer............
|
||||
ScaLBL_Comm->Barrier();
|
||||
comm.barrier();
|
||||
//.........................................
|
||||
|
||||
//************ MAIN ITERATION LOOP ***************************************/
|
||||
PROFILE_START("Loop");
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax ) {
|
||||
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
|
||||
PROFILE_START("Update");
|
||||
// *************ODD TIMESTEP*************
|
||||
timestep++;
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// Perform the collision operation
|
||||
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FROM NORMAL
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
|
||||
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
// Set boundary conditions
|
||||
// TODO to be revised!
|
||||
if (BoundaryCondition == 3){
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
if (BoundaryCondition == 4){
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 5){
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
|
||||
}
|
||||
ScaLBL_D3Q19_AAodd_FreeLeeModel_SingleFluid_BGK(NeighborList, gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
|
||||
0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_Comm->Barrier();
|
||||
|
||||
// *************EVEN TIMESTEP*************
|
||||
timestep++;
|
||||
//-------------------------------------------------------------------------------------------------------------------
|
||||
// Perform the collision operation
|
||||
ScaLBL_Comm->SendD3Q19AA(gqbar); //READ FORM NORMAL
|
||||
ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
|
||||
ScaLBL_Comm->FirstInterior(), ScaLBL_Comm->LastInterior(), Np);
|
||||
ScaLBL_Comm->RecvD3Q19AA(gqbar); //WRITE INTO OPPOSITE
|
||||
ScaLBL_Comm->Barrier();
|
||||
// Set boundary conditions
|
||||
// TODO to be revised!
|
||||
if (BoundaryCondition == 3){
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_z(NeighborList, gqbar, din, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 4){
|
||||
din = ScaLBL_Comm->D3Q19_Flux_BC_z(NeighborList, gqbar, flux, timestep);
|
||||
ScaLBL_Comm->D3Q19_Pressure_BC_Z(NeighborList, gqbar, dout, timestep);
|
||||
}
|
||||
else if (BoundaryCondition == 5){
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_z(gqbar);
|
||||
ScaLBL_Comm->D3Q19_Reflection_BC_Z(gqbar);
|
||||
}
|
||||
ScaLBL_D3Q19_AAeven_FreeLeeModel_SingleFluid_BGK(gqbar, Velocity, Pressure, tau, rho0, Fx, Fy, Fz,
|
||||
0, ScaLBL_Comm->LastExterior(), Np);
|
||||
ScaLBL_Comm->Barrier();
|
||||
//************************************************************************
|
||||
PROFILE_STOP("Update");
|
||||
}
|
||||
PROFILE_STOP("Loop");
|
||||
PROFILE_SAVE("lbpm_color_simulator",1);
|
||||
//************************************************************************
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
if (rank==0) printf("********************************************************\n");
|
||||
if (rank==0) printf("CPU time = %f \n", cputime);
|
||||
if (rank==0) printf("Lattice update rate (per core)= %f MLUPS \n", MLUPS);
|
||||
MLUPS *= nprocs;
|
||||
if (rank==0) printf("Lattice update rate (total)= %f MLUPS \n", MLUPS);
|
||||
if (rank==0) printf("********************************************************\n");
|
||||
|
||||
// ************************************************************************
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::WriteDebug_TwoFluid(){
|
||||
// Copy back final phase indicator field and convert to regular layout
|
||||
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||
DoubleArray PhaseData(Nxh,Nyh,Nzh);
|
||||
//ScaLBL_Comm->RegularLayout(Map,Phi,PhaseField);
|
||||
ScaLBL_CopyToHost(PhaseField.data(), Phi, sizeof(double)*N);
|
||||
ScaLBL_CopyToHost(PhaseData.data(), Phi, sizeof(double)*Nh);
|
||||
|
||||
FILE *OUTFILE;
|
||||
sprintf(LocalRankFilename,"Phase.%05i.raw",rank);
|
||||
OUTFILE = fopen(LocalRankFilename,"wb");
|
||||
fwrite(PhaseField.data(),8,N,OUTFILE);
|
||||
fwrite(PhaseData.data(),8,Nh,OUTFILE);
|
||||
fclose(OUTFILE);
|
||||
|
||||
ScaLBL_Comm->RegularLayout(Map,&Den[0],PhaseField);
|
||||
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||
ScaLBL_Comm->RegularLayout(Map,Den,PhaseField);
|
||||
FILE *AFILE;
|
||||
sprintf(LocalRankFilename,"A.%05i.raw",rank);
|
||||
sprintf(LocalRankFilename,"Density.%05i.raw",rank);
|
||||
AFILE = fopen(LocalRankFilename,"wb");
|
||||
fwrite(PhaseField.data(),8,N,AFILE);
|
||||
fclose(AFILE);
|
||||
|
||||
ScaLBL_Comm->RegularLayout(Map,&Den[Np],PhaseField);
|
||||
FILE *BFILE;
|
||||
sprintf(LocalRankFilename,"B.%05i.raw",rank);
|
||||
BFILE = fopen(LocalRankFilename,"wb");
|
||||
fwrite(PhaseField.data(),8,N,BFILE);
|
||||
fclose(BFILE);
|
||||
|
||||
ScaLBL_Comm->RegularLayout(Map,Pressure,PhaseField);
|
||||
FILE *PFILE;
|
||||
sprintf(LocalRankFilename,"Pressure.%05i.raw",rank);
|
||||
@@ -561,3 +997,37 @@ void ScaLBL_FreeLeeModel::WriteDebug(){
|
||||
fclose(CGZ_FILE);
|
||||
*/
|
||||
}
|
||||
|
||||
void ScaLBL_FreeLeeModel::WriteDebug_SingleFluid(){
|
||||
|
||||
DoubleArray PhaseField(Nx,Ny,Nz);
|
||||
|
||||
// Copy back final phase indicator field and convert to regular layout
|
||||
ScaLBL_Comm->RegularLayout(Map,Pressure,PhaseField);
|
||||
FILE *PFILE;
|
||||
sprintf(LocalRankFilename,"Pressure.%05i.raw",rank);
|
||||
PFILE = fopen(LocalRankFilename,"wb");
|
||||
fwrite(PhaseField.data(),8,N,PFILE);
|
||||
fclose(PFILE);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -26,16 +26,22 @@ public:
|
||||
void ReadParams(std::shared_ptr<Database> db0);
|
||||
void SetDomain();
|
||||
void ReadInput();
|
||||
void Create();
|
||||
void Initialize();
|
||||
void Run();
|
||||
void WriteDebug();
|
||||
void Create_TwoFluid();
|
||||
void Initialize_TwoFluid();
|
||||
void Run_TwoFluid();
|
||||
void WriteDebug_TwoFluid();
|
||||
void Create_SingleFluid();
|
||||
void Initialize_SingleFluid();
|
||||
void Run_SingleFluid();
|
||||
void WriteDebug_SingleFluid();
|
||||
|
||||
bool Restart,pBC;
|
||||
int timestep,timestepMax;
|
||||
int BoundaryCondition;
|
||||
double tauA,tauB,rhoA,rhoB;
|
||||
double W,gamma;
|
||||
double tau, rho0;//only for single-fluid Lee model
|
||||
double tauM;//relaxation time for phase field (or mass)
|
||||
double W,gamma,kappa,beta;
|
||||
double Fx,Fy,Fz,flux;
|
||||
double din,dout,inletA,inletB,outletA,outletB;
|
||||
|
||||
@@ -61,7 +67,7 @@ public:
|
||||
signed char *id;
|
||||
int *NeighborList;
|
||||
int *dvcMap;
|
||||
double *fq, *hq;
|
||||
double *gqbar, *hq;
|
||||
double *mu_phi, *Den, *Phi;
|
||||
double *ColorGrad;
|
||||
double *Velocity;
|
||||
@@ -81,6 +87,7 @@ private:
|
||||
|
||||
//int rank,nprocs;
|
||||
void LoadParams(std::shared_ptr<Database> db0);
|
||||
void AssignComponentLabels_ChemPotential_ColorGrad();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -910,10 +910,8 @@ void ScaLBL_GreyscaleColorModel::Run(){
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_Comm->Barrier();
|
||||
comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
//.........................................
|
||||
|
||||
//************ MAIN ITERATION LOOP ***************************************/
|
||||
@@ -923,6 +921,7 @@ void ScaLBL_GreyscaleColorModel::Run(){
|
||||
auto current_db = db->cloneDatabase();
|
||||
//runAnalysis analysis( current_db, rank_info, ScaLBL_Comm, Dm, Np, Regular, Map );
|
||||
//analysis.createThreads( analysis_method, 4 );
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax ) {
|
||||
//if ( rank==0 ) { printf("Running timestep %i (%i MB)\n",timestep+1,(int)(Utilities::getMemoryUsage()/1048576)); }
|
||||
PROFILE_START("Update");
|
||||
@@ -1319,10 +1318,10 @@ void ScaLBL_GreyscaleColorModel::Run(){
|
||||
PROFILE_SAVE("lbpm_color_simulator",1);
|
||||
//************************************************************************
|
||||
ScaLBL_Comm->Barrier();
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
|
||||
@@ -485,10 +485,8 @@ void ScaLBL_GreyscaleModel::Run(){
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_DeviceBarrier();
|
||||
comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
//.........................................
|
||||
|
||||
Minkowski Morphology(Mask);
|
||||
@@ -500,6 +498,7 @@ void ScaLBL_GreyscaleModel::Run(){
|
||||
double rlx_eff = 1.0/tau_eff;
|
||||
double error = 1.0;
|
||||
double flow_rate_previous = 0.0;
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax && error > tolerance) {
|
||||
//************************************************************************/
|
||||
// *************ODD TIMESTEP*************//
|
||||
@@ -744,10 +743,10 @@ void ScaLBL_GreyscaleModel::Run(){
|
||||
//************************************************************************
|
||||
ScaLBL_DeviceBarrier();
|
||||
comm.barrier();
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
|
||||
@@ -784,7 +784,7 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){
|
||||
//.......create and start timer............
|
||||
//double starttime,stoptime,cputime;
|
||||
//ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
//starttime = MPI_Wtime();
|
||||
//auto t1 = std::chrono::system_clock::now();
|
||||
|
||||
for (int ic=0; ic<number_ion_species; ic++){
|
||||
timestep=0;
|
||||
@@ -886,10 +886,10 @@ void ScaLBL_IonModel::Run(double *Velocity, double *ElectricField){
|
||||
ScaLBL_D3Q7_Ion_ChargeDensity(Ci, ChargeDensity, IonValence[ic], ic, 0, ScaLBL_Comm->LastExterior(), Np);
|
||||
}
|
||||
//************************************************************************/
|
||||
//stoptime = MPI_Wtime();
|
||||
//if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
//// Compute the walltime per timestep
|
||||
//cputime = (stoptime - starttime)/timestep;
|
||||
//auto t2 = std::chrono::system_clock::now();
|
||||
//double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
//// Performance obtained from each node
|
||||
//double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
|
||||
@@ -230,14 +230,13 @@ void ScaLBL_MRTModel::Run(){
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_DeviceBarrier(); comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
if (rank==0) printf("Beginning AA timesteps, timestepMax = %i \n", timestepMax);
|
||||
if (rank==0) printf("********************************************************\n");
|
||||
timestep=0;
|
||||
double error = 1.0;
|
||||
double flow_rate_previous = 0.0;
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax && error > tolerance) {
|
||||
//************************************************************************/
|
||||
timestep++;
|
||||
@@ -354,10 +353,10 @@ void ScaLBL_MRTModel::Run(){
|
||||
}
|
||||
}
|
||||
//************************************************************************/
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
|
||||
@@ -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,12 +518,12 @@ 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;
|
||||
//ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
//starttime = MPI_Wtime();
|
||||
//comm.barrier();
|
||||
//auto t1 = std::chrono::system_clock::now();
|
||||
|
||||
timestep=0;
|
||||
double error = 1.0;
|
||||
@@ -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();
|
||||
//************************************************************************/
|
||||
@@ -466,11 +579,11 @@ void ScaLBL_Poisson::Run(double *ChargeDensity){
|
||||
}
|
||||
|
||||
//************************************************************************/
|
||||
//stoptime = MPI_Wtime();
|
||||
////if (rank==0) printf("LB-Poission Solver: a steady-state solution is obtained\n");
|
||||
////if (rank==0) printf("---------------------------------------------------------------------------\n");
|
||||
//// Compute the walltime per timestep
|
||||
//cputime = (stoptime - starttime)/timestep;
|
||||
//auto t2 = std::chrono::system_clock::now();
|
||||
//double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
//// Performance obtained from each node
|
||||
//double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -573,16 +573,14 @@ void ScaLBL_StokesModel::Run(){
|
||||
}
|
||||
}
|
||||
|
||||
//.......create and start timer............
|
||||
double starttime,stoptime,cputime;
|
||||
ScaLBL_Comm->Barrier(); comm.barrier();
|
||||
starttime = MPI_Wtime();
|
||||
if (rank==0) printf("****************************************************************\n");
|
||||
if (rank==0) printf("LB Single-Fluid Navier-Stokes Solver: timestepMax = %i\n", timestepMax);
|
||||
if (rank==0) printf("****************************************************************\n");
|
||||
timestep=0;
|
||||
double error = 1.0;
|
||||
double flow_rate_previous = 0.0;
|
||||
auto t1 = std::chrono::system_clock::now();
|
||||
while (timestep < timestepMax && error > tolerance) {
|
||||
//************************************************************************/
|
||||
timestep++;
|
||||
@@ -700,10 +698,10 @@ void ScaLBL_StokesModel::Run(){
|
||||
}
|
||||
}
|
||||
//************************************************************************/
|
||||
stoptime = MPI_Wtime();
|
||||
if (rank==0) printf("-------------------------------------------------------------------\n");
|
||||
// Compute the walltime per timestep
|
||||
cputime = (stoptime - starttime)/timestep;
|
||||
auto t2 = std::chrono::system_clock::now();
|
||||
double cputime = std::chrono::duration<double>( t2 - t1 ).count() / timestep;
|
||||
// Performance obtained from each node
|
||||
double MLUPS = double(Np)/cputime/1000000;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user