How to mimic EQUIVALENCE when using Fortran allocatable arrays

175 views Asked by At

I have 3 allocatable 1D arrays in a Fortran routine, VX(:), VY(:), VZ(:), all with the same size.

I need to aggregate them in a 2D array named VARXYZ and send it to a routine that modifies the 'matrix'. The code below works but forces to double the memory size.

      SUBROUTINE TEST(VX,VY,VZ)
      REAL(8), INTENT(INOUT), DIMENSION(:) :: VX,VY,VZ ! They've been allocated with size N in the main
      REAL(8), ALLOCATABLE, DIMENSION(:,:) :: VARXYZ   ! The 'matrix'

      ALLOCATE(VARXYZ(3,N))

      VARXYZ(1,:)=VX(:)
      VARXYZ(2,:)=VY(:)
      VARXYZ(3,:)=VZ(:)
      
      CALL CHANGE_MATRIX(VARXYZ)

      VX(:)=VARXYZ(1,:)
      VY(:)=VARXYZ(2,:)
      VZ(:)=VARXYZ(3,:)
      ...

To avoid the 'double allocation', my first bad reflex was to use an EQUIVALENCE between the 1D arrays and the 3 'columns' of the matrix, but it is not allowed apparently.

After some reading, I have seen people recommending using pointers and the TRANSFER intrinsic function, but I have no idea of how to use them here.

Could you please give an example of how to mimic this EQUIVALENCE mechanism I need?

1

There are 1 answers

0
francescalus On

It is not possible to do exactly what you want, but changes to structures higher up may be possible.

The three input arrays vx, vy and vz are simply contiguous, but there is no expectation that the three arrays together form a (simply) contiguous block of memory. In particular, this means that a storage association mechanism such as using EQUIVALANCE cannot work. (Allocatable objects and dummy arguments are also explicitly prohibited from appearing as equivalence objects, but the previous argument shows the futility of working around this.)

Pointers more widely cannot point to arbitrary blocks of memory.

Finally, transfer is a means of creating a new entity with a transferred physical representation: it's a copy.

You can perhaps work backwards, by ensuring your three arrays are themselves the columns of the larger three-dimensional arrays, but you cannot force this from the procedure test itself. Note, however, that you will need to change test in this case: the allocatable array dummy arguments must correspond to actual array dummy arguments which are allocatable: sections of a larger array never will be. (This example appears not to rely on the allocatable nature of the dummy arguments, however.)