我有这个问题,我试图通过使用英特尔MKL子程序集(快速泊松求解器子程序)来求解泊松方程(它只是迭代过程中的三个耦合方程之一)。 现在,重要的是我提到我的整个代码(几千行)是按照以下方式假设基于零的索引编写的:
arbitrary_array(0:N),arbitrary_matrix(0:N,0:M)
其中N和M分别是x和y方向上的网格点。 由于我知道MKL泊松求解器有一个基于索引的,我编写了以下子程序来进行必要的转换:
SUBROUTINE POISSON_SOLVER_MKL(N,M,Phi,Div,Ja,Lx,Ly,dx,dy)
IMPLICIT NONE
!
INTEGER,INTENT(IN)::N,M !Zero-based index count
REAL(DP),INTENT(IN)::Div(0:N,0:M) !This is right-hand side of PE
REAL(DP),INTENT(IN)::Ja,Lx,Ly,dx,dy !BC,X and Y size of the system,unit cell size
REAL(DP),INTENT(OUT)::Phi(0:N,0:M) !This is left-hand side of PE
INTEGER::NX,NY !One-based index count
INTEGER::stat,ipar(128) !MKL parameters
REAL(DP)::ax,bx,ay,by,q
REAL(DP),ALLOCATABLE::dpar(:),f_POISSON(:,:),bd_ax(:),bd_bx(:),bd_ay(:),bd_by(:)
TYPE(DFTI_DESCRIPTOR),POINTER::xhandle
CHARACTER(4)::BCtype
NX=N+1 !This is where indices are shifted
NY=M+1
ALLOCATE(dpar(13*NX/2+7),f_POISSON(NX+1,NY+1),bd_ax(NY+1),bd_bx(NY+1),bd_ay(NX+1),bd_by(NX+1))
!Allocation of the arrays and matrices required for MKL solver
q=0.d0 !Set for Poisson equation
ax=0.d0 !First coordinate in x direction
bx=Lx !Last coordiante in x direction
ay=0.d0
by=Ly
BCtype='NNNN' !Set the Boundary Conditions to be all Neumann
bd_ax=0.d0
bd_bx=0.d0
bd_ay=-Ja
bd_by=Ja
ipar=0
CALL D_INIT_HELMHOLTZ_2D(ax,bx,ay,by,NX,NY,BCtype,q,ipar,dpar,stat)
PRINT*,'STAT=',STAT
f_POISSON(1:NX+1,1:NY+1)=Div(0:N,0:M) !Transferring the variables from zero-based indexing to one-based indexing
CALL D_COMMIT_HELMHOLTZ_2D(f_POISSON,bd_ax,bd_bx,bd_ay,bd_by,xhandle,ipar,dpar,stat)
PRINT*,'STAT=',STAT
CALL D_HELMHOLTZ_2D(f_POISSON,bd_ax,bd_bx,bd_ay,bd_by,xhandle,ipar,dpar,stat)
PRINT*,'STAT=',STAT
Phi(0:N,0:M)=f_POISSON(1:NX+1,1:NY+1) !Returning the variables from one-based indexing to zero-based indexing
CALL FREE_HELMHOLTZ_2D(xhandle,ipar,stat)
PRINT*,'STAT=',STAT
DEALLOCATE(dpar,f_POISSON,bd_ax,bd_bx,bd_ay,bd_by)
END SUBROUTINE POISSON_SOLVER_MKL
不幸的是,这整个代码块都是在没有任何错误的情况下编译的,但是我得到的结果并没有多大意义。 这导致我得出结论,我可能在索引转换和分配中出错,但我根本看不出这个错误在哪里。
有没有人遇到过类似的问题?
答案 0 :(得分:0)
关注this page,NX
和NY
似乎是网格间隔的数量(不是网格点),因此似乎可以接收Div
作为Div( 0:N, 0:M )
虚拟参数中的1}}或Div( N+1, M+1 )
(Phi
相同)并设置Nx = N
和Ny = M
。如果我们使用后者,修改后的代码可能看起来像这样(但尚未测试,所以请尝试使用实际数据):
SUBROUTINE POISSON_SOLVER_MKL(N,M,Phi,Div,Ja,Lx,Ly,dx,dy) !! the same input should be used
IMPLICIT NONE
!
INTEGER,INTENT(IN)::N,M ! Number of mesh intervals (not grid points)
REAL(DP),INTENT(IN)::Div( N+1, M+1 ) !This is right-hand side of PE
REAL(DP),INTENT(IN)::Ja,Lx,Ly,dx,dy !BC,X and Y size of the system,unit cell size
REAL(DP),INTENT(OUT)::Phi( N+1, M+1 ) !This is left-hand side of PE
INTEGER::stat,ipar(128), Nx, Ny !MKL parameters
REAL(DP)::ax,bx,ay,by,q
REAL(DP),ALLOCATABLE::dpar(:),bd_ax(:),bd_bx(:),bd_ay(:),bd_by(:)
TYPE(DFTI_DESCRIPTOR),POINTER::xhandle
CHARACTER(4)::BCtype
Nx = N
Ny = M
!! The grid points now read as x(i) = ax + (i-1) * (bx - ax)/nx
!! for i = 1,2,...,nx+1 (similar for y)
ALLOCATE( dpar(13*Nx/2+7), bd_ax(Ny+1), bd_bx(Ny+1), bd_ay(Nx+1), bd_by(Nx+1) )
q=0.d0 !Set for Poisson equation
ax=0.d0 ! lower bound of x
bx=Lx ! upper bound of x
ay=0.d0 ! lower bound of y
by=Ly ! upper bound of y
BCtype='NNNN' !Set the Boundary Conditions to be all Neumann
bd_ax=0.d0
bd_bx=0.d0
bd_ay=-Ja
bd_by=Ja
ipar=0
CALL D_INIT_HELMHOLTZ_2D ( ax, bx, ay, by, Nx, Ny, BCtype,q,ipar,dpar,stat )
PRINT*,'STAT=',STAT
CALL D_COMMIT_HELMHOLTZ_2D ( Div, bd_ax, bd_bx, bd_ay, bd_by, xhandle,ipar,dpar,stat )
PRINT*,'STAT=',STAT
CALL D_HELMHOLTZ_2D ( Div, bd_ax, bd_bx, bd_ay, bd_by, xhandle,ipar,dpar,stat )
PRINT*,'STAT=',STAT
Phi(:,:) = Div(:,:) !! [Q] Div overwritten with the solution? Plz check the manual...
CALL FREE_HELMHOLTZ_2D(xhandle,ipar,stat)
PRINT*,'STAT=',STAT
END SUBROUTINE POISSON_SOLVER_MKL
请注意,我们不需要修改调用子例程(这里使用的数组可能基于0,如Div(0:N, 0:M)
),而且我们不需要复制{copy-out of { {1}}使用Div
。
我们也可以用基于0的索引编写相同的例程(如问题所示)。在这种情况下,对于i = 0,1,...,nx(类似于y),网格点变为f_poisson
,并且最好将边界数组声明为基于0,例如< / p>
x(i) = ax + i * (bx - ax)/nx