I am wondering how to best handle in Fortran a subroutine that takes an argument of unknown rank. For instance:
Real * 8 :: array1(2,2),array2(2,2,3)
call mysubroutine(array1)
call mysubroutine(array2)
As for now, I always need to fix the shape (number of rank) in the subroutine.
For instance, the intrinsic subroutine random_number(array) can do. (But maybe it is not coded in Fortran?)
You have to write a specific subroutine for each array rank, but you create a generic interface so that you can use a generic call for all the ranks and don't have to figure out the specific one to call. There is example code at how to write wrapper for 'allocate'
In case you need to fill the arrays elementwise and those operations are independent of each other, you may consider alternative to the suggestion of M. S. B. to use an elemental
function. In this case you write the function for a scalar (one element) and it gets automatically applied to all elements of the array irrespective how the shape of the array looks like. However, your scalar function must be satisfy the conditions posed on an elemental
routine, basically meaning that is not allowed to cause any side effects, which would make your result depend on the order it is applied to the individual array elements.
Below a demonstration, which multiplies each element of the array by two:
module testmod
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
elemental subroutine mul2(scalar)
real(dp), intent(inout) :: scalar
scalar = scalar * 2.0_dp
end subroutine mul2
end module testmod
program test
use testmod
implicit none
real(dp) :: a1(5), a2(3,2)
a1 = 1.0_dp
a2 = 2.0_dp
call mul2(a1)
call mul2(a2)
print *, a1
print *, a2
end program test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With