module amr


!-----------------------------------------------------------------------
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!NOTE: here we assume that the grid is 3-dimensional
!      You can use it for 1-d and 2-d grids as well
!      at a cost of a few unnecessary bytes of memory wasted
!-----------------------------------------------------------------------


use types
use amr_param 
use coord_param
use refinement_control

       type LEVEL_INFO
         type(ADAPTIVE_MESH),pointer     :: ml
         type(CLUSTERS),pointer          :: clhead
         real(SP),   dimension(3)        :: ldr
         real(SP)                        :: ldt
         integer(I4B)                    :: lrgint
         integer(I4B)                    :: lsteps
         integer(I4B)                    :: lbwx
         integer(I4B)                    :: lbwy
         integer(I4B)                    :: lbwz
         real(SP)                        :: rcxshp
         real(SP)                        :: rcyshp
         real(SP)                        :: rczshp
         real(SP)                        :: rcrhtm
         integer(I4B)                    :: nclusters
       end type LEVEL_INFO

!    ml    : pointer to first grid on the level
!    ldr   : spatial mesh spacing on the level
!    ldt   : temporal mash spacing on the level 
!    lrgint: regrid every lrgint steps on the level
!    lsteps: total # of time steps taken on this level
!    lbw   : regriding buffer width

!   GLOBAL VARIABLES

type(LEVEL_INFO), dimension(maxlev)     :: lp
integer(I4B)                            :: curlev,finlev


contains

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

       do i=1,maxlev
        nullify(lp(i)%ml)
        nullify(lp(i)%clhead)
        lp(i)%lsteps = 0
        lp(i)%nclusters=0
       enddo

       lp%rcxshp = rcxshp
       lp%rcyshp = rcxshp
       lp%rczshp = rcxshp
       lp%lrgint = rcrgin
       lp%rcrhtm = rcrhtm

       lp(1)%rcxshp = 0
       lp(1)%rcyshp = 0
       lp(1)%rczshp = 0
       lp(1)%rcrhtm = 0

       lp%ldr(1)=0.0
       lp%ldr(2)=0.0
       lp%ldr(3)=0.0
       lp%ldt=0.0
       lp%lbwx=bufwid(1)
       lp%lbwy=bufwid(2)
       lp%lbwz=bufwid(3)

             lp(1)%ldr    = 1.0 ! just security
             lp(1)%ldr(1) = (gxmax-gxmin)/(basenx-1)
if(maxdim>1) lp(1)%ldr(2) = (gymax-gymin)/(baseny-1) ! just in case baseny
if(maxdim>2) lp(1)%ldr(3) = (gzmax-gzmin)/(basenz-1) ! or basenz is 0
             lp(1)%ldt=lp(1)%ldr(1) * dtbydr


       if(maxlev.ge.2) then
          do lev = 2, maxlev
            lp(lev)%ldr(1)=lp(lev-1)%ldr(1)/lp(lev)%rcxshp
            lp(lev)%ldr(2)=lp(lev-1)%ldr(2)/lp(lev)%rcxshp
            lp(lev)%ldr(3)=lp(lev-1)%ldr(3)/lp(lev)%rcxshp
            lp(lev)%ldt=lp(lev-1)%ldt/lp(lev)%rcrhtm
            lp(lev)%lrgint=lp(lev)%lrgint
            lp(lev)%lbwx=lp(lev-1)%lbwx
            lp(lev)%lbwy=lp(lev-1)%lbwy
            lp(lev)%lbwz=lp(lev-1)%lbwz
          enddo
       endif

      return
      end subroutine initialize_level_info

!****************************************************************

      subroutine clear_cluster_structure()
      implicit none

 
      type(CLUSTERS),pointer              :: cls,c 
      integer(I4B)                        :: lev , i

  !    write(6,*) 'curlev=', curlev


       do lev=1,maxlev

  20   continue
       if(.not.associated(lp(lev)%clhead)) cycle

       cls=>lp(lev)%clhead

       do i=1,lp(lev)%nclusters-1
       c=>cls%clnext
       deallocate(cls)
       cls=>c
       enddo  

       deallocate(cls)
       nullify(lp(lev)%clhead)

 !      write(6,*) 'curlev=', curlev

       lp(lev)%nclusters=0
!      write(6,*) 'curlev=', curlev
       enddo


       return
       end subroutine clear_cluster_structure



end module amr














