I am trying to write a program where I want the allocatable array A to be of either rank 1, 2, or 3, depending on my input at run-time. I want to do this since the subsequent operations on A are similar, and I have defined in a module an interface work with module procedures that when acted on A, gives the desired result.
What I am doing currently is this:
program main
implicit none
integer :: rank,n=10
real*8, allocatable :: A1(:)
real*8, allocatable :: A2(:,:)
read (*,*) rank
if (rank.eq.1) then
allocate (A1(n))
else if (rank.eq.2) then
allocate (A2(n,n))
end if
! operate on the array
if (rank.eq.1) then
call work(A1)
else if (rank.eq.2) then
call work(A2)
end if
end program
Things would be much easier if somehow I could choose the rank of A, as then the if statements are not needed. Maybe this is not possible, but all help are appreciated.
Declare the array to be rank three. If a lower rank array is required, allocate the relevant trailing dimensions to be of size one.
real, allocatable :: array(:,:,:)
...
select case (desired_rank)
case (1) ; allocate(array(n,1,1))
case (2) ; allocate(array(n,n,1))
case (3) ; allocate(array(n,n,n))
case default ; error stop 'bad desired rank'
end select
You can then use an array section to get a contiguous slice of array that is consistent with your desired rank. Alternatively, write the relevant procedures that operate on array to take a rank three argument, and make them aware of the meaning of a size one extent for the higher dimensions.
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