如果我想创建一个可分配的多维数组,我可以说:
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
按这个或那个查看更多细节
在我看来,您试图在秩为-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
的3级数组来表示1D问题(必要时是2D问题),则在每个模板计算中总是有3组最近邻。只是在平坦的维度中,最近的邻居要么是包含边界值的鬼细胞,要么是你的空间包围的细胞本身。
写你的代码总是在3个维度上工作,但不假设至少两个维度的范围,我认为,比写排名敏感的代码更容易。但我还没有仔细考虑过这件事,也没有真正考虑过它对你的f-d方案的影响。