module hpfprocessors

integer, parameter :: NPROC=4
!HPF$ PROCESSORS PROC(NPROC)

end module hpfprocessors

module param
real, parameter              :: dr_base = 1.0
integer, parameter           :: rho = 2 ! regridding factor
real, parameter              :: dtbydr = 1.0

integer, parameter           :: gnx=100,gny=100,gnz=1
integer, parameter           :: maxlev=3
integer, parameter           :: mtl=2 !max time levels
integer, parameter           :: mgd=3 !max grids on the same level

type ADAPTIVE_MESH
 integer                        :: grid_id
 integer, dimension(3)          :: nr
 real, dimension(3)             :: rmin
 real, dimension(3)             :: rmax
 integer, dimension(3,2)        :: ibound !3d,min,max =1 -physical boundaries
 type (ADAPTIVE_MESH), pointer  :: parent
 type (ADAPTIVE_MESH), pointer  :: neighbor
 type (ADAPTIVE_MESH), pointer  :: child  
end type ADAPTIVE_MESH

type LEVEL_INFO
 integer                        :: ngd
 real                           :: dr
 real                           :: dt
 type (ADAPTIVE_MESH), pointer  :: grid 
end type LEVEL_INFO

type (LEVEL_INFO), dimension(maxlev) :: lp

end module param

module gridfunctions
use hpfprocessors
use param

!grid functions            

real, dimension(mtl,gnx,gny,gnz),target     :: g1 !base grid
real, dimension(:,:,:,:),allocatable,target :: g21,g22,g23 !3 grids at level 2
real, dimension(:,:,:,:),allocatable,target :: g31,g32,g33 !3 grids at level 3
real, dimension(:,:,:,:),allocatable        :: ctrest


!HPF$ DISTRIBUTE (*,BLOCK,*,*) onto PROC :: g1,g21,g22,g23,g31,g32,g33
!HPF$ DISTRIBUTE ctrest (*,BLOCK,*,*) onto PROC

real, dimension(:,:,:,:), pointer :: p,pp,pc

!!coordinates
real, dimension(maxlev,mgd,3) :: rmin,rmax
!real, dimension(maxlev,gnx) :: coordx
!real, dimension(maxlev,gny) :: coordy
!real, dimension(maxlev,gnz) :: coordz
!!HPF$ ALIGN coordx (*,:) WITH TMPL(:,*)  
!!HPF$ ALIGN coordy (*,:) WITH TMPL(*,:)
!! z coordinate is to be replicated

!regridding
real, dimension(maxlev) :: threshold = (/ 0.08, 0.25, 0.5 /)


end module gridfunctions

program driver
use gridfunctions
   
integer icstep,ncsteps,finlev
real t

REAL time1(2), time2(2)

CALL dtime(time1)
ncsteps=45
!ncsteps=16
t=0
g=0


lp(1)%dr=dr_base
do i=2,maxlev
lp(i)%dr=lp(i-1)%dr/rho
enddo

do i=1,maxlev
 lp(i)%ngd=0
 lp(i)%dt=lp(i)%dr*dtbydr
 nullify(lp(i)%grid)
enddo

call init_base_grid
finlev=1

do icstep=1,ncsteps
write(6,*) 'advance',icstep
call advance(t,finlev,icstep)
enddo

CALL dtime(time2)
PRINT *, 'Time taken = ', time2(1) - time1(1)

stop
end

subroutine init_base_grid
use gridfunctions

type (ADAPTIVE_MESH), pointer  :: basegrid

allocate(basegrid)
basegrid%grid_id=1
basegrid%nr(1)=gnx
basegrid%nr(2)=gny
basegrid%nr(3)=gnz
basegrid%rmin=1.0
basegrid%rmax=basegrid%nr
basegrid%ibound=1
nullify(basegrid%parent)
nullify(basegrid%child)
nullify(basegrid%neighbor)

lp(1)%ngd=1
lp(1)%grid=>basegrid


!coordinates
!rmin(1,1,:)=1
!rmax(1,1,:)=nr(1,:)
!FORALL(i=1:nr(1,1)) coordx(1,i)=real(i)
!FORALL(i=1:nr(1,2)) coordy(1,i)=real(i)
!FORALL(i=1:nr(1,3)) coordz(1,i)=real(i)

!initial values on the grid function
g1(:,:,:,:)=0.0

return
end



