Arrays fortran循环使用指针的2D数组列表
我在代码中分配了很多2D数组,我希望每个数组都从名为array's name的文件中读取。问题是每个数组的大小不同,所以我正在寻找最有效的方法。代码如下所示:Arrays fortran循环使用指针的2D数组列表,arrays,list,pointers,fortran,Arrays,List,Pointers,Fortran,我在代码中分配了很多2D数组,我希望每个数组都从名为array's name的文件中读取。问题是每个数组的大小不同,所以我正在寻找最有效的方法。代码如下所示: Module Test USE ... implicit NONE private public:: initializeTest, readFile real(kind=8),dimension(:,:),allocatable,target:: ar1,ar2,ar3,ar4,ar5,...,ar10 real(kind=8),di
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
如果数组ar1、ar2等具有相同的维度,则可以将它们全部放入三维数组中。由于它们有不同的维度,您可以定义一个派生类型,称之为“矩阵”,并使用可分配的数组组件,然后创建该派生类型的数组。然后,您可以从i=1的“input_1.txt”等文件中读取第i个矩阵。 下面的程序与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
据我所知,在运行时从变量中提取变量名是行不通的
如果您需要大量的数组自动化,请考虑使用一个派生类型的数组,如另一个答案所建议的,以便在分配和读取中循环它们。然后可以枚举文件,或存储具有派生类型的标签
根据特定的数组名称,另一种方法是只读取/写入具有所需名称的文件作为例程的参数: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=8
不应使用()。谢谢您的回答。我认为这是摆脱指针并使用您所评论的派生类型数组的更好方法。但问题是我使用的数组有不同的名称。我不想做一个数组y(nmat),所以y(1)=array1,等等(array1,…,array10是一个例子),但在代码中,它们有不同的名称,对应于分配的数据,我希望可读,以便人们理解数据包括什么。我尝试了你的例子,它是有效的。回答:指针是我对如何做到这一点的看法,并不一定要用指针来完成。我不知道kind=8会产生这些问题。readFile为true,不必公开。两个问题:open(newunit=fd)似乎适用于f90,难道不仅仅是f08的特性吗?还有一种方法可以循环这个调用readFile(ar1,'ar1'到ar10,'ar10'),但是数组的名称是不同的,因此'ar1'可能是'grav','ar2'可能是'radius',等等。。我可以列出数组变量名并循环使用它吗?newunit
是Fortran 2008,但它受例如gfortran的支持(从4.5开始,请参阅)。“似乎与f90配合使用”是什么意思?您是否使用例如-std=f95
来编译?不,我在某个地方没有使用std=95。我有一个makefile要用英特尔编译器编译,但我的意思是模块文件名为Module1.f90。.f90
文件扩展名并不意味着Fortran 90,gfortran和ifort都解释它包含自由格式的源代码,请阅读:好的,我看到了,有用的链接。您知道如何将调用readFile(array1,'array1')从array1循环到array20吗。