The argument of my fortran 95 subroutine is an assumed shape array with intent inout:
the_subroutine(my_argument)
real, dimension(:,:), intent(inout) :: my_argument
(...)
In the main program, I have an allocatable array. I allocate it and also rename indexes. Then I call the subroutine and pass that (correctly allocated) array to the subroutine:
allocate(the_array( 5:1005 , 5:1005 ))
call the_subroutine(my_argument=the_array)
The subroutine does certain calculations and fills the array with values. In the very last line before the end of the subroutine, I check a random value:
(...)
print*, my_argument(213,126) ! I get 2.873...
end subroutine the_subroutine
Then, in the very first line after the subroutine call, I check if the value has been correctly communicated by the subroutine to the outer world, but that is not the case:
call the_subroutine(my_argument=the_array)
print*, the_array(213,126) ! I get 3.798... A completely different value.
The problem arises from having re-indexed the array in the main program as:
allocate(the_array( 5:1005 , 5:1005 ))
where max_index - min_index = 1000-1, but the subroutine "sees" the array internally as if I had declared the normal way, i.e.:
allocate(the_array( 1:1000, 1:1000))
Or simply, allocate(the_array( 1000, 1000 ))
Therefore, the element (213,126) in the internal array is in another location as in the main program array. Is there any easy way out of this?
Finally, I found the solution.
First, if working in Fortran 2003 (or Fortran 95 with non-standard extensions), you may simply declare the assumed shape argument in the subroutine as ALLOCATABLE:
subroutine the_subroutine(my_argument)
real, dimension(:,:), allocatable, intent(inout) :: my_argument
Then the subroutine "sees" the renamed index correctly. However this is not allowed in the Fortran 95 standard.
In Fortran 95, the most elegant way I found for this is by making use of a pointer:
program example
implicit none
real, dimension(:,:), allocatable, target :: the_array
real, dimension(:,:), pointer :: the_pointer
[...]
allocate(the_array(5:1005,5:1005))
the_pointer => the_array
call the_subroutine(my_argument=the_pointer)
And in the subroutine:
subroutine the_subroutine(my_argument)
real, dimension(:,:), pointer :: my_argument
Then it works perfectly. Inside the subroutine, MY_ARGUMENT is treated exactly as if it was an assumed shape array.