2012-06-23 128 views
0

我想對多塊CFD代碼使用動態分配,其中索引(i,j,k)針對不同的塊而變化。我真的不知道,如何爲n個塊分配任意數組索引並將其傳遞給子例程。我給出了一個示例代碼,該代碼在使用gfortran進行編譯時給出錯誤消息「錯誤:(1)處的表達式必須是標量」。多維動態數組分配

common/iteration/nb 
    integer, dimension (:),allocatable::nib,njb,nkb 
    real, dimension (:,:,:,:),allocatable::x,y,z 
    allocate (nib(nb),njb(nb),nkb(nb)) 
    do l=1,nb 
    ni=nib(l) 
    nj=njb(l) 
    nk=nkb(l) 
    allocate (x(l,ni,nj,nk),y(l,ni,nj,nk),z(l,ni,nj,nk)) 
    enddo 
    call gridatt (x,y,z,nib,njb,nkb) 
    deallocate(x,y,z,nib,njb,nkb) 
    end 

    subroutine gridatt (x,y,z,nib,njb,nkb) 
    common/iteration/nb 
    integer, dimension (nb)::nib,njb,nkb 
    real, dimension (nb,nib,njb,nkb)::x,y,z 
    do l=1,nb 
    read(7,*)nib(l),njb(l),nkb(l) 
    read(7,*)(((x(l,i,j,k),i=1,nib(l)),j=1,njb(l)),k=1,nkb(l)), 
$ (((y(l,i,j,k),i=1,nib(l)),j=1,njb(l)),k=1,nkb(l)), 
$ (((z(l,i,j,k),i=1,nib(l)),j=1,njb(l)),k=1,nkb(l)) 
    enddo 
    return 
    end 
+0

請問你能告訴我們究竟是什麼'(1)'表達式是? –

+0

錯誤消息是在分配語句x,y,z和維度(nb,nib,njb,nkb)的筆尖 –

回答

3

gfortran給出的錯誤信息是一樣好。它指向nib在行

real, dimension (nb,nib,njb,nkb)::x,y,z 

nib被聲明爲一個數組。這是不允許的。 (會的xy,並且z大小是什麼在這個維度?)

從這個

除此之外,我真的不明白你的是什麼,你正在嘗試做的說明和示例代碼你表演對我來說沒有多大意義。

common/iteration/nb 
integer, dimension (:),allocatable::nib,njb,nkb 
real, dimension (:,:,:,:),allocatable::x,y,z 
allocate (nib(nb),njb(nb),nkb(nb)) 

在編寫新代碼時,使用模塊在程序單元之間進行通信非常受歡迎。舊式的公共塊應避免。

您正在嘗試分配nib,njbnkb,大小爲nb。問題是nb還沒有被賦予一個值(並且不會在代碼中的任何地方給出)。

do l=1,nb 
ni=nib(l) 
nj=njb(l) 
nk=nkb(l) 
allocate (x(l,ni,nj,nk),y(l,ni,nj,nk),z(l,ni,nj,nk)) 
enddo 

再次,nb的問題沒有價值。此循環運行未知次數。您還正在使用數組nib,njbnkb,它們尚未包含任何值。

在循環的每次迭代中,x,yz被分配。這將導致第二次迭代中的運行時錯誤,因爲您無法分配已分配的變量。即使分配能夠工作,這個循環也是無用的,因爲這三個數組在每次迭代中都會被重置,並最終被設置爲最後一次分配的維數。

現在我正在寫這篇文章,我開始認爲你所要做的是創建所謂的「鋸齒狀數組」:你想在x(1,:,:,:)中創建一個大小不同的塊在x(2,:,:,:)的塊中的第二,第三和/或第四維中,等等。這在fortran中根本不可能。

實現此目的的一種方法是創建具有可分配三維數組組件的用戶定義類型,並創建此類型的數組。然後可以爲用戶定義類型的數組的每個元素分配數組組件的所需大小。 這看起來像下面這樣(免責聲明:未經測試,只是實現目標的一種可能方式)。

type :: blocktype 
    real, dimension(:, :, :), allocatable :: x, y, z 
end type blocktype 

type(blocktype), dimension(nb) :: myblocks 

然後可以運行一個循環分配xyz到不同大小的每個數組元素。這是假設nb已被設置爲所需值,並且nib,njbnkb包含不同塊的期望大小。

do block = 1, nb 
    ni = nib(block) 
    nj = njb(block) 
    nk = nkb(block) 
    allocate(myblocks(block)%x(ni, nj, nk)) 
    allocate(myblocks(block)%y(ni, nj, nk)) 
    allocate(myblocks(block)%z(ni, nj, nk)) 
enddo 

如果你想這樣做,這樣,你肯定會想要把模塊的程序,因爲這樣你自動獲得明確的接口,都需要通過用戶定義的類型,例如數組進行。

一個事後:不要使用隱式類型,即使在示例代碼中。始終使用implicit none

+0

Thankyou爲您的詳細評論。我只是給了這個示例程序暗示我的問題不是爲了執行。那麼,我會嘗試這種方法並給你反饋。問候。 –