/* * 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/distance.h" #include "analysis/morphology.h" //************************************************************************* // Morpohologica pre-processor // Initialize phase distribution using morphological approach // Signed distance function is used to determine fluid configuration //************************************************************************* int main(int argc, char **argv) { // 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); { //....................................................................... // Reading the domain information file //....................................................................... char LocalRankFilename[40]; string filename; double SW,Rcrit_new; if (argc > 1){ filename=argv[1]; Rcrit_new=0.f; //SW=strtod(argv[2],NULL); } else ERROR("No input database provided\n"); NULL_USE( Rcrit_new ); // read the input database auto db = std::make_shared( filename ); auto domain_db = db->getDatabase( "Domain" ); // Read domain parameters auto READFILE = domain_db->getScalar( "Filename" ); auto size = domain_db->getVector( "n" ); auto nproc = domain_db->getVector( "nproc" ); auto ReadValues = domain_db->getVector( "ReadValues" ); auto WriteValues = domain_db->getVector( "WriteValues" ); SW = domain_db->getScalar("Sw"); signed char ErodeLabel=2; signed char OpenLabel=1; if (domain_db->keyExists( "OpenLabel" )){ OpenLabel = domain_db->getScalar("OpenLabel"); } if (domain_db->keyExists( "ErodeLabel" )){ ErodeLabel = domain_db->getScalar("ErodeLabel"); } // Generate the NWP configuration //if (rank==0) printf("Initializing morphological distribution with critical radius %f \n", Rcrit); if (rank==0) printf("Performing morphological opening with target saturation %f \n", SW); // GenerateResidual(id,nx,ny,nz,Saturation); int nx = size[0]; int ny = size[1]; int nz = size[2]; size_t N = (nx+2)*(ny+2)*(nz+2); std::shared_ptr Dm (new Domain(domain_db,comm)); std::shared_ptr Mask (new Domain(domain_db,comm)); // std::shared_ptr Dm (new Domain(nx,ny,nz,rank,nprocx,nprocy,nprocz,Lx,Ly,Lz,BC)); for (size_t n=0; nid[n]=1; Dm->CommInit(); signed char *id; id = new signed char [N]; Mask->Decomp(READFILE); Mask->CommInit(); // Generate the NWP configuration //if (rank==0) printf("Initializing morphological distribution with critical radius %f \n", Rcrit); if (rank==0) printf("Performing morphological opening with target saturation %f \n", SW); // GenerateResidual(id,nx,ny,nz,Saturation); nx+=2; ny+=2; nz+=2; // Generate the signed distance map // Initialize the domain and communication Array id_solid(nx,ny,nz); DoubleArray SignDist(nx,ny,nz); // Solve for the position of the solid phase for (int k=0;kid[n]; // Initialize the solid phase if (Mask->id[n] > 0){ id_solid(i,j,k) = 1; } else id_solid(i,j,k) = 0; } } } // Initialize the signed distance function for (int k=0;kkeyExists( "HistoryLabels" )){ if (rank==0) printf("Relabel solid components that touch fluid 1 \n"); auto LabelList = domain_db->getVector( "ComponentLabels" ); auto HistoryLabels = domain_db->getVector( "HistoryLabels" ); size_t NLABELS=LabelList.size(); if (rank==0){ for (unsigned int idx=0; idx < NLABELS; idx++){ signed char VALUE = LabelList[idx]; signed char NEWVAL = HistoryLabels[idx]; printf(" Relabel component %d as %d \n", VALUE, NEWVAL); } } for (int k=0;kid[n] = id[n]; } } } MPI_Barrier(comm); auto filename2 = READFILE + ".morphopen.raw"; if (rank==0) printf("Writing file to: %s \n", filename2.data()); Mask->AggregateLabels(filename2); } MPI_Barrier(comm); MPI_Finalize(); }