2012-06-23 197 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为您的详细评论。我只是给了这个示例程序暗示我的问题不是为了执行。那么,我会尝试这种方法并给你反馈。问候。 –