subroutine exchange_ghost_particles(comm3d,worker_comm,local_nb_mps, local_mps, ghost_mps, max_ghosts, ghost_count,local_xmin, local_xmax, local_zmin, local_zmax, re,rank,global_indices)
implicit none
include 'mpif.h'
integer, intent(in) :: comm3d, max_ghosts,rank,worker_comm,global_indices(54000)
integer, intent(in) :: local_nb_mps
type(MPS_kinematic), intent(in) :: local_mps(:)
type(MPS_kinematic), intent(out) :: ghost_mps(max_ghosts)
integer, intent(out) :: ghost_count
real(RK), intent(in) :: local_xmin, local_xmax, local_zmin, local_zmax, re
integer :: status(MPI_STATUS_SIZE)
integer :: ierr, i, dir, p, num_send, num_recv, count,local_rank, worker_size
integer :: left_rank, right_rank, up_rank, down_rank
integer, parameter :: n_vars = 7,max_send_per_dir = 1800
real(RK) :: send_buf(4,n_vars*max_send_per_dir)
real(RK) :: recv_buf(4,n_vars*max_send_per_dir)
integer, dimension(4) :: send_requests, recv_requests
integer :: send_tag, recv_tag, neighbor_send, neighbor_recv
integer :: num_send_reqs, num_recv_reqs
integer :: recv_counts(4) = 0
integer :: ghost_offset = 0
logical :: is_overflow
if (rank == 0) return
num_send_reqs = 0
num_recv_reqs = 0
ghost_count = 0
call MPI_Comm_rank(worker_comm, local_rank, ierr)
call MPI_Comm_size(worker_comm, worker_size, ierr)
call MPI_Cart_shift(comm3d, 0, 1, left_rank, right_rank, ierr)
call MPI_Cart_shift(comm3d, 2, 1, down_rank, up_rank, ierr)
do dir = 1, 4
select case(dir)
case(1)
send_tag = 0; recv_tag = 0
neighbor_send = right_rank; neighbor_recv = left_rank
case(2)
send_tag = 1; recv_tag = 1
neighbor_send = left_rank; neighbor_recv = right_rank
case(3)
send_tag = 2; recv_tag = 2
neighbor_send = up_rank; neighbor_recv = down_rank
case(4)
send_tag = 3; recv_tag = 3
neighbor_send = down_rank; neighbor_recv = up_rank
end select
if (neighbor_send /= -1) then
num_send = 0
p = 1
select case(dir)
case(1)
do i = 1, local_nb_mps
if (local_mps(global_indices(i))%Pos(1) >= (local_xmax - 2.0_RK*re) .and. &
local_mps(global_indices(i))%Pos(1) < (local_xmax - re)) then
num_send = num_send + 1
if (num_send > max_send_per_dir) then
print *, "ERROR: Send buffer overflow! Dir=", dir, &
", Local_rank=", local_rank, ", Max_cap=", max_send_per_dir
is_overflow = .true.
exit
end if
send_buf(dir, p) = local_mps(global_indices(i))%Pos(1)
send_buf(dir, p+1) = local_mps(global_indices(i))%Pos(2)
send_buf(dir, p+2) = local_mps(global_indices(i))%Pos(3)
send_buf(dir, p+3) = local_mps(global_indices(i))%Vel(1)
send_buf(dir, p+4) = local_mps(global_indices(i))%Vel(2)
send_buf(dir, p+5) = local_mps(global_indices(i))%Vel(3)
send_buf(dir, p+6) = local_mps(global_indices(i))%press
p = p + n_vars
end if
end do
case(2)
do i = 1, local_nb_mps
if (local_mps(global_indices(i))%Pos(1) >= (local_xmin + 1.0_RK*re) .and. &
local_mps(global_indices(i))%Pos(1) < (local_xmin + 2.0_RK*re)) then
num_send = num_send + 1
if (num_send > max_send_per_dir) then
print *, "ERROR: Send buffer overflow! Dir=", dir, &
", Local_rank=", local_rank, ", Max_cap=", max_send_per_dir
is_overflow = .true.
exit
end if
send_buf(dir, p) = local_mps(global_indices(i))%Pos(1)
send_buf(dir, p+1) = local_mps(global_indices(i))%Pos(2)
send_buf(dir, p+2) = local_mps(global_indices(i))%Pos(3)
send_buf(dir, p+3) = local_mps(global_indices(i))%Vel(1)
send_buf(dir, p+4) = local_mps(global_indices(i))%Vel(2)
send_buf(dir, p+5) = local_mps(global_indices(i))%Vel(3)
send_buf(dir, p+6) = local_mps(global_indices(i))%press
p = p + n_vars
end if
end do
case(3)
do i = 1, local_nb_mps
if (local_mps(global_indices(i))%Pos(3) >= (local_zmax - 2.0_RK*re) .and. &
local_mps(global_indices(i))%Pos(3) < (local_zmax - 1.0_RK*re)) then
num_send = num_send + 1
if (num_send > max_send_per_dir) then
print *, "ERROR: Send buffer overflow! Dir=", dir, &
", Local_rank=", local_rank, ", Max_cap=", max_send_per_dir
is_overflow = .true.
exit
end if
send_buf(dir, p) = local_mps(global_indices(i))%Pos(1)
send_buf(dir, p+1) = local_mps(global_indices(i))%Pos(2)
send_buf(dir, p+2) = local_mps(global_indices(i))%Pos(3)
send_buf(dir, p+3) = local_mps(global_indices(i))%Vel(1)
send_buf(dir, p+4) = local_mps(global_indices(i))%Vel(2)
send_buf(dir, p+5) = local_mps(global_indices(i))%Vel(3)
send_buf(dir, p+6) = local_mps(global_indices(i))%press
p = p + n_vars
end if
end do
case(4)
do i = 1, local_nb_mps
if (local_mps(global_indices(i))%Pos(3) >= (local_zmin + 1.0_RK*re) .and. &
local_mps(global_indices(i))%Pos(3) < (local_zmin + 2.0_RK*re)) then
num_send = num_send + 1
if (num_send > max_send_per_dir) then
print *, "ERROR: Send buffer overflow! Dir=", dir, &
", Local_rank=", local_rank, ", Max_cap=", max_send_per_dir
is_overflow = .true.
exit
end if
send_buf(dir, p) = local_mps(global_indices(i))%Pos(1)
send_buf(dir, p+1) = local_mps(global_indices(i))%Pos(2)
send_buf(dir, p+2) = local_mps(global_indices(i))%Pos(3)
send_buf(dir, p+3) = local_mps(global_indices(i))%Vel(1)
send_buf(dir, p+4) = local_mps(global_indices(i))%Vel(2)
send_buf(dir, p+5) = local_mps(global_indices(i))%Vel(3)
send_buf(dir, p+6) = local_mps(global_indices(i))%press
p = p + n_vars
end if
end do
end select
if (num_send > 0) then
num_send_reqs = num_send_reqs + 1
call MPI_Isend(send_buf(dir, 1:num_send*n_vars), &
num_send*n_vars, MPI_DOUBLE_PRECISION, &
neighbor_send, send_tag, comm3d, &
send_requests(num_send_reqs), ierr)
end if
end if
if (neighbor_recv /= -1) then
call MPI_Probe(neighbor_recv, recv_tag, comm3d, status, ierr)
call MPI_Get_count(status, MPI_DOUBLE_PRECISION, count, ierr)
num_recv = count / n_vars
recv_counts(dir) = num_recv
if (num_recv > 0) then
num_recv_reqs = num_recv_reqs + 1
call MPI_Irecv(recv_buf(dir, 1:num_recv*n_vars), &
num_recv*n_vars, MPI_DOUBLE_PRECISION, &
neighbor_recv, recv_tag, comm3d, &
recv_requests(num_recv_reqs), ierr)
end if
else
recv_counts(dir) = 0
end if
end do
if (num_send_reqs > 0) then
call MPI_Waitall(num_send_reqs, send_requests(1:num_send_reqs), MPI_STATUSES_IGNORE, ierr)
end if
if (num_recv_reqs > 0) then
call MPI_Waitall(num_recv_reqs, recv_requests(1:num_recv_reqs), MPI_STATUSES_IGNORE, ierr)
end if
do dir = 1, 4
num_recv = recv_counts(dir)
if (num_recv <= 0) cycle
p = 1
do i = 1, num_recv
ghost_count = ghost_count + 1
ghost_mps(ghost_count)%Pos(1) = recv_buf(dir, p)
ghost_mps(ghost_count)%Pos(2) = recv_buf(dir, p+1)
ghost_mps(ghost_count)%Pos(3) = recv_buf(dir, p+2)
ghost_mps(ghost_count)%Vel(1) = recv_buf(dir, p+3)
ghost_mps(ghost_count)%Vel(2) = recv_buf(dir, p+4)
ghost_mps(ghost_count)%Vel(3) = recv_buf(dir, p+5)
ghost_mps(ghost_count)%press = recv_buf(dir, p+6)
p = p + n_vars
end do
end do
end subroutine exchange_ghost_particles请你查看一下现在存在一些什么问题呢?
最新发布