Filling Multidimensional Arrays

272 views Asked by At

I have created a derived type to access multi-dimensional arrays. With each array I associate a name in the array nm.

My problem consists how to fill the array values once I have allocated the memory.

An initial idea has been to use a multi-dimensional array as input. However I might run into memory problems if I store two copies as the arrays can be big. A better idea might be to pass a one-dimensional array with data along the first dimension and a specification on the position of the second and third dimensions where the data should reside.

I would value some suggestions on possibly better ways to fill arrays to derived types if there are people who have experience working with big data sets.

Type :: Multia

  Character (Len=65) :: nm(3)
  Real, Allocatable :: ma(:,:,:) 
  Real, Allocatable :: mb(:,:,:) 
  Real, Allocatable :: mc(:,:,:) 

  Contains
    Procedure :: set

End Type Multia


Subroutine set (m, nm, u, i, j)

  Class (Multia), Intent (InOut) :: m
  Character (Len=65) :: nm
  Real, Intent (In) :: u(:) 
  Integer, Intent (In) :: i, j

  If (nm .e. (m% nm(1))) Then
    m% ma(:,i,j) = u
  Else If (nm .e. (m% nm(2))) Then
    m% mb(:,i,j) = u
  Else If (nm .e. (m% nm(3))) Then
    m% mc(:,i,j) = u
  End If

End Subroutine set
1

There are 1 answers

3
francescalus On BEST ANSWER

If your concern is about the duplication of arrays such as in

m%ma = [...]  ! Humongous array

then Fortran 2003 offers the move_alloc intrinsic which moves the allocation (including the values) from one variable to another.

Subroutine set (m, u, v, w)
  Class (Multia), Intent (InOut) :: m
  Real, Intent (InOut), allocatable, dimension(:,:,:) :: u, v, w

  call move_alloc(u, m%ma)
  call move_alloc(v, m%mb)
  call move_alloc(w, m%mc)
End Subroutine set

called something like

type(Multia) m
real, dimension(:,:,:), allocatable :: u, v, w
! ... allocating and setting u, v, w
call m%set(u, v, w)
! Components of m now allocated, u, v, w, not allocated

From the notes (in Fortran 2008) of that intrinsic:

It is expected that the implementation of allocatable objects will typically involve descriptors to locate the allocated storage; MOVE ALLOC could then be implemented by transferring the contents of the descriptor for FROM to the descriptor for TO and clearing the descriptor for FROM.

That is, the expectation is that there will be no copying of data or array temporaries.

This assumes, of course, that you can't just allocate the components of m and assign there directly.