这个问题的背景是一些计算领域,例如计算流体动力学(CFD)。我们经常在一些关键区域需要更精细的网格/网格,而背景网格可以更粗糙。例如,用于跟踪气象学中的冲击波和嵌套域的自适应细化网格。
使用笛卡尔拓扑,域分解如下图所示。在这种情况下,使用4*2=8个处理器。单个数字表示处理器的等级,(x,y) 表示其拓扑坐标。

假设网格在等级2、3、4、5(中间)的区域中被细化,并且在这种情况下局部细化比率被定义为R=D_coarse/D_fine=2。由于网格已细化,因此时间推进也应细化。这需要在细化区域中计算时间步长 t、t+1/2*dt、t+dt,而在全局区域中仅计算时间步长 t 和 t+dt。这需要一个更小的通信器,它只包括中间的等级以进行额外的计算。全局排名+坐标和相应的局部排名(红色)草图如下所示:
然而,我在实现这个方案时遇到了一些错误,并显示了 Fortran 中的代码片段(不完整):
integer :: global_comm, local_comm ! global and local communicators
integer :: global_rank, local_rank !
integer :: global_grp, local_grp ! global and local groups
integer :: ranks(4) ! ranks in the refined region
integer :: dim ! dimension
integer :: left(-2:2), right(-2:2) ! ranks of neighbouring processors in 2 directions
ranks=[2,3,4,5]
!---- Make global communicator and their topological relationship
call mpi_init(ierr)
call mpi_cart_create(MPI_COMM_WORLD, 2, [4,2], [.false., .false.], .true., global_comm, ierr) …Run Code Online (Sandbox Code Playgroud) program main
use omp_lib
implicit none
integer :: n=8
integer :: i, j, myid, a(8, 8), b, c(8)
! Generate a 8*8 array A
!$omp parallel default(none), private(i, myid), &
!$omp shared(a, n)
myid = omp_get_thread_num()+1
do i = 1, n
a(i, myid) = i*myid
end do
!$omp end parallel
! Array A
print*, 'Array A is'
do i = 1, n
print*, a(:, i)
end do
! Sum of array A
b = 0
!$omp parallel reduction(+:b), shared(a, n), …Run Code Online (Sandbox Code Playgroud)