I had not tried MOVE_ALLOC() before, but it seems interesting.
Not quite sure how best to use it yet, but it worked with three compilers.
Looks like maybe if I used the original values as a SOURCE= on the allocate it might be better; still playing but I think MOVE_ALLOC() looks appealing …
grid1 after
> [1.000000000,4.000000000,10.00000000,40.00000000,70.00000000 ]
> [2.000000000,5.000000000,20.00000000,50.00000000,80.00000000 ]
> [3.000000000,6.000000000,30.00000000,60.00000000,90.00000000 ]
T F 3 10
grid1 after
> [1.000000000,4.000000000,10.00000000,40.00000000,70.00000000,-1.000000000,-4.000000000,-10.00000000,-40.00000000,-70.00000000 ]
> [2.000000000,5.000000000,20.00000000,50.00000000,80.00000000,-2.000000000,-5.000000000,-20.00000000,-50.00000000,-80.00000000 ]
> [3.000000000,6.000000000,30.00000000,60.00000000,90.00000000,-3.000000000,-6.000000000,-30.00000000,-60.00000000,-90.00000000 ]
program demo_move_alloc ! Example to allocate a bigger GRID
implicit none
real, allocatable :: grid1(:,:)
integer :: i
! initialize small grid
allocate(grid1(3,2))
! fill grids with some values
grid1=reshape([ (real (i), i=1,size(grid1) ) ],shape(grid1))
call showgrid('grid1 before',grid1)
! add a 3x3 array to the right of grid1
call mergegrid(grid1,reshape([10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0],[3,3]))
call showgrid('grid1 after',grid1)
! merge it with a negative copy of itself
call mergegrid(grid1,-grid1)
call showgrid('grid1 after',grid1)
contains
subroutine mergegrid(grida,gridb)
! assuming same number of rows in both
real, allocatable :: grida(:,:), tempgrid(:,:)
real :: gridb(:,:)
integer :: c1, c2, r1, r2
! initialize TEMPGRID which will be used to replace GRIDA
associate( r1=>size(grida,dim=1), r2=>size(gridb,dim=1), &
& c1=>size(grida,dim=2), c2=>size(gridb,dim=2) )
allocate (tempgrid(r1,c1+c2)) ! Allocate bigger grid
tempgrid(:,1:c1)=grida
tempgrid(:,c1+1:c1+c2)=gridb
end associate
! move TEMPGRID to GRIDA
call MOVE_ALLOC (from=tempgrid, to=grida)
! TEMPGRID should no longer be allocated
! and GRID should be the size TEMPGRID was
print *, allocated(grida), allocated(tempgrid),shape(grida)
end subroutine mergegrid
subroutine showgrid(title,arr)
implicit none
character(len=*),parameter::ident= "@(#)showgrid(3f) - print small 2d integer arrays in row-column format"
character(len=*),intent(in) :: title
real,intent(in) :: arr(:,:)
integer :: i
write(*,*)trim(title) ! print title
do i=1,size(arr,dim=1) ! print one row of array at a time
write(*,fmt='(" > [",*(g0.10:,","))',advance='no')arr(i,:)
write(*,'(" ]")')
enddo
end subroutine showgrid
end program demo_move_alloc
PS:
It does work to put the data in as a source and shortens the code a little, but probably creates another temporary so not so sure about a change such as
! initialize TEMPGRID which will be used to replace GRIDA
associate( r1=>size(grida,dim=1), r2=>size(gridb,dim=1), &
& c1=>size(grida,dim=2), c2=>size(gridb,dim=2) )
allocate (tempgrid(r1,c1+c2),source=reshape([grida,gridb],[r1,c1+c2])) ! Allocate bigger grid
end associate