Reputation: 2124
I've got a program below which creates an array inside the first subroutine (CALCONE) then I want to pass that into the next subroutine (CALCTWO) then output it to file in the main program. I don't know where to put the INTENT(IN), INTENT(OUT) statements because the array needs to be allocated IN subroutine CALCONE (because in my program the length is determined in CALCONE) - I have left my attempt out to avoid confusion. Could someone help put them in the correct place. Once I have a template, I'll understand how it works for future. Thanks.
I've simplified the program and the variables represent other things which cannot be moved around. I just need a way to move an array between subroutines then write it out at the end of the main program.
program TEST
implicit none
integer a,b,c,d,reclen
a = 1
b = 2
c = 3
d = 4
call CALCONE(a,b,c,d,array)
call CALCTWO(e,f,g,h,array)
inquire(iolength=reclen)array
open(unit=8,file='array_output.dat', &
form="unformatted",access="stream")
write(unit=8)array
close(unit=8)
END PROGRAM TEST
SUBROUTINE CALCONE(adummy,bdummy,cdummy,ddummy,arraydummy)
IMPLICIT NONE
integer i,j,k
integer e,f,g,h,N
!ALLOCATE ARRAY HERE OR IN MAIN PROGRAM?
real*8, allocatable :: arraydummy(:,:)
e = a + 1
f = b + 1
g = c + 1
h = d + 1
! N can only be is calculated here
allocate(arraydummy(1:N,1:3))
!POPULATE 'arraydummy'
!PASS ARRAY BACK OUT TO NEXT SUBROUTINE FOR FURTHER PROCESSING IN CALCTWO
END SUBROUTINE CALCTWO
SUBROUTINE CALCTWO(edummy,fdummy,gdummy,hdummy,arraydummy)
IMPLICIT NONE
integer e,f,g,h
!DEFINE HERE ALSO? i.e.
!real*8, allocatable :: arraydummy(:,:)
e = a + 1
f = b + 1
g = c + 1
h = d + 1
arraydummy = arraydummy*e*f*g*h
END SUBROUTINE CALCTWO
Upvotes: 1
Views: 8517
Reputation: 60008
You do not have to allocate the the array in the main program, but you definitely have to declare it there and you have to pass it as an argument (which you do). Notice, that symbol array
is not defined in the main program.
Be sure to privide en explicit interface to the subs. Because you use advanced features (allocatable dummy arguments) it is necessary. Best is to put them in a module.
The array has to be defined as a dummy argument in both. I declared it as intent(out) in the first one, because it is allocated at the beginning. It is not strictly necessary.
Another option would be to declare the array in the module and let it be shared by the module procedures.
DISCLAIMER: I did not try to compile it.
module subs
integer,parameter :: rp = kind(1d0)
contains
SUBROUTINE CALCONE(adummy,bdummy,cdummy,ddummy,arraydummy)
IMPLICIT NONE
integer i,j,k
integer e,f,g,h,N
!ALLOCATE ARRAY HERE OR IN MAIN PROGRAM?
real(rp), allocatable, intent(out) :: arraydummy(:,:)
e = a + 1
f = b + 1
g = c + 1
h = d + 1
!N can only be is calculated here
allocate(arraydummy(1:N,1:3))
!POPULATE 'arraydummy'
!PASS ARRAY BACK OUT TO NEXT SUBROUTINE FOR FURTHER PROCESSING IN CALCTWO
END SUBROUTINE CALCTWO
SUBROUTINE CALCTWO(edummy,fdummy,gdummy,hdummy,arraydummy)
IMPLICIT NONE
integer e,f,g,h
!DEFINE HERE ALSO? i.e.
real(rp), allocatable, intent(inout) :: arraydummy(:,:)
e = a + 1
f = b + 1
g = c + 1
h = d + 1
arraydummy = arraydummy*e*f*g*h
END SUBROUTINE CALCTWO
end module subs
program TEST
use subs
implicit none
integer a,b,c,d,reclen
real(rp),allocatable :: array
a = 1
b = 2
c = 3
d = 4
call CALCONE(a,b,c,d,array)
call CALCTWO(e,f,g,h,array)
inquire(iolength=reclen)array
open(unit=8,file='array_output.dat', &
form="unformatted",access="stream")
write(unit=8)array
close(unit=8)
END PROGRAM TEST
Upvotes: 6