Fortran:从文件读取中分配内存

时间:2014-03-13 08:34:23

标签: memory-management file-io input fortran subroutine

我尝试从文件中读取大量数据。文件的结构是一致的,但重复的次数不是。输入文件中的第一行表示文件重复的次数。我想分配许多与输入文件重复长度相同的向量。

有没有一种优雅的方法可以解决这个问题,而无需分配每一个变量?我当前的子程序不起作用(我是Fortran新手)。

subroutine geometry(N, Aw, Vp, Vtot,Ds, Spos, DIR)
implicit none

  integer, intent(out) :: N
  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
  real, dimension(:), allocatable, intent(out) :: Spos
  integer, dimension(:), allocatable, intent(out) :: Ns, DIR
  real, dimension(:), allocatable :: Hp
  real, parameter :: pi = 4.0*atan(1.0) 
  real :: Vs, Ds, Ns
  integer :: i

  open(unit = 11, file = "semisub.dat")
  read(11,*) N

  allocate(Aw(N))
  allocate(Vp(N))
  allocate(Vtot(N))
  allocate(Ym(N))
  allocate(Zm(N))
  allocate(Zt(N))
  allocate(Ds(N))
  allocate(Spos(N,4))
  allocate(Ns(N))
  allocate(DIR(N))
  allocate(Hp(N))

  do i = 1,N
     read(11,*) Bp, Hp, Lp, Ym(i), Zm(i), DIR(i)
     read(11,*) Ns(i), Ds(i)
     read(11,*) Spos(i,1:Ns(i))
  end do

Aw(:) = 2 * Ds(:) * Ns(:)   
Vp(:) = 2 * Lp(:) * Bp(:) * Hp(:)   
Vs(:) = 2 * Ns(:) * pi * (Ds/2)**2 * (-Zt(:))


 Vtot(:) = Vp(:) + Vs(:)


end subroutine geometry

错误日志:

geometry.f03:7.54:

  integer, dimension(:),allocatable, intent(out) :: Ns, DIR
                                                      1
Error: Symbol at (1) is not a DUMMY variable
geometry.f03:5.65:

  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
                                                                 1
Error: Symbol at (1) is not a DUMMY variable
geometry.f03:5.69:

  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
                                                                     1
Error: Symbol at (1) is not a DUMMY variable
geometry.f03:5.73:

  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
                                                                         1
Error: Symbol at (1) is not a DUMMY variable
geometry.f03:23.15:

  allocate(Spos(N,4))
               1
Error: Rank mismatch in array reference at (1) (2/1)
geometry.f03:32.20:

     read(11,*) Spos(i,1:Ns(i))
                    1
Error: Rank mismatch in array reference at (1) (2/1)

1 个答案:

答案 0 :(得分:1)

您必须在之前阅读时分配您正在填充的每个阵列。你的方法没问题,有些错误不影响逻辑。

唯一的另一种选择是通过分配使用重新分配:

do...
...
  read(11,*) Ns_tmp, Ds_tmp
  Ns = [Ns, Ns_tmp]
  Ds = [Ds, Ds_tmp]
...
end do...

但如果您知道文件开头的部分数量,我就不会这样做。它更慢,太复杂。


您的错误是,参数列表(N, Aw, Vp, Vtot,Ds, Spos, DIR)

与您的伪参数声明不一致:

  integer, intent(out) :: N
  real, dimension(:), allocatable, intent(out):: Aw, Vp, Vtot, Ym, Zm, Zt, Ds
  real, dimension(:), allocatable, intent(out) :: Spos
  integer, dimension(:), allocatable, intent(out) :: Ns, DIR

只需排除它就可以了。只需在参数列表中添加所有参数,不要将intent用于非参数。

另一个错误是您将Spos声明为on-dimensional,并且您将其用作二维。