简体   繁体   中英

Fortran: Array of arbitrary dimension?

If I want to create an allocatable multidimensional array, I can say:

program test
    real, dimension(:,:), allocatable :: x
    integer :: i,j

    allocate(x(5, 5))

    do i = 1,size(x,1)
        do j = 1,size(x,2)
            x(i,j) = i*j
        end do
    end do

    write(*,*) x

end program test

However, what if I don't know how many dimension x will be. Is there a way to accommodate that?

Newer compilers allow the use of assumed-rank objects for interoperability. I think that is what you are looking for. But this is for call to functions or subroutines. The function or subroutine declares the dummy argument as assumed-rank and the actual rank is passed with the actual argument at runtime.

Example from IBM website:

REAL :: a0
REAL :: a1(10)
REAL :: a2(10, 20)
REAL, POINTER :: a3(:,:,:)

CALL sub1(a0)
CALL sub1(a1)
CALL sub1(a2)
CALL sub1(a3)

CONTAINS
    SUBROUTINE sub1(a)
        REAL :: a(..)
        PRINT *, RANK(a)
    END

END

follow this or that for more details

It looks to me like you're trying to carry out stencil computations across an array of rank-1, -2 or -3 -- this isn't quite the same as needing arrays of arbitrary rank. And assumed-rank arrays are really only applicable when passing an array argument to a routine, there's no mechanism even in the forthcoming standard for declaring an array to have a rank determined at run-time.

If you're impatient to get on with your code and your compiler doesn't yet implement TS 29113:2012 perhaps the following approach will appeal to you.

   real, dimension(:,:,:), allocatable :: voltage_field

   if (nd == 1) allocate(voltage_field(nx,1,1))
   if (nd == 2) allocate(voltage_field(nx,ny,1))       
   if (nd == 3) allocate(voltage_field(nx,ny,nz))

Your current approach faces the problem of not knowing, in advance of knowing the number of dimensions in the field, how many nearest-neighbours to consider in the stencil, so you might find yourself writing 3 versions of each stencil update. If you simply abuse a rank-3 array of size nx*1*1 to represent a 1D problem ( mutatis mutandis a 2D problem) you always have 3 sets of nearest-neighbours in each stencil calculation. It's just that in the flattened dimensions the nearest neighbour is, well, either a ghost cell containing a boundary value, or the cell itself if your space wraps round.

Writing your code to work always in 3 dimensions but to make no assumptions about the extent of at least two of them will, I think, be easier than writing rank-sensitive code. But I haven't given the matter a lot of thought and I haven't really thought too much about its impact on your fd scheme.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM