/* * Pre-processor to generate signed distance function from segmented data * segmented data should be stored in a raw binary file as 1-byte integer (type char) * will output distance functions for phases */ #include #include #include #include #include #include #include "common/Array.h" #include "common/Domain.h" #include "analysis/TwoPhase.h" #include "analysis/distance.h" inline void MeanFilter(DoubleArray &Mesh){ for (int k=1; k<(int)Mesh.size(2)-1; k++){ for (int j=1; j<(int)Mesh.size(1)-1; j++){ for (int i=1; i<(int)Mesh.size(0)-1; i++){ double sum; sum=Mesh(i,j,k)+Mesh(i+1,j,k)+Mesh(i-1,j,k)+Mesh(i,j+1,k)+Mesh(i,j-1,k)+ +Mesh(i,j,k+1)+Mesh(i,j,k-1); Mesh(i,j,k) = sum/7.0; } } } } double ReadFromBlock( char *ID, int iproc, int jproc, int kproc, int Nx, int Ny, int Nz){ int x,y,z,i,j,k; // Get the list of blocks that contain the local rank int b0x =iproc*(Nx-2)/1024; int b0y =jproc*(Ny-2)/1024; int b0z =kproc*(Nz-2)/1024; int Bx =(iproc+1)*(Nx-2)/1024+1; int By =(jproc+1)*(Ny-2)/1024+1; int Bz =(kproc+1)*(Nz-2)/1024+1; // arrays to hold the strings char LocalRankFilename[40]; char sx[2]; char sy[2]; char sz[2]; // array to store ids read from block char *id; id = new char [1024*1024*1024]; for (int bz=b0z; bz 1) filename=argv[1]; else ERROR("No input database provided\n"); // read the input database auto db = std::make_shared( filename ); auto domain_db = db->getDatabase( "Domain" ); // Read domain parameters auto L = domain_db->getVector( "L" ); auto size = domain_db->getVector( "n" ); auto nproc = domain_db->getVector( "nproc" ); auto ReadValues = domain_db->getVector( "ReadValues" ); auto WriteValues = domain_db->getVector( "WriteValues" ); nx = size[0]; ny = size[1]; nz = size[2]; nprocx = nproc[0]; nprocy = nproc[1]; nprocz = nproc[2]; int N = (nx+2)*(ny+2)*(nz+2); std::shared_ptr Dm (new Domain(domain_db,comm)); // std::shared_ptr Dm (new Domain(nx,ny,nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BC)); for (n=0; nid[n]=1; Dm->CommInit(); std::shared_ptr Averages( new TwoPhase(Dm) ); nx+=2; ny+=2; nz+=2; // Read the phase ID double porosity; sprintf(LocalRankFilename,"ID.%05i",rank); if (READ_FROM_BLOCK == 0){ size_t readID; FILE *ID = fopen(LocalRankFilename,"rb"); readID=fread(Dm->id,1,N,ID); if (readID != size_t(N)) printf("lbpm_segmented_pp: Error reading ID \n"); fclose(ID); } else{ // Read from the large block and write the local ID file if (rank==0) printf("Reading ID file from blocks \n"); fflush(stdout); porosity = ReadFromBlock(Dm->id,Dm->iproc(),Dm->jproc(),Dm->kproc(),nx,ny,nz); MPI_Barrier(MPI_COMM_WORLD); if (rank==0) printf("Writing local ID files (poros=%f) \n",porosity); fflush(stdout); FILE *ID = fopen(LocalRankFilename,"wb"); fwrite(Dm->id,1,N,ID); fclose(ID); if (rank==0) printf("Succeeded! \n"); fflush(stdout); } // Initialize the domain and communication Array id(nx,ny,nz); //TwoPhase Averages(Dm); // DoubleArray Distance(nx,ny,nz); // DoubleArray Phase(nx,ny,nz); int count = 0; // Solve for the position of the solid phase for (k=0;kid[n] > 0) id(i,j,k) = 1; else id(i,j,k) = 0; } } } // Initialize the signed distance function for (k=0;kSDs(i,j,k) = 2.0*double(id(i,j,k))-1.0; } } } MeanFilter(Averages->SDs); if (rank==0) printf("Initialized solid phase -- Converting to Signed Distance function \n"); CalcDist(Averages->SDs,id,*Dm); sprintf(LocalRankFilename,"SignDist.%05i",rank); FILE *DIST = fopen(LocalRankFilename,"wb"); fwrite(Averages->SDs.data(),8,N,DIST); fclose(DIST); } MPI_Barrier(comm); MPI_Finalize(); return 0; }