//Mesh for swept-compression-ramp, coded by Dglin, 2019-11 #include "mpi.h" #include #include #include #include #define PI 3.1415926535897932 FILE *fp; MPI_File tmp_file; MPI_Status status; char str[100]; int my_id, n_processe; int Tec1, Tec2, Mesh2D; int nx, ny, nz, N, NZ, *NPZ, *NP; int nx_inlet, nx_conner, nx_buff; double dx_inlet, Lx_inlet, Lx_conner, alfax_buff; double sw_angle, comp_angle; double High, hy_wall, Lz; double hx0, R; double *xa, *xb, *ya, *yb, *xx, *yy, *xs, *ys, *x3d, *y3d, *z3d; void mpi_init(int *Argc, char ***Argv); void Read_parameter(); void gridx_inlet(int nx, double Length, double dx1, double dx2, double *xx); void gridx(); void gridxy(); void gridxyz(); void Wall_Orthonormalization(); void output(); void Finalize(); void output1d(int n); void output2d(int nx, int ny, double *xx); void output3d(int nx, int ny, int nz, double *xx); int main(int argc, char *argv[]){ mpi_init(&argc , &argv); Read_parameter(); gridx_inlet(nx_inlet + 1, Lx_inlet, dx_inlet, hx0, xa); gridx(); gridxy(); Wall_Orthonormalization(); gridxyz(); output(); //output1d(nx); //output2d(nx, ny, xx); Finalize(); return 0; } void mpi_init(int *Argc , char *** Argv){ MPI_Init(Argc, Argv); MPI_Comm_rank(MPI_COMM_WORLD , &my_id); MPI_Comm_size(MPI_COMM_WORLD, &n_processe); } void Read_parameter(){ if(my_id == 0){ if((fp = fopen("swept-compression-grid.in", "r")) == NULL){ printf("Can't open this file: 'swept-compression-grid.in'\n"); exit(0); } fgets(str, 100, fp); fscanf(fp, "%d%d%d%d\n", &nx,&ny,&nz,&N); fgets(str, 100, fp); fscanf(fp, "%d%d%d\n", &nx_inlet, &nx_conner, &nx_buff); fgets(str, 100, fp); fscanf(fp, "%lf%lf%lf%lf\n", &dx_inlet, &Lx_inlet, &Lx_conner, &alfax_buff); fgets(str, 100, fp); fscanf(fp, "%lf%lf\n", &sw_angle, &comp_angle); fgets(str, 100, fp); fscanf(fp, "%lf%lf%lf\n", &High, &hy_wall, &Lz); fgets(str, 100, fp); fscanf(fp, "%d%d%d\n", &Tec1, &Mesh2D, &Tec2); fclose(fp); if(nx_inlet + nx_conner + nx_buff != nx){ printf("Error ! nx_conner+nx_inlet+nx_buff != nx\n"); exit(0); } printf("Read_parameter is OK!\n"); printf("The Number of total Processes is %d!\n", N); } int tmp1[10]; double tmp2[9]; if(my_id == 0){ tmp1[0] = nx; tmp1[1] = ny; tmp1[2] = nz; tmp1[3] = N; tmp1[4] = nx_inlet; tmp1[5] = nx_conner; tmp1[6] = nx_buff; tmp1[7] = Tec1; tmp1[8] = Mesh2D; tmp1[9] = Tec2; tmp2[0] = dx_inlet; tmp2[1] = Lx_inlet; tmp2[2] = Lx_conner; tmp2[3] = alfax_buff; tmp2[4] = sw_angle; tmp2[5] = comp_angle; tmp2[6] = High; tmp2[7] = hy_wall; tmp2[8] = Lz; } MPI_Bcast(tmp1, 10, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(tmp2, 9, MPI_DOUBLE, 0, MPI_COMM_WORLD); if(my_id != 0){ nx = tmp1[0]; ny = tmp1[1]; nz = tmp1[2]; N = tmp1[3]; nx_inlet = tmp1[4]; nx_conner = tmp1[5]; nx_buff = tmp1[6]; Tec1 = tmp1[7]; Mesh2D = tmp1[8]; Tec2 = tmp1[9]; dx_inlet = tmp2[0]; Lx_inlet = tmp2[1]; Lx_conner = tmp2[2]; alfax_buff = tmp2[3]; sw_angle = tmp2[4]; comp_angle = tmp2[5]; High = tmp2[6]; hy_wall = tmp2[7]; Lz = tmp2[8]; } sw_angle = sw_angle * PI / 180.; comp_angle = comp_angle * PI / 180.; hx0 = 2. * Lx_conner/(nx_conner - 1); R = Lx_conner/tan(comp_angle/2.) - High; NZ = nz/N; if(my_id < nz%N) NZ += 1; NPZ = (int*)malloc(N * sizeof(int)); NP = (int*)malloc(N * sizeof(int)); memset((void*)NPZ, 0, N); memset((void*)NP, 0, N); for(int i = 0; i < N; i++){ if(i < nz%N){ NPZ[i] = (int)nz/N + 1; }else{ NPZ[i] = (int)nz/N; } NP[0] = 0; if(i != 0) NP[i] = NP[i-1] + NPZ[i-1]; } if(NP[N-1] != nz-NPZ[N-1]) printf("NP is wrong![debug]\n"); xa = (double*)malloc(nx * sizeof(double)); xb = (double*)malloc(nx * sizeof(double)); ya = (double*)malloc(nx * sizeof(double)); yb = (double*)malloc(nx * sizeof(double)); xx = (double*)malloc(nx * ny * sizeof(double)); yy = (double*)malloc(nx * ny * sizeof(double)); if(N != n_processe){ if(my_id == 0) printf("The Number of total Processes is not equal to N!\n"); MPI_Finalize(); exit(0); } } void gridx_inlet(int nx, double Length, double dx1, double dx2, double *xx){ double dx, x, Ah1, Sh0, Sh1; dx = Length/(nx - 1.); if(my_id == 0) printf("dx1 is %lf, dx0 is %lf, dx2 is %lf!\n", dx1, dx, dx2); if((dx < dx1 && dx < dx2) || (dx > dx1 && dx > dx2)){ if(my_id == 0) printf("warning ! dx0 should between dx1 and dx2 !!!\n"); } for(int i = 1; i <= nx; i++){ x = (i -1.)/(nx - 1.); Ah1 = (1. - 2. * (x - 1.)) * x * x; Sh0 = x * pow(x - 1.,2); Sh1 = (x - 1.) * x * x; *(xx + i - 1) = Length * Ah1 + dx1 * (nx -1.) * Sh0 + dx2 * (nx - 1.) * Sh1; } } void gridx(){ double seta, dx; //inlet region for(int i = 0; i < nx_inlet; i++){ xa[i] = xa[i] - Lx_conner - Lx_inlet; ya[i] = 0.; xb[i] = xa[i]; yb[i] = High; } //conner region for(int i = 0; i < nx_conner; i++){ seta = comp_angle * i /(nx_conner - 1.); if(seta < comp_angle/2){ xa[i + nx_inlet] = i * hx0 - Lx_conner; ya[i + nx_inlet] = 0.; }else { xa[i + nx_inlet] = (i * hx0 - Lx_conner) * cos(comp_angle); ya[i + nx_inlet] = (i * hx0 - Lx_conner) * sin(comp_angle); } xb[i + nx_inlet] = R * sin(seta) - Lx_conner; yb[i + nx_inlet] = R * (1. - cos(seta)) + High; } //buff region for(int i = 0; i < nx_buff; i++){ dx = (xa[i + nx_inlet + nx_conner -1] - xa[i + nx_inlet + nx_conner - 2]) * alfax_buff; xa[i + nx_inlet + nx_conner] = xa[i + nx_inlet + nx_conner -1] + dx; ya[i + nx_inlet + nx_conner] = ya[i + nx_inlet + nx_conner -1] + dx * tan(comp_angle); xb[i + nx_inlet + nx_conner] = xb[i + nx_inlet + nx_conner -1] + dx; yb[i + nx_inlet + nx_conner] = yb[i + nx_inlet + nx_conner -1] + dx * tan(comp_angle); } MPI_Barrier(MPI_COMM_WORLD); if(my_id == 0) printf("Comput gridx is OK!\n"); } void gridxy(){ double SL, dy, delta, bnew, fb, fbx, s, sy, a, b = 3.5, continue_b = 0; double (*x)[nx] = (double(*)[nx])(xx); double (*y)[nx] = (double(*)[nx])(yy); for(int i = 0; i < nx; i++){ SL = sqrt(pow(xb[i] - xa[i], 2) + pow(yb[i] - ya[i], 2)); dy = 1. / (ny - 1.); delta = hy_wall / SL; do{ continue_bnew:; fb = (exp(b / (ny - 1.)) - 1.)/(exp(b) - 1.) - delta; fbx = (exp(b / (ny - 1.))/(ny - 1.)*(exp(b) - 1.) - (exp(b / (ny - 1.)) - 1.)*exp(b))/pow(exp(b) - 1., 2); bnew = b - fb / fbx; b = bnew; continue_b += 1; } while(abs(bnew - b) > 1.e-6); if(continue_b < 10) goto continue_bnew; a = 1./(exp(b) - 1.); for(int j = 0; j < ny; j++){ s = j * dy; sy = a * (exp(s * b) - 1); x[j][i] = xa[i] + (xb[i] - xa[i]) * sy; y[j][i] = ya[i] + (yb[i] - ya[i]) * sy; } } MPI_Barrier(MPI_COMM_WORLD); if(my_id == 0) printf("Comput gridxy is OK!\n"); } void gridxyz(){ double z, tmp_inlet, tmp_conner; x3d = (double*)malloc(nx * ny * NZ * sizeof(double)); y3d = (double*)malloc(nx * ny * NZ * sizeof(double)); z3d = (double*)malloc(nx * ny * NZ * sizeof(double)); double (*x)[nx] = (double (*)[nx])(xx); double (*y)[nx] = (double (*)[nx])(yy); double (*xx3d)[ny][nx] = (double (*)[ny][nx])(x3d); double (*yy3d)[ny][nx] = (double (*)[ny][nx])(y3d); double (*zz3d)[ny][nx] = (double (*)[ny][nx])(z3d); //for(int i = 0; i < nx_conner; i++){ // // sx[j][i + nx_inlet] = sx[j][nx_inlet - 1] + x[j][i + nx_inlet] - tmp_inlet; // sy[j][i + nx_inlet] = y[j][i + nx_inlet]; // x[j][i + nx_inlet] = x[j][nx_inlet - 1] + x[j][i + nx_inlet] - tmp_inlet; //} // //for(int i = 0; i < nx_buff; i++){ // // lx_buff = x[j][nx - 1] - tmp_conner; // lx_buff_left = lx_buff + (N - my_id - 1) * Lz * tan(sw_angle)/N; // lx_buff_right = lx_buff + (N - my_id) * Lz * tan(sw_angle)/N; // // sx[j][i + nx_inlet + nx_conner] = (x[j][i +nx_inlet + nx_conner] - // tmp_conner) * lx_buff_right / lx_buff + sx[j][nx_inlet + nx_conner - 1]; // // sy[j][i + nx_inlet + nx_conner] = (y[j][i +nx_inlet + nx_conner] - // y[j][nx_inlet + nx_conner - 1]) * lx_buff_right / lx_buff + y[j][nx_inlet + nx_conner - 1]; // x[j][i + nx_inlet + nx_conner] = (x[j][i +nx_inlet + nx_conner] - // tmp_conner) * lx_buff_left / lx_buff + x[j][nx_inlet + nx_conner - 1]; //} // } for(int k = 0; k < NZ; k++){ z = k*Lz*(NPZ[my_id] - 1) / ((NZ - 1)*(nz - 1)) + NP[my_id]*Lz/(nz - 1); for(int j = 0; j < ny; j++){ tmp_inlet = x[j][nx_inlet - 1]; for(int i = 0; i < nx_inlet; i++){ xx3d[k][j][i] = (x[j][i] - x[j][0])*(Lx_inlet - Lz*tan(sw_angle) + Lz/(nz - 1)*(k+NP[my_id])*tan(sw_angle))/Lx_inlet + x[j][0]; yy3d[k][j][i] = y[j][i]; zz3d[k][j][i] = z; } for(int i = nx_inlet; i < nx; i++){ xx3d[k][j][i] = xx3d[k][j][nx_inlet - 1] + x[j][i] - tmp_inlet;; yy3d[k][j][i] = y[j][i]; zz3d[k][j][i] = z; } } } MPI_Barrier(MPI_COMM_WORLD); if(my_id == 0) printf("Comput gridxyz is OK!\n"); } void Wall_Orthonormalization(){ int Maxstep = 10, Jmax = 20; double b = 3., qn, qnx, qny, s; double *dx, *dy, *dx1, *dy1; double (*x)[nx] = (double(*)[nx])(xx); double (*y)[nx] = (double(*)[nx])(yy); dx = (double *)malloc(nx * sizeof(double)); dy = (double *)malloc(nx * sizeof(double)); dx1 = (double *)malloc(nx * sizeof(double)); dy1 = (double *)malloc(nx * sizeof(double)); for(int mstep = 0; mstep < Maxstep; mstep++){ for(int j = 1; j < Jmax; j++){ dx[0] = 0.; dy[0] = 0.; dx[nx - 1] = 0.; dy[nx - 1] = 0.; for(int i = 1; i < nx - 1; i++){ qn = sqrt(pow(x[j][i + 1] - x[j][i - 1],2) + pow(y[j][i + 1] - y[j][i - 1], 2)); qnx = -(y[j][i + 1] - y[j][i - 1])/qn; qny = (x[j][i + 1] - x[j][i - 1])/qn; s = (x[j][i] - x[j - 1][i])*qnx + (y[j][i] - y[j - 1][i])*qny; dx[i] = s * qnx - (x[j][i] - x[j - 1][i]); dy[i] = s * qny - (y[j][i] - y[j - 1][i]); } for(int i = 1; i < nx - 1; i++){ dx1[i] = (dx[i - 1] + 2. * dx[i] + dx[i + 1])/4.; dy1[i] = (dy[i - 1] + 2. * dy[i] + dy[i + 1])/4.; x[j][i] = x[j][i] + exp(-b * j / Jmax)/2. * dx1[i]; y[j][i] = y[j][i] + exp(-b * j / Jmax)/2. * dy1[i]; } } } free(dx); free(dy); free(dx1); free(dy1); MPI_Barrier(MPI_COMM_WORLD); if(my_id == 0) printf("Wall_Orthonormalization is OK!\n"); } #define FWRITE(ptr , size , num , stream){\ int _ENCODE_START = num * size;\ int _ENCODE_END = num * size;\ fwrite(&_ENCODE_START, sizeof(int), 1, stream);\ fwrite(ptr, size, num, stream);\ fwrite(&_ENCODE_END, sizeof(int), 1, stream);\ } #define FWRITE_MPI(ptr , size , num , stream){\ int _ENCODE_START = num * size;\ int _ENCODE_END = num * size;\ MPI_File_write(stream, &_ENCODE_START, 1, MPI_INT, &status);\ MPI_File_write(stream, ptr, size, MPI_DOUBLE, &status);\ MPI_File_write(stream, &_ENCODE_END, 1, MPI_INT, &status);\ } void output(){ int num = nx * ny; int num_byte = nx * ny * sizeof(double); double (*x)[nx] = (double(*)[nx])(xx); double (*y)[nx] = (double(*)[nx])(yy); double (*xx3d)[ny][nx] = (double (*)[ny][nx])(x3d); double (*yy3d)[ny][nx] = (double (*)[ny][nx])(y3d); double (*zz3d)[ny][nx] = (double (*)[ny][nx])(z3d); if(my_id == 0){ fp = fopen("y1d.dat", "w"); for(int j = 0; j < ny; j++){ fprintf(fp, "%15.6f\n", y[j][0]); } fclose(fp); if(Tec1 == 1){ fp = fopen("gridxy.dat", "w"); fprintf(fp, "variables=x,y\n"); fprintf(fp, "zone i=%d ,j=%d\n", nx, ny); for(int j = 0; j < ny; j++){ for(int i = 0; i < nx; i++){ fprintf(fp, "%15.6f%15.6f\n", x[j][i], y[j][i]); } } fclose(fp); } if(Mesh2D == 1){ fp = fopen("OCFD2d-Mesh.dat", "w"); FWRITE(xx, sizeof(double), num, fp); FWRITE(yy, sizeof(double), num, fp); fclose(fp); } } MPI_File_open(MPI_COMM_WORLD, "OCFD3d-Mesh.dat", MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &tmp_file); MPI_File_seek(tmp_file, 0, MPI_SEEK_SET); if(my_id == 0) printf("Write X3d ...\n"); MPI_File_seek(tmp_file, NP[my_id]*(num*sizeof(double) + 2*sizeof(int)), MPI_SEEK_CUR); for(int k = 0; k < NZ; k++){ MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); MPI_File_write(tmp_file, x3d+num*k, num, MPI_DOUBLE, &status); MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); } MPI_File_seek(tmp_file, (nz-NZ)*(num*sizeof(double) + 2*sizeof(int)), MPI_SEEK_CUR); if(my_id == 0) printf("Write Y3d ...\n"); for(int k = 0; k < NZ; k++){ MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); MPI_File_write(tmp_file, y3d+num*k, num, MPI_DOUBLE, &status); MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); } MPI_File_seek(tmp_file, (nz-NZ)*(num*sizeof(double) + 2*sizeof(int)), MPI_SEEK_CUR); if(my_id == 0) printf("Write Z3d ...\n"); for(int k = 0; k < NZ; k++){ MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); MPI_File_write(tmp_file, z3d+num*k, num, MPI_DOUBLE, &status); MPI_File_write(tmp_file, &num_byte, 1, MPI_INT, &status); } //output3d(nx, ny, nz, z3d); MPI_File_close(&tmp_file); if(Tec2 == 1){ if(my_id == 0){ fp = fopen("grid.dat", "w"); fprintf(fp, "variables=x,y,z\n"); fprintf(fp, "zone i=%d ,j=%d ,k=%d\n", nx, ny, nz); } for(int n = 0; n < N; n++){ if(my_id == 0){ for(int k = 0; k < NPZ[n]; k++){ for(int j = 0; j < ny; j++){ for(int i = 0; i < nx; i++){ fprintf(fp, "%15.6f%15.6f%15.6f\n", xx3d[k][j][i], yy3d[k][j][i], zz3d[k][j][i]); } } } } if(my_id != 0){ MPI_Send(x3d, nx*ny*NPZ[my_id], MPI_DOUBLE, my_id-1, 1, MPI_COMM_WORLD); MPI_Send(y3d, nx*ny*NPZ[my_id], MPI_DOUBLE, my_id-1, 1, MPI_COMM_WORLD); MPI_Send(z3d, nx*ny*NPZ[my_id], MPI_DOUBLE, my_id-1, 1, MPI_COMM_WORLD); } if(my_id != N-1){ MPI_Recv(x3d, nx*ny*NPZ[my_id+1], MPI_DOUBLE, my_id+1, 1, MPI_COMM_WORLD, &status); MPI_Recv(y3d, nx*ny*NPZ[my_id+1], MPI_DOUBLE, my_id+1, 1, MPI_COMM_WORLD, &status); MPI_Recv(z3d, nx*ny*NPZ[my_id+1], MPI_DOUBLE, my_id+1, 1, MPI_COMM_WORLD, &status); } } if(my_id == 0) fclose(fp); } } void Finalize(){ free(xa); free(ya); free(xb); free(yb); free(xx); free(yy); free(x3d); free(y3d); free(z3d); MPI_Finalize(); } void output1d(int n){ fp = fopen("grid1d.dat", "w"); for(int i = 0; i < n; i++){ fprintf(fp, "%d\t%16.8f%16.8f%16.8f%16.8f\n", i, *(xa + i), *(ya + i), *(xb + i), *(yb + i)); } fclose(fp); } void output2d(int nx, int ny, double *xx){ double (*x)[nx] = (double(*)[nx])(xx); for(int j = 0; j < ny; j++){ for(int i =0; i < nx; i++){ printf("%d\t%d\t%lf\n", i, j, x[j][i]); } } } void output3d(int nx, int ny, int nz, double *xx){ double (*x)[ny][nx] = (double(*)[ny][nx])(xx); for(int k = 0; k < nz; k++){ for(int j = 0; j < ny; j++){ for(int i = 0; i < nx; i++){ printf("%d\t%d\t%d\t%lf\n", i, j, k, x[k][j][i]); } } } }