fortran使用指针循环一个2D数组列表

时间:2014-04-28 16:53:46

标签: arrays list pointers fortran

我在我的代码中分配了很多2D数组,我希望每个数组都从一个名为数组名称的文件中读取。问题是每个阵列都有不同的大小,所以我正在寻找最有效的方法。代码是这样的:

Module Test
USE ...
implicit NONE
private
public:: initializeTest, readFile

real(kind=8),dimension(:,:),allocatable,target:: ar1,ar2,ar3,ar4,ar5,...,ar10
real(kind=8),dimension(:,:),pointer:: pAr

CONTAINS
!
subroutine initializeTest
integer:: k1,k2,k3,k4,k5
integer:: ind1,ind2

allocate(ar1(k1,k1),ar2(k1,k2),ar3(k2,k4),ar4(k5,k5),...) !variable sizes

! here needs automatization - since its repeated
pAr => ar1
ind1 = size(pAr,1)
ind2 = size(pAr,2)   
call readFile(par,ind1,ind2)

pAr => ar2
ind1 = size(pAr,1)
ind2 = size(pAr,2)   
call readFile(par,ind1,ind2)

!....ar3, ... , ar9

pAr => ar10
ind1 = size(pAr,1)
ind2 = size(pAr,2)   
call readFile(par,ind1,ind2)

end subroutine initializeTest
!
!

subroutine readFile(ar,row,col)
real(kind=8),dimension(row,col)
integer:: i,j,row,col

! it should open the file with same name as 'ar'
open(unit=111,file='ar.dat')
do i = 1, row
 read(222,*) (ar(i,j),j=1,col) 
enddo
end subroutine importFile
!
!
end module Test

2 个答案:

答案 0 :(得分:1)

如果数组ar1,ar2等具有相同的尺寸,则可以将它们全部放在三维数组中。由于它们具有不同的维度,因此您可以定义派生类型,将其称为“矩阵”,使用可分配的数组组件,然后创建该派生类型的数组。然后,您可以从i = 1的文件中读取第i个矩阵,例如“input_1.txt”。 下面的程序与g95和gfortran一起使用,显示了如何声明和使用派生类型。

module foo
implicit none
type, public :: matrix
   real, allocatable :: xx(:,:)
end type matrix
end module foo

program xfoo
use foo, only: matrix
implicit none
integer, parameter :: nmat = 9
integer            :: i
character (len=20) :: fname
type(matrix) :: y(nmat)
do i=1,nmat
   allocate(y(i)%xx(i,i))
   write (fname,"('input_',i0)") i
   ! in actual code, read data into y(i)%xx from file fname
   y(i)%xx = 0.0
   print*,"read from file ",trim(fname)
end do
end program xfoo

答案 1 :(得分:0)

据我所知,在运行时从变量中提取变量的名称是行不通的。

如果您需要大量的数组自动化,请考虑使用派生类型的数组,正如另一个答案所示,以便为分配和读取循环它们。然后,您可以枚举文件,或使用派生类型存储标签。

坚持使用特定的数组名称,另一种方法是只读取/写入具有所需名称的文件作为例程的参数:

Module Test
...
! here needs automatization - since its repeated 
call readFile(ar1,'ar1')
call readFile(ar2,'ar2')
!....ar3, ... , ar9
call readFile(ar10,'ar10')

end subroutine initializeTest

subroutine readFile(ar,label)
real(kind=8) :: ar(:,:)
character(len=*) :: label
integer:: i,j,nrow,ncol,fd
nrow=size(ar,1)
ncol=size(ar,2)    
open(newunit=fd,file=label)
do i = 1, row
  read(fd,*) (ar(i,j),j=1,col) 
enddo
end subroutine readFile

end module Test

一些未经批评的评论:我不明白为什么(在这个例子中)readFile是公开的,为什么需要指针?此外,不应使用kind=8Fortran 90 kind parameter)。