Fortran:任意维度的数组?

Fortran: Array of arbitrary dimension?

如果我想创建一个可分配的多维数组,我可以说:

program test
    real, dimension(:,:), allocatable :: x
    integer :: i,j

    allocate(x(5, 5))

    do i = 1,size(x,1)
        do j = 1,size(x,2)
            x(i,j) = i*j
        end do
    end do

    write(*,*) x

end program test

但是,如果我不知道 x 有多少维度怎么办。有办法解决吗?

较新的编译器允许使用假定等级对象来实现互操作性。 我想这就是你要找的。但这是为了调用函数或子程序。函数或子例程将伪参数声明为假定等级,实际等级在运行时与实际参数一起传递。

来自 IBM 网站的示例:

REAL :: a0
REAL :: a1(10)
REAL :: a2(10, 20)
REAL, POINTER :: a3(:,:,:)

CALL sub1(a0)
CALL sub1(a1)
CALL sub1(a2)
CALL sub1(a3)

CONTAINS
    SUBROUTINE sub1(a)
        REAL :: a(..)
        PRINT *, RANK(a)
    END

END

关注this or that了解更多详情

在我看来,您正在尝试对 rank-1、-2 或 -3 的数组执行模板计算——这与需要任意级别的数组并不完全相同。假定秩数组实际上只适用于将数组参数传递给例程时,即使在即将发布的标准中也没有任何机制来声明数组的秩在 运行 时确定。

如果您迫不及待地想继续编写代码并且您的编译器尚未实现 TS 29113:2012,那么以下方法可能会吸引您。

   real, dimension(:,:,:), allocatable :: voltage_field

   if (nd == 1) allocate(voltage_field(nx,1,1))
   if (nd == 2) allocate(voltage_field(nx,ny,1))       
   if (nd == 3) allocate(voltage_field(nx,ny,nz))

您当前的方法面临的问题是,在知道字段中的维数之前,不知道模板中要考虑多少最近邻,因此您可能会发现自己为每个模板更新编写了 3 个版本.如果您简单地滥用大小为 nx*1*1 的 rank-3 数组来表示一维问题(mutatis mutandis 一个二维问题)您在每个模板中总是有 3 组最近邻计算。只是在扁平维度中,最近的邻居要么是包含边界值的幽灵单元格,要么是单元格本身,如果你的 space 环绕。

编写代码以始终在 3 个维度上工作,但不对其中至少两个维度的范围做出任何假设,我认为这比编写对等级敏感的代码更容易。但我没有考虑太多,也没有真正考虑它对你的 f-d 方案的影响。