快速泊松求解器(MKL)与Fortran 90

时间:2015-10-06 11:44:34

标签: fortran intel-mkl

我有这个问题,我试图通过使用英特尔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

不幸的是,这整个代码块都是在没有任何错误的情况下编译的,但是我得到的结果并没有多大意义。 这导致我得出结论,我可能在索引转换和分配中出错,但我根本看不出这个错误在哪里。

有没有人遇到过类似的问题?

1 个答案:

答案 0 :(得分:0)

关注this pageNXNY似乎是网格间隔的数量(不是网格点),因此似乎可以接收Div作为Div( 0:N, 0:M )虚拟参数中的1}}或Div( N+1, M+1 )Phi相同)并设置Nx = NNy = 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