//************************************************************************* // Lattice Boltzmann Simulator for Single Phase Flow in Porous Media // James E. McCLure //************************************************************************* #include #include #include #include "common/ScaLBL.h" #include "common/MPI_Helpers.h" using namespace std; //*************************************************************************************** int main(int argc, char **argv) { //***************************************** // ***** MPI STUFF **************** //***************************************** // Initialize MPI int rank,nprocs; MPI_Init(&argc,&argv); MPI_Comm comm = MPI_COMM_WORLD; MPI_Comm_rank(comm,&rank); MPI_Comm_size(comm,&nprocs); int check; { // parallel domain size (# of sub-domains) int nprocx,nprocy,nprocz; int iproc,jproc,kproc; if (rank == 0){ printf("********************************************************\n"); printf("Running Unit Test: TestPressVel \n"); printf("********************************************************\n"); } // BGK Model parameters string FILENAME; unsigned int nBlocks, nthreads; int timestepMax, interval; double tau,Fx,Fy,Fz,tol; // Domain variables double Lx,Ly,Lz; int nspheres; int Nx,Ny,Nz; int i,j,k,n; int dim = 50; if (rank == 0) printf("dim=%d\n",dim); double rlx_setA=1.0; double rlx_setB=1.0; Fx = Fy = 0.f; Fz = 1.0e-4; if (rank==0){ //....................................................................... // Reading the domain information file //....................................................................... ifstream domain("Domain.in"); if (domain.good()){ domain >> nprocx; domain >> nprocy; domain >> nprocz; domain >> Nx; domain >> Ny; domain >> Nz; domain >> nspheres; domain >> Lx; domain >> Ly; domain >> Lz; } else if (nprocs==1){ nprocx=nprocy=nprocz=1; Nx=4; Ny = 4; Nz = 4; nspheres=0; Lx=Ly=Lz=1; } //....................................................................... } // ************************************************************** // Broadcast simulation parameters from rank 0 to all other procs MPI_Barrier(comm); //................................................. MPI_Bcast(&Nx,1,MPI_INT,0,comm); MPI_Bcast(&Ny,1,MPI_INT,0,comm); MPI_Bcast(&Nz,1,MPI_INT,0,comm); MPI_Bcast(&nprocx,1,MPI_INT,0,comm); MPI_Bcast(&nprocy,1,MPI_INT,0,comm); MPI_Bcast(&nprocz,1,MPI_INT,0,comm); MPI_Bcast(&nspheres,1,MPI_INT,0,comm); MPI_Bcast(&Lx,1,MPI_DOUBLE,0,comm); MPI_Bcast(&Ly,1,MPI_DOUBLE,0,comm); MPI_Bcast(&Lz,1,MPI_DOUBLE,0,comm); //................................................. MPI_Barrier(comm); // ************************************************************** // ************************************************************** if (nprocs != nprocx*nprocy*nprocz){ printf("nprocx = %i \n",nprocx); printf("nprocy = %i \n",nprocy); printf("nprocz = %i \n",nprocz); INSIST(nprocs == nprocx*nprocy*nprocz,"Fatal error in processor count!"); } if (rank==0){ printf("********************************************************\n"); printf("Sub-domain size = %i x %i x %i\n",Nx,Ny,Nz); printf("********************************************************\n"); } MPI_Barrier(comm); kproc = rank/(nprocx*nprocy); jproc = (rank-nprocx*nprocy*kproc)/nprocx; iproc = rank-nprocx*nprocy*kproc-nprocz*jproc; if (rank == 0) { printf("i,j,k proc=%d %d %d \n",iproc,jproc,kproc); } MPI_Barrier(comm); if (rank == 1){ printf("i,j,k proc=%d %d %d \n",iproc,jproc,kproc); printf("\n\n"); } double iVol_global = 1.0/Nx/Ny/Nz/nprocx/nprocy/nprocz; int BoundaryCondition=0; Domain Dm(Nx,Ny,Nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BoundaryCondition); Nx += 2; Ny += 2; Nz += 2; int N = Nx*Ny*Nz; //....................................................................... // Assign the phase ID field //....................................................................... char LocalRankString[8]; sprintf(LocalRankString,"%05d",rank); char LocalRankFilename[40]; sprintf(LocalRankFilename,"ID.%05i",rank); /* FILE *IDFILE = fopen(LocalRankFilename,"rb"); if (IDFILE==NULL) ERROR("Error opening file: ID.xxxxx"); fread(Dm.id,1,N,IDFILE); fclose(IDFILE); */ Dm.CommInit(comm); //....................................................................... // Compute the media porosity //....................................................................... double sum; double sum_local=0.0, porosity; int Np=0; // number of local pore nodes for (k=1;k 0){ sum_local+=1.0; Np++; } } } } MPI_Allreduce(&sum_local,&sum,1,MPI_DOUBLE,MPI_SUM,comm); porosity = sum*iVol_global; if (rank==0) printf("Media porosity = %f \n",porosity); MPI_Barrier(comm); if (rank == 0) cout << "Domain set." << endl; if (rank==0) printf ("Create ScaLBL_Communicator \n"); // Create a communicator for the device ScaLBL_Communicator ScaLBL_Comm(Dm); //...........device phase ID................................................. if (rank==0) printf ("Copying phase ID to device \n"); char *ID; ScaLBL_AllocateDeviceMemory((void **) &ID, N); // Allocate device memory // Copy to the device ScaLBL_CopyToDevice(ID, Dm.id, N); //........................................................................... if (rank==0){ printf("Total domain size = %i \n",N); printf("Reduced domain size = %i \n",Np); } // LBM variables if (rank==0) printf ("Allocating distributions \n"); int neighborSize=18*Np*sizeof(int); int *neighborList; IntArray Map(Nx,Ny,Nz); neighborList= new int[18*Np]; ScaLBL_Comm.MemoryOptimizedLayoutAA(Map,neighborList,Dm.id,Np); // ScaLBL_Comm.MemoryDenseLayoutFull(Map,neighborList,Dm.id,Np); // this was how I tested for correctness MPI_Barrier(comm); //......................device distributions................................. int dist_mem_size = Np*sizeof(double); int *NeighborList; // double *f_even,*f_odd; double * dist; double * Velocity; //........................................................................... ScaLBL_AllocateDeviceMemory((void **) &dist, 19*dist_mem_size); ScaLBL_AllocateDeviceMemory((void **) &NeighborList, neighborSize); ScaLBL_AllocateDeviceMemory((void **) &Velocity, 3*sizeof(double)*Np); ScaLBL_CopyToDevice(NeighborList, neighborList, neighborSize); //........................................................................... /* * AA Algorithm begins here * */ //ScaLBL_D3Q19_Init(ID, dist, &dist[10*Np], Np, 1, 1); double *DIST; DIST = new double [19*Np]; double VALUE=0.1; for (int n=0; n 1e-8){ printf("ERROR: site %i, value=%f \n",n,Vz[n]); check = 15; } } } // **************************************************** MPI_Barrier(comm); MPI_Finalize(); // **************************************************** }