Herman Toothrot
Herman Toothrot

Reputation: 1533

How to create array of arrays from all variables in a module

I have a number of variables declared in a module such as

module test

use othermod, only: n

integer, dimension(n) :: var0
real, dimension(n) :: var1
real, dimension(n) :: var2
..... 
real, dimension(n) :: var1000

end module test

Then I have a subroutine that fills these variables with values. At this point I would like to create an array of arrays with all the variables declared in module test so that I can easily copy or print all variables of a particular (n) at the same time, like dimension(n,allvariablesin module test). For example I would like to do something like array(3,:)=array(2,:). Because this code is part of a very large program I cannot really modify too much, but rather I need to create an array of arrays from all the variables in this module without typing all the variables. How can I easily integrate this change in the current code?

Upvotes: 0

Views: 220

Answers (1)

jlokimlin
jlokimlin

Reputation: 593

I urge you follow to @Vladimir F's advice and encapsulate your variables inside a derived data type. You can employ the associate construct to call old codes expecting var0, var1, .., etc. Lastly, we can overload the type's name to get a Java style constructor in the code below

module type_MyArray

  implicit none
  private

  type, public :: MyArray
     ! type-components
     real, dimension(:), allocatable :: var0, var1, var2
   contains
     ! type-bound procedures
     procedure :: create => create_my_array
     procedure :: destroy => destroy_my_array
  end type MyArray

  interface MyArray
     module procedure my_array_constructor
  end interface MyArray

contains

  pure function my_array_constructor(n) result (return_value)
    ! Dummy arguments
    integer, intent (in) :: n
    type (MyArray)       :: return_value

    call return_value%create(n)

  end function my_array_constructor


  pure subroutine create_my_array(self, n)
    ! Dummy arguments
    class(MyArray), intent(in out) :: self
    integer,        intent(in)     :: n

    allocate( self%var0(n) )
    allocate( self%var1(n) )
    allocate( self%var2(n) )

  end subroutine create_my_array


  pure subroutine destroy_my_array(self)
    ! Dummy arguments
    class(MyArray), intent(in out) :: self

    if (allocated(self%var0)) deallocate( self%var0 )
    if (allocated(self%var1)) deallocate( self%var1 )
    if (allocated(self%var2)) deallocate( self%var2 )

  end subroutine destroy_my_array

end module type_MyArray

program main

  use type_MyArray, only: MyArray
  use old_code,     only: do_something

  implicit none

  type (MyArray) :: foo, bar

  ! Allocate memory
  foo = MyArray(42)
  bar = MyArray(4200)

  associate( var0 => foo%var0, var1 => bar%var1 )

    ! Call old code using var0 and var1
    call do_something(var0, var1)

  end associate

  ! Release memory
  call foo%destroy()
  call bar%destroy()

end program main

Upvotes: 1

Related Questions