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?
The default lower bound for an assumed shape array is one.
If you want a different lower bound, then you need to declare the array dummy argument appropriately.
(The rules for the bounds of the dummy argument are different for deferred shape arrays - array dummy arguments which also have the POINTER or ALLOCATABLE attributes.)
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:
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:
And in the subroutine:
Then it works perfectly. Inside the subroutine, MY_ARGUMENT is treated exactly as if it was an assumed shape array.
use
lbound
to pass the bounds to the subroutine:another approach to the problem: make the array a derived type and the subroutine a method of the type:
as you see now the subroutine automatically knows the correct dimensions. Obviously now the subroutine can only work with the derived type array.