Parallel Method for solving a Coupled PDE and its application in simulation of thin composite films Parallel Method for solving a Coupled PDE and its application in simulation of thin composite films By: E. Nedaaee IASBS
What is thin film
is thermal fluctuations of the flux of the incoming particles, such that represents the fluctuations in the density of the incoming particles with, the order parameter which represents the difference between the densities of the two types of particles of the surface, the height of the surface Our Model:
Discretization Fully implicit finite difference method
Start Initial Conditions Solve Nonlinear Set of Equations. Finish Yes No Algorithm
Nonlinear Solver Newton-Raphson Method
Initial guess for X Solve. Set. No Yes Return Solving this linear set of equations by Conjugate- Gradient method and store J with sparse manner
Parallelization Method Domain Decomposition Solve Nonlinear Set of Equations. In each domain Yes No z Solve Nonlinear Set of Equations. In each domain Finish No Yes B.C. Exchange
MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nump); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); nump_row = (int) sqrt(nump); dims[0] = nump_row; dims[1] = nump_row; periods[0] = periods[1] = 1; MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 0, &comm); MPI_Comm_rank(comm, &myrank); MPI_Cart_coords(comm, myrank, 2, coords); MPI_Type_hvector(np,1,(np+2)*sizeof(double), MPI_DOUBLE, &BC); MPI_Type_commit(&BC);
rcoords[0] = coords[0]; rcoords[1] = coords[1]+1; if(coords[1] == (nump_row-1)) rcoords[1] = 0; lcoords[0] = coords[0]; lcoords[1] = coords[1]-1; if(coords[1] == 0) lcoords[1] = nump_row - 1; bcoords[1] = coords[1]; bcoords[0] = coords[0]+1; if(coords[0] == (nump_row-1)) bcoords[0] = 0; tcoords[1] = coords[1]; tcoords[0] = coords[0]-1; if(coords[0] == 0) tcoords[0] = nump_row - 1; MPI_Cart_rank(comm, lcoords, &left); MPI_Cart_rank(comm, rcoords, &right); MPI_Cart_rank(comm, tcoords, &top); MPI_Cart_rank(comm, bcoords, &buttom);
MPI_File_open(comm, fh_m_out,MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh_m); MPI_File_open(comm, fh_h_out,MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh_h); MPI_Barrier(comm); lsizes[0] = np; lsizes[1] = np; gsizes[0] = np*nump_row*file_size; gsizes[1] = np*nump_row; memsizes[0] = lsizes[0] + 2; memsizes[1] = lsizes[1] + 2; start_indices[0] = start_indices[1] = 1; MPI_Type_create_subarray(2,memsizes, lsizes, start_indices, MPI_ORDER_C,MPI_DOUBLE, &memtype); MPI_Type_commit(&memtype);
start_indices[0] = coords[0]*lsizes[0]+count_ind*np*nump_row; start_indices[1] = coords[1]*lsizes[1]; MPI_Type_create_subarray(2,gsizes,lsizes,start_indices,MPI_ORDER_C,MPI_D OUBLE,&filetype); MPI_Type_commit(&filetype); MPI_File_set_view(fh_m, 0, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL); MPI_File_set_view(fh_h, 0, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL); MPI_File_write_all(fh_m,u_m, 1, memtype, &status); MPI_Wait(&req, &status); MPI_File_write_all(fh_h,u_h, 1, memtype, &status); MPI_Wait(&req, &status); MPI_Barrier(comm); count_ind +=1;
for(;;){ vecfunc(x); newt(x, &check,vecfunc); MPI_Barrier(comm); BC_exchange(left,right,top,buttom); MPI_Barrier(comm); pnorm_s = NORM(x,x_temp); MPI_Allreduce(&pnorm_s, &pnorm_r, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); if(sqrt(pnorm_r) <= 1.e-9) break; for(int i = 1; i<= 2*np*np; i++) x_temp[i] = x[i]; count +=1; }
void BC_exchange(int left, int right, int top, int buttom){ /*send and received from left neighbor*/ MPI_Isend(&u_h[1][1],np,MPI_DOUBLE, top,0,MPI_COMM_WORLD, &requests[0]); MPI_Irecv(&u_h[0][1],np,MPI_DOUBLE, top,0,MPI_COMM_WORLD, &requests[1]); /*send and received from right neighbor*/ MPI_Isend(&u_h[np][1],np,MPI_DOUBLE, buttom,0,MPI_COMM_WORLD, &requests[2]); MPI_Irecv(&u_h[np+1][1],np,MPI_DOUBLE,buttom,0,MPI_COMM_WORLD, &requests[3]); /*send and received from top neighbor*/ MPI_Isend(&u_h[1][np],1,BC, right,0,MPI_COMM_WORLD, &requests[4]); MPI_Irecv(&u_h[1][np+1],1,BC,right,0,MPI_COMM_WORLD, &requests[5]); /*send and received from bottom neighbor*/ MPI_Isend(&u_h[1][1],1,BC, left,0,MPI_COMM_WORLD, &requests[6]); MPI_Irecv(&u_h[1][0],1,BC, left,0,MPI_COMM_WORLD, &requests[7]); MPI_Waitall(8,requests, statuses);