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