Fortran子例程调用在模块中的while循环中不起作用

时间:2014-03-21 15:19:35

标签: module fortran subroutine

我正在编写一个Fortran 95程序来生成随机相关曲面。代码在“程序”文件中工作,但我需要将其放在一个模块中。出于某种原因,我使用的排序算法超出范围,如果我把它放在一个模块后我在while循环中调用它。如果我在while循环之外调用它,或者如果我在相同大小的矢量(代码中的xo)上调用它,它将保持在边界内。我试着在我要排序的矢量副本上调用它,但它失败了。我真的不知道为什么,有没有人有想法?

我正在使用gfortran 4.7.3编译器在Ubuntu 13.10中工作

包含变量和while循环的代码:

subroutine generate_skewed_surface(x, system_length, corr_length, alpha)
real(wp), intent(inout), allocatable :: x(:)
real(wp), intent(in) :: system_length, corr_length, alpha

real(wp) :: deltat, deltao
real(wp) :: prefactor, factor
integer :: dim, i
integer, allocatable :: indx(:), indxp(:)
real(wp), allocatable :: omega_k(:), Sxx(:), xo(:), Rp(:)
complex(wp), allocatable :: Xf(:), Rk(:)
logical :: converged

if(.not. allocated(x)) then
   !main should be alerted
   return
end if

[跳过初始化和中间步骤。 x发生的唯一事情是它充满了随机数]

!store a copy
xo = x

!sort original signal
call QsortC(xo) !<- this call works

!create surface by reordering original signal
converged = .false.
do while (.not. converged)
   Rk = cmplx(x, 0._wp, wp)
   call fft(Rk)
   Rp = atan2(real(-imu * Rk, wp), real(Rk, wp))
   Rk = exp(imu*Rp)*abs(Xf)
   call ifft(Rk)
   x = real(Rk, wp)
   indx = (/(i, i=1, dim)/)
   call QsortC(x, indx) !<- this call produces the error during the first call
   do i=1, dim
      x(indx(i)) = xo(i)
   end do
   converged = .true.
   do i=1, dim
      if (indx(i) .ne. indxp(i)) then
         converged = .false.
      end if
   end do
   indxp = indx
end do

排序算法代码(单独的模块文件):

module module_qsort
use SFL_precision, only : DP, SP
implicit none
public :: QsortC
private :: Partition

integer, parameter, private :: wp = DP

contains

recursive subroutine QsortC(A, indices)
  real(wp), intent(in out), dimension(:) :: A
  integer, optional, intent(inout), dimension(:) :: indices
  integer :: iq

  if(size(A) > 1) then
     if (present(indices)) then
        call Partition(A, iq, indices)
        call QsortC(A(:iq-1), indices(:iq-1))
        call QsortC(A(iq:), indices(iq:))
     else
        call Partition(A, iq)
        call QsortC(A(:iq-1))
        call QsortC(A(iq:))
     end if
  endif
end subroutine QsortC

subroutine Partition(A, marker, indices)
  real(wp), intent(in out), dimension(:) :: A
  integer, intent(out) :: marker
  integer, optional, intent(inout), dimension(:) :: indices
  integer :: i, j, tempint
  real(wp) :: temp
  real(wp) :: x      ! pivot point
  x = A(1)
  i= 0
  j= size(A) + 1

  do
     j = j-1
     do
        if (A(j) <= x) exit !<- j goes to zero, giving A(0) below lower bound
        j = j-1
     end do
     i = i+1
     do
        if (A(i) >= x) exit
        i = i+1
     end do
     if (i < j) then
        ! exchange A(i) and A(j)
        temp = A(i)
        A(i) = A(j)
        A(j) = temp
        if (present(indices)) then
           tempint = indices(i)
           indices(i) = indices(j)
           indices(j) = tempint
        end if
     elseif (i == j) then
        marker = i+1
        return
     else
        marker = i
        return
     endif
  end do

end subroutine Partition

end module module_qsort

-fbounds-check标志的具体错误是

At line 51 of file module_quicksort.f90 Fortran runtime error: Index '0' of dimension 1 of array 'a' below lower bound of 1

正如我所提到的,代码在“程序”文件中工作,但在我创建单独的模块文件后却没有。

干杯

1 个答案:

答案 0 :(得分:0)

事实证明我在初始化参数变量时使用了错误的语法,因此将它们设置为0,这反过来意味着我正在排序NaNs的向量。很抱歉打扰了你们一个新手的错误:)