2

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
5
  • I am trying to create a linked list for a monte carlo simulation. List var should contain all the information needed for the variables in list. For instance, I want it to contain the number of cells in the simulation ncell, length of a cell(rn), number of cells per dimension (M), and the arrays head of chain (HOC) which contains the pointers to the linked list (ll). I want to create the linked list in subroutine nlist Commented Feb 1, 2014 at 17:04
  • This possibly isn't the best way to go about a linked list, but that's a whole new question. Commented Feb 1, 2014 at 17:08
  • You've tagged as fortran90, but you're not limited to that old standard? Commented Feb 1, 2014 at 17:09
  • My current issue is that all the arrays I mentioned need to be dynamic arrays. So I don't know how to tell the subroutine the size of the arrays in listvar Commented Feb 1, 2014 at 17:10
  • Sorry, I don't follow. Commented Feb 1, 2014 at 17:10

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

8 Comments

Is there no way to do it without a module? How does the subroutine know the size of the dynamic arrays that are members of the class list?
You want to do it with a module. When there is the explicit interface (and the single defined type), it's the job of the compiler to ensure it knows the size of the arrays.
so when I allocate the arrays in my main (sorry still thinking in c++) program, all other subroutines will then know the size of the arrays upon subsequent calling?
Correct. When a type variable is passed around all information about it goes with it (except when it is passed as intent(out)). This includes sizes of components (and lots of other things in more complicated cases).
Awesome! one last question. If subroutine nlist took as an argument a variable of a class type defined in a seperate module, would that be in an issue? In c++, I would just #include the other header file or forward declare the class type, but not sure about here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.