非连续数据和临时数组创建
non-contiguous data and temporary array creation
中回答了类似的问题。但是,这些解决方案对我的情况并没有多大帮助。
在一个子程序中,我有一个子程序调用:
subroutine initialize_prim(prim)
real(kind=wp), dimension(2, -4:204), intent(out) :: prim
call double_gaussian(prim(1, :))
end subroutine initialize_prim
subroutine double_gaussian(y)
real(kind=wp), dimension(-4:204), intent(out) :: y
integer :: i
do i = -4, 204
y(i) = 0.5 * ( &
exp(-((r(i) - r0))**2) + exp(-((r(i) + r0)/std_dev)**2))
end do
end subroutine double_gaussian
这给出了一条错误消息,指出 Fortran 在 "double_gaussian" 中为 "y" 创建了一个临时数组。阅读了一些有关连续数组的内容后,我明白了为什么会出现此错误。
现在,看看我的整个程序,反转 "prim" 的数组顺序将非常乏味,因此该解决方案实际上是不可能的。
为了在 "double_gaussian" 中创建假定形状,我尝试这样做,
real(kind=wp), dimension(:), intent(out) :: y
integer :: i
do i = -4, 204
y(i) = 0.5 * ( &
exp(-((r(i) - r0))**2) + exp(-((r(i) + r0)/std_dev)**2))
end do
end subroutine double_gaussian
但是,这会导致 Fortran 崩溃并显示错误消息
"Index '-4' of dimension 1 of array 'y' below lower bound of 1"。
似乎对于假定形状格式,索引仍然假定为从 1 开始,而在我的情况下它从 -4 开始。
有办法解决这个问题吗?
我认为您可能将编译器 警告 误解为 错误。通常编译器在创建临时数组时会发出警告 - 这对 high-performance 编程很有帮助。但我不确定编译器是否会将其视为错误。是的,我理解为什么你可能不想 re-order 你的数组只是为了避免
至于崩溃 - 您发现 Fortran 例程不会自动知道您小心设置为 1
以外的数组的下限(也不是它们的上限)。如果有必要,您必须在参数列表中传递边界(通常只有下限,例程可以自己计算出上限)。
但是,它很少是必要的,而且它似乎不在您的代码中 - 设置 y
数组的每个值的循环可以(如果我理解正确的话)替换为
y = 0.5 * (exp(-((r - r0))**2) + exp(-((r + r0)/std_dev)**2))
PS 我认为你问题的这一部分,关于不遵守 other-than-1 数组下界的例程,几乎可以肯定是其他几个人的重复,但我不能马上找到。
subroutine initialize_prim(prim)
real(kind=wp), dimension(2, -4:204), intent(out) :: prim
call double_gaussian(prim(1, :))
end subroutine initialize_prim
subroutine double_gaussian(y)
real(kind=wp), dimension(-4:204), intent(out) :: y
integer :: i
do i = -4, 204
y(i) = 0.5 * ( &
exp(-((r(i) - r0))**2) + exp(-((r(i) + r0)/std_dev)**2))
end do
end subroutine double_gaussian
这给出了一条错误消息,指出 Fortran 在 "double_gaussian" 中为 "y" 创建了一个临时数组。阅读了一些有关连续数组的内容后,我明白了为什么会出现此错误。 现在,看看我的整个程序,反转 "prim" 的数组顺序将非常乏味,因此该解决方案实际上是不可能的。 为了在 "double_gaussian" 中创建假定形状,我尝试这样做,
real(kind=wp), dimension(:), intent(out) :: y
integer :: i
do i = -4, 204
y(i) = 0.5 * ( &
exp(-((r(i) - r0))**2) + exp(-((r(i) + r0)/std_dev)**2))
end do
end subroutine double_gaussian
但是,这会导致 Fortran 崩溃并显示错误消息 "Index '-4' of dimension 1 of array 'y' below lower bound of 1"。 似乎对于假定形状格式,索引仍然假定为从 1 开始,而在我的情况下它从 -4 开始。 有办法解决这个问题吗?
我认为您可能将编译器 警告 误解为 错误。通常编译器在创建临时数组时会发出警告 - 这对 high-performance 编程很有帮助。但我不确定编译器是否会将其视为错误。是的,我理解为什么你可能不想 re-order 你的数组只是为了避免
至于崩溃 - 您发现 Fortran 例程不会自动知道您小心设置为 1
以外的数组的下限(也不是它们的上限)。如果有必要,您必须在参数列表中传递边界(通常只有下限,例程可以自己计算出上限)。
但是,它很少是必要的,而且它似乎不在您的代码中 - 设置 y
数组的每个值的循环可以(如果我理解正确的话)替换为
y = 0.5 * (exp(-((r - r0))**2) + exp(-((r + r0)/std_dev)**2))
PS 我认为你问题的这一部分,关于不遵守 other-than-1 数组下界的例程,几乎可以肯定是其他几个人的重复,但我不能马上找到。