2014-04-28 79 views
0

我在代碼中分配了很多二維數組,我希望每個數組都從一個名爲數組名的文件中讀取。問題是每個陣列都有不同的大小,所以我正在尋找最有效的方法。代碼是這樣的:fortran循環使用指針的二維數組列表

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 

回答

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 

一些unsollicited評論:我真的不知道爲什麼(在這個例子中)readFile是公開的,爲什麼需要指針?另外,不應使用kind=8Fortran 90 kind parameter)。

+0

我試過你的例子,它的工作原理。答案:指針是我對如何做到這一點的看法,而不是使用指針來完成的。我不知道那種= 8可以產生這些問題。 readFile對於公開並不重要。兩個問題:open(newunit = fd)似乎與f90一起使用,僅僅是f08的一個特性?還有一種方式來循環這個調用readFile(ar1,'ar1'到ar10,'ar10'),但是數組名稱是不同的,所以'ar1'可能'grav','ar2'可能'radius',等等。我可以創建一個數組變量名稱的列表並循環它嗎? – OverStacked

+0

'newunit'是Fortran 2008,但它支持gfortran(自4.5開始,請參閱http://gcc.gnu.org/wiki/Fortran2008Status)。你的意思是「似乎與f90一起工作」?您是否在使用例如'-std = f95'來編譯? – steabert

+0

不,我不使用std = 95的地方。我有一個makefile與intel編譯器編譯,但我的意思是模塊文件命名爲Module1.f90。 – OverStacked

1

如果你的數組ar1,ar2等有相同的尺寸,你可以把它們全部放入一個三維數組中。由於它們具有不同的維度,因此可以使用可分配的數組組件來定義派生類型,將其稱爲「矩陣」,然後創建該派生類型的數組。然後,您可以從文件中讀取第i個矩陣,例如i = 1的「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 
+0

謝謝你的回答。我認爲這是擺脫指針並使用派生類型數組的更好方法,正如您所評論的那樣。但問題是我使用的數組名稱不同。我不想製作一個數組y(nmat),所以y(1)= array1等等。 (array1,...,array10就是一個例子),但是在代碼中,它們具有與分配的數據相對應的不同名稱,並且我希望可讀,以便人們瞭解數據包含哪些內容。 – OverStacked