I am trying to pass the name of another subroutine_b and an array to a generic subroutine_a. This subroutine_a is supposed to pass the array to subroutine_b and get back its computed value.
Following is the code that I have written:
module pass_subroutine_mod1
implicit none
private
public :: ave_value, fx
contains
subroutine ave_value( func, x, y, ave )
! Calculate average of y which is passed on from another function `func`.
!
external :: func
double precision, intent(in), dimension(:) :: x
double precision, intent(inout), dimension(:) :: y
double precision, intent(inout) :: ave
integer :: n
N = size( x )
call func( x, y )
ave = sum( y ) / dble( N )
return
end subroutine ave_value
subroutine fx( x, y )
double precision, dimension(:), intent(in) :: x
double precision, dimension(:), intent(inout) :: y
y = x ** 3
return
end subroutine fx
end module pass_subroutine_mod1
program main
use :: pass_subroutine_mod1
implicit none
integer :: i, N = 101
double precision :: ave
double precision, allocatable, dimension(:) :: x, y
allocate( x(N), y(N), source=0.0d0 )
do i = 1, N
x(i) = dble( i - 1 )
end do
call ave_value( fx, x, y, ave )
write( *, '(A, ES15.6E3)' ) "Average value of y (from fx) = ", ave
deallocate( x, y )
end program main
Here ave_value()
is the subroutine_a and fx()
is subroutine_b.
When I compile and run the above code, it throws the following error:
At line 28 of file pass_subroutine.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'y' (1/1125899906842625)
Line 28
is the line y = x ** 3
in subroutine fx( x, y )
.
It thus seems that the arrays x
and y
are not properly passed to fx()
because when I try to print x
from within fx()
, it is unable to do so.
If, instead of arrays x
and y
, I use scalars (and update the code accordingly) the code is able to run properly and output the desired result.
Additionally, after going through this thread, if I modify the ave_value
by adding an interface block, the code runs properly again. Following is the modification with ave_value
:
subroutine ave_value( func, x, y, ave )
! Calculate average of y which is passed on from another function `func`.
!
external :: func
double precision, intent(in), dimension(:) :: x
double precision, intent(inout), dimension(:) :: y
double precision, intent(inout) :: ave
integer :: n
interface
subroutine func( ip, op )
double precision, dimension(:), intent(in) :: ip
double precision, dimension(:), intent(inout) :: op
end subroutine func
end interface
N = size( x )
call func( x, y )
ave = sum( y ) / dble( N )
return
end subroutine ave_value
Thus, my questions are:
a) Is the above modification correct?
b) If yes, then why do I need an interface block when working with arrays and not when working with scalars?