Reputation: 225
I just recently switched from C++ over to Fortran. As you would probably guess, I am having some syntax growing pains.
What I am trying to accomplish is define a class with dynamic arrays. I then need to pass a class variable to a subroutine, but I can't figure out how to declare (is that the right word here? I am still thinking in C++), the arrays in the subroutine.
Here are the portions of my code that are applicable.
program lennard
implicit none
type list
integer :: M,ncell !! m is number of cells per dimension. ncell is the total number of cells
double precision :: rn !! length per dimension of cell
double precision, allocatable :: HOC(:), ll(:),nlist(:)
double precision, allocatable :: verlet(:,:)
end type list
type(list) :: listvar
double precision, allocatable :: x(:), y(:), z(:)
integer :: N
allocate (x(np),y(np),z(np))
listvar%rn = box/int(box/rcut)
listvar%ncell = vol/(listvar%rn**3)
listvar%M = listvar%ncell**(1.0/3.0)
allocate (listvar%HOC(listvar%ncell), listvar%ll(np), listvar%nlist(np))
allocate (listvar%verlet(np,np))
stop
end program lennard
and here is the subroutine
subroutine nlist(np,x,y,z,listvar)
implicit none
type list
integer :: M,ncell !! m is number of cells per dimension. ncell is the total number of cells
double precision :: rn !! length per dimension of cell
double precision :: HOC(:), ll(:),nlist(:)
double precision :: verlet(:,:)
end type list
integer :: i
integer :: icel, M,ncell
integer :: np
type(list) :: listvar
double precision :: x(np),y(np),z(np)
double precision,allocatable :: listvar%ll(np),x(np),y(np),z(np)
double precision,allocatable :: listvar%HOC(listvar%ncell)
do i=1,ncell
listvar%hoc(i)=0.0
enddo
do i=1,np
icel = int(x(i)/listvar%rn)+M*int(y(i)/listvar%rn)+M*M*int(z(i)/listvar%rn)
listvar%ll(i) = listvar%hoc(icel)
listvar%hoc(icel) = i
enddo
return
end subroutine nlist
Upvotes: 2
Views: 389
Reputation: 32461
Before coming to answer what I think is your question, I'll note something. The type list
in the subroutine and the type list
in the program are not the same thing, even though they have the same name and components. Instead, you'll want just one type definition. As subroutine nlist
is not internal to the program you do this with a module, which you then use
in your program.
Further, you may want to put the subroutine nlist
also in this module (after a contains
) as this is an easy way to make an explicit interface for it available to the program. If you don't have nlist
in the module then you'll need to use
the module there, too.
With that out of the way
double precision,allocatable :: listvar%ll(np),x(np),y(np),z(np)
double precision,allocatable :: listvar%HOC(listvar%ncell)
makes no sense. You don't need to declare the components once you have the type definition. Indeed, it's erroneous to and the allocatable
attribute has to be given in the type definition, just like you had in the program. In addition, you've already declared x
, y
and z
in previous lines. [Note also that unless you are doing things with the allocation status of these variables they needn't be declared with the allocatable
attribute.]
You have a module, then, like:
module listmod
implicit none
type list
integer :: M,ncell
double precision :: rn !! length per dimension of cell
double precision, allocatable :: HOC(:), ll(:),nlist(:)
double precision, allocatable :: verlet(:,:)
end type list
contains
subroutine nlist(np,x,y,z,listvar)
! Declarations for np, x, y, z
type(list), intent(inout) :: listvar ! A sensible assumption of intent
! Declaration of local variables
! Work
end subroutine
end module
Upvotes: 1