Reputation: 771
I've been working on some code lately that requires me to shift elements in an array left, right, up, and down (depending on an index i
). My first thought was to try something like this:
subroutine shift(f)
real, intent(inout) :: f(0:8, rDim, cDim)
real :: periodicHor(rDim)
periodicHor(:) = f(1,:,cDim)
f(1,:,2:cDim) = f(1,:,1:cDim - 1)
f(1,:,1) = periodicHor(:)
!and so on for directions 2:8
end subroutine
However, when I lay it out this way, column 1 gets copied into column 2, which gets copied into column 3 which gets copied into... It's not a shift of the data so much as the first column overwriting everything to the left.
If I flip the indices, though,
subroutine betterShift(f)
real, intent(inout) :: f(rDim, cDim, 0:8)
real :: periodicHor(rDim)
periodicHor(:) = f(:,cDim,1)
f(:,2:cDim,1) = f(:,1:cDim - 1,1)
f(:,1,1) = periodicHor(:)
end subroutine
things work fine, shifting left or right. I suspect the compiler detects an in-place update of continuous memory in the 2nd case, so it makes a temporary copy "under the hood" to avoid the overwrite issue, but that's just speculation on my part. Can anyone give a more detailed explanation as to why the shift works one way and not the other?
Upvotes: 0
Views: 176