我正在使用Fortran 2008和Intel 17 Compiler . 我在子程序中得到一个3D(x,y,z)假设的形状数组,并希望将xy切片作为一维数组传递给另一个将其与矩阵相乘的函数:

SUBROUTINE xy_gyro_average_3d(this,infield,barfield)
    class(xy_GyroAverager_t) :: this
    REAL,DIMENSION(:,:,:), INTENT(IN),contiguous,TARGET :: infield
    REAL,DIMENSION(:,:,:,:,:), INTENT(OUT),contiguous,TARGET :: barfield

    INTEGER :: n,m,k,li0,lj0
    type(Error_t) :: err
    REAL,DIMENSION(:),POINTER :: inptr,outptr

    li0=SIZE(infield,1)
    lj0=SIZE(infield,2)
    DO n=1,this%ln0
        DO m=1,this%lm0
            DO k=1,this%lk0
                inptr(1:li0*lj0) => infield(:,:,k)
                outptr(1:li0*lj0) => barfield(:,:,k,m,n)
                CALL this%gyromatrix(k,m,n)%multiply_with(invec=inptr,&
                    &                                    outvec=outptr,err=err)
                if (err%err) call write_err(err)
            END DO ! k
        END DO ! m
    END DO ! n
END SUBROUTINE xy_gyro_average_3d

multiply_with例程看起来(简化)如下:

SUBROUTINE multiply_with(this,invec,outvec,err)
    CLASS(Matrix_t) :: this
    real, dimension(1:), intent(IN) :: invec
    real, dimension(1:),intent(OUT) :: outvec
    CLASS(Error_t),INTENT(OUT) :: err

    CALL this%multiply_with__do(invec,outvec,err)

END SUBROUTINE multiply_with

我收到关于指针分配的警告,然后是关于不匹配的实际和伪参数类型的错误:

src/GyroAverager.F90(294): warning #8589: Fortran 2008 specifies that if a bound remapping list is specified, data target must be of rank one.   [INFIELD]
            inptr(1:SIZE(infield(:,:,k))) => infield(:,:,k)
----------------------------------------------^
src/GyroAverager.F90(295): warning #8589: Fortran 2008 specifies that if a bound remapping list is specified, data target must be of rank one.   [BARFIELD]
            outptr(1:li0*lj0) => barfield(:,:,k,m,n)
----------------------------------^
src/GyroAverager.F90(297): error #6633: The type of the actual argument differs from the type of the dummy argument.   [INPTR]
            CALL this%gyromatrix(k,m,n)%multiply_with(invec=inptr,&
-------------------------------------------------------------^
src/GyroAverager.F90(298): error #6633: The type of the actual argument differs from the type of the dummy argument.   [OUTPTR]
                &                                    outvec=outptr,err=err)

现在我认为警告不应该是一个问题,只要数组内场和barfield被标记为连续(有没有办法这样做以消除警告消息?) . 错误消息究竟出现了什么问题?指针inptr和outptr与伪参数invec和outvec具有相同的维度 . 但我读到如果你传递一个指针但是没有把它作为指针接收它指向的数组会被传递 . 所以最后它仍然作为2D数组而不是1D传递或者是其他地方的问题?

当multiply_with例程的 Headers 如下所示时,它正在工作:

SUBROUTINE multiply_with(this,invec,outvec,err)
    CLASS(Matrix_t) :: this
    class(*), dimension(1:),intent(IN) :: invec
    class(*), dimension(1:),intent(OUT) :: outvec
    CLASS(Error_t),INTENT(OUT) :: err

然后multiply_with调用的例程稍后将通过选择类型获取类型 . 但我减少了代码,因为我们总是使用真正的数组 .

这样做的正确方法是什么?