非连续数据和临时数组创建

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 数组下界的例程,几乎可以肯定是其他几个人的重复,但我不能马上找到。