Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

joining arrays

Status
Not open for further replies.

augh

Programmer
Dec 21, 2008
5
IT
Here is a problem that I would manage easily in fortran 77 but it seems to be more tricky in 90 (but probably i'm wrong):

suppose to have NV arrays of the same shape and dimensions, say (nx,ny,nz). I would like to have a unique array with 4 dims, one indicating the variable to address.

In 77 this would be easily managed using common

program unit 1:
real(nx,ny,nz) a,b,c
common/qaz/a,b,c

program unit 2: (nv==3)
real(nv,nx,ny,nz) v
common/qaz/c

This defines the relationships
v(1,i,j,k)=a(i,j,k)
v(2,i,j,k)=b(i,j,k)
v(3,i,j,k)=c(i,j,k)

Is there any way to do int in 90 without the use of common?
 
progunit c

module commonMod
real c(3,nx,ny,nz)
end module

progunit 1
use commonMod
..do whatever with c

progunit 2
use commonMod
..do whatever with c
 
I'm sure I haven't explaiend my problem clearly.

vars qaz,zaq,zot are defined in a module and they are there with
different names and this situation cannot be changed (part of the
program is maintained by another group that does not loke to chenge
their coding "standards")

module qq
integer, parameter :: nx=, ny
real, dimension(nx,ny) :: qaz, zaq, zot
end module qq

I write a routine that at a given point need to call a function that
accept a variable defined like this
var(1,:,:)=qaz:),:)
var(2,:,:)=zaq:),:)
var(3,:,:)=zot:),:)

stat=myfunction(var)

each time I call this function I need to allocate memory that in fact is
already allocated and assigned values. To avoid this in f77 using common
blocks I would define a named common block in the main program
common/qwerty/qaz,zaq,zot
and then I would use the same common in my routine (the one calls
myfunction) to point to the same "contiguous" location but using a
single variable name with an additional index"
common/qwerty/var

I hope my problem is more clear now.
Alberto

 
Use equivalence
Code:
equvalence(var(1,1,1,1),qaz(1,1,1))
That is all you need - the rest should fall into place. You could have done that in g77 too.
 
Dynamic equivalence in F90+:
Code:
program updim
real, dimension(2,2), target:: a, b;

type p2d
real, pointer:: p(:,:)
end type p2d

type(p2d)::p3d(2)

p3d(1)%p => a
p3d(2)%p => b

p3d(1)%p(1,1) = 1
p3d(2)%p(1,1) = 2

print *,a(1,1),b(1,1)
end
Now you have 3d array surrogate and it's possible to handle it as a true 3d array with slightly exotic accessors syntax...
 

Thank you everybody for stimulating suggestions.

I managed to do what I wanted to do in a different way that I would like
to submit to your experienced opinions for improvement.

Here is the code tested with gfortran, g95 and ifort. Any suggestion
and/or criticism is welcome.

Code:
module external_var_definition

  implicit none

  ! suppose this module is part of a code I cannot do major changes in
  ! it. Basically, I can only add few lines enclosed in some compiler
  ! directive #ifdef ... #endif
  integer, parameter :: nx=2, ny=2
  real, dimension(nx,ny) :: qaz, zaq

#ifdef mystruct
  ! I define here the additional code to link the set of variables
  ! defined by this module to a container variable.
  integer, parameter :: nv=2 ! number of packed variables
  common/container/qaz,zaq ! variable packaging
#endif

end module external_var_definition




program myprogram

! I do not need to know anything of container variable here
  use external_var_definition, only: nx, ny, qaz, zaq

  implicit none

  integer :: i, j, k

  ! init
  qaz(:,1)=(/1,2/)
  qaz(:,2)=(/3,4/)

  zaq=2*qaz

  print*,'variable qaz'
  do j=1,ny
    print*,(qaz(i,j),i=1,nx)
  end do
  print*

  print*,'variable zaq'
  do j=1,ny
    print*,(zaq(i,j),i=1,nx)
  end do
  print*


  call write_packed_vars

end program myprogram




subroutine write_packed_vars

  ! here I need to pack the variables defined in external_var_definition
  ! in one array with higher diimension
  use external_var_definition, only: nx, ny, nv

  implicit none

  ! the only thing I need to know here is the name of the common in the
  ! module, the variable shape and the number of packed vars
  real, dimension(nx,ny,nv) :: packed_vars
  common/container/packed_vars

  integer :: i, j, k

  do k=1,nv
  print*,'variable ',k
    do j=1,ny
      print*,(packed_vars(i,j,k),i=1,nx)
    end do
    print*
  end do

end subroutine write_packed_vars
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top