user3225087
user3225087

Reputation: 225

Class structure/dynamic array

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

Answers (1)

francescalus
francescalus

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

Related Questions