Reputation: 23
I created a type, model
, in a module, and then declared a variable, md
, having that type. In the subroutine contained in the module, the declaration of md
above is ignored, I have to declare it explicitly again.
In the main program I don't need to declare the type of md
, the use statement appears to work. Can anyone explain why the subroutine ignores the type declaration of md
?
Here is the code. I am using gfortran compiler on Linux.
program main
use struc_model
call mod_gen(md)
do i=1, md%ndof
write(*,*) 'row =', i
write(*,*) 'm=', md%m(i,:)
end do
end
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
type (model) :: md
contains
subroutine mod_gen(md)
! for some reason have to declare type of md again
! declaration above is ignored
type (model) :: md
md%ndof=4
allocate(md%m(md%ndof,md%ndof))
md%m=0.d0
do i=1, md%ndof
md%m(i,i)=1.d0
end do
end subroutine
end module
Upvotes: 2
Views: 208
Reputation: 32451
There are three terms of interest here: use association, host association and argument association. You can read about those in full detail with other resources, but I'll use them here in explanation.
Look first at the module. For the sake of clarity I'm going to take your variables to be of type integer. Here's a simple program
module mod
implicit none
integer i
end module mod
program prog
use mod
implicit none
print *, i ! i is use associated
end program prog
Here, we aren't saying that the type of i
is known from the declaration through the module, we're saying that i
is the variable from the module (and its type follows from that).
Now look at a simplified module:
module mod
implicit none
integer i
contains
subroutine sub(i)
integer i
end subroutine
end module mod
So, why do I need that integer i
declaration in the subroutine sub
? That's because i
in that subroutine, appearing as it does in the argument list, is a dummy argument. A dummy argument needs its type specifying in its scope, the subroutine. Within the subroutine a reference to i
is to the dummy argument and not to the module variable: the module variable is made inaccessible.
If my program then looks like
use mod
call sub(i)
end program
what I'm doing is passing the module variable i
---which has been use associated---to the subroutine sub
as its dummy argument (through argument association).
Now, if I wanted to modify the module variable in the module's subroutine I could instead use host association
module mod
implicit none
integer i
contains
subroutine sub() ! No dummy argument i, references in here are to the module's i
end subroutine
end module mod
program prog
use mod
implicit none
call sub ! No argument for the module's own variable
end program prog
Within that module subroutine i
refers to the module variable.
But what I suspect you mean to do is have a variable in the program's scope which is passed to the subroutine. Going back to your terminology:
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
contains
subroutine mod_gen(md)
type (model) :: md
md%ndof=4
allocate(md%m(md%ndof,md%ndof))
md%m=0.d0
do i=1, md%ndof
md%m(i,i)=1.d0
end do
end subroutine
end module
program main
use struc_model
type (model) :: md ! A variable within the program's scope
call mod_gen(md) ! Argument associated with the subroutine's dummy
do i=1, md%ndof
write(*,*) 'row =', i
write(*,*) 'm=', md%m(i,:)
end do
end
In summary
module struc_model
type model
integer :: ndof
real*8, allocatable, dimension(:,:) :: m
end type
type (model) :: md
end module
declares a module variable md
and doesn't state that all variables called md
are of type(model)
.
Upvotes: 5