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
在我看来,您正在尝试对 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 方案的影响。
如果我想创建一个可分配的多维数组,我可以说:
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
在我看来,您正在尝试对 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 方案的影响。