
!-----------------------------------------------------------------
! tree module
module tree
use paramesh_dimensions
private
public :: maxblocks_tr
public :: nchild, nfaces, mchild, mfaces, mdim, mflags
public :: nboundaries, mboundaries
! Block limit to be used in manipulating tree when modifying the grid.
integer, parameter :: maxblocks_tr=4*maxblocks
! Number of children of a node
integer, parameter :: nchild=2**ndim
! Number of faces on a grid block
integer, parameter :: nfaces=2*ndim
! Parameters used to define array sizes
integer, parameter :: mdim=3,mchild=2**mdim,mfaces=2*mdim
! Parameters used to declare the number of block marker flags needed
integer, parameter :: mflags=1 !<<<< USER EDIT
! Parameters used to declare the number of boundary regions where boundary
! conditions are to be applied
integer, parameter :: nboundaries=2*ndim !<<<< USER EDIT
integer, parameter :: mboundaries=2*mdim
public :: neigh,child,which_child
public :: parent,lrefine,lnblocks,new_lnblocks
public :: nodetype,empty,bflags,newchild,derefine,refine
public :: stay,work_block,coord,bsize,bnd_box
public :: grid_xmin,grid_xmax,grid_ymin,grid_ymax
public :: grid_zmin,grid_zmax
public :: lrefine_max,lrefine_min
! Variables for storing tree datastructure
integer, save :: neigh(2,mfaces,maxblocks_tr)
integer, save :: child(2,mchild,maxblocks_tr)
integer, save :: which_child(maxblocks_tr)
integer, save :: parent(2,maxblocks_tr),lrefine(maxblocks_tr)
integer, save :: lnblocks,new_lnblocks
integer, save :: nodetype(maxblocks_tr)
integer, save :: empty(maxblocks_tr),bflags(mflags,maxblocks_tr)
logical, save :: newchild(maxblocks_tr)
logical, save :: derefine(maxblocks_tr),refine(maxblocks_tr)
logical, save :: stay(maxblocks_tr)
real, save :: work_block(maxblocks_tr)
real, save :: coord(mdim,maxblocks_tr)
real, save :: bsize(mdim,maxblocks_tr)
real, save :: bnd_box(2,mdim,maxblocks_tr)
real,save :: grid_xmin,grid_xmax
real,save :: grid_ymin,grid_ymax
real,save :: grid_zmin,grid_zmax
integer, save :: lrefine_max,lrefine_min
! flag to record grid change
public :: grid_changed
integer, save :: grid_changed
! added for surrblks calculation with mpi
public :: boundary_box,boundary_index
real, save :: boundary_box(2,mdim,mboundaries)
integer, save :: boundary_index(mboundaries)
! added for use with mpi block buffering
public :: strt_buffer,last_buffer
public :: strt_buffer_tree,last_buffer_tree
public :: laddress,surr_blks
integer, save :: strt_buffer,last_buffer
integer, save :: strt_buffer_tree,last_buffer_tree
integer, save :: laddress(1:2,1:maxblocks_alloc)
integer, save :: surr_blks(2,3,1+2*k2d,1+2*k3d,maxblocks_alloc)
!--------------------------------------------
!
! A convention is established for numbering the neighbors (or faces
! of a block. The first neighbor is at lower x coordinate, the
! second at higher x, the third at lower y, fourth at higher y, fifth
! at lower z and the sixth at higher z.
!
! The convention by which the children of a block are numbered is the
! same as the fortran array ordering, so that the first child is
! at lower x, y and z coordinate, the second child is at upper x
! but lower y and z, the third is at lower x, upper y and lower z,
! and so on.
!
! When a block has a refined neighbor we will need to know which children
! of this neighbor are to provide guard cell information. The id's of the
! correct children are stored in kchild using the conventions described
! above. For example, if we are working on the 3rd neighbor of the
! current block and it is at finer refinement level, then we must access
! the children designated by kchild(:,3), in this case children 1, 2, 5
! and 6.
!--------------------------------------------
!
!
! Description:
! This is the include file for a quad or oct-tree data structure,
! implemented on a parallel computer.
!
! The tree organizes a set of up to maxblocks_tr grids on each processor.
! All the grids are assumed to be cartesian with a uniform size. Each
! grid has a level of refinement associated with it. The set of level 0
! grids cover the computational domain without overlap. Each grid
! can be the parent of 2**d offspring grids which completely cover
! the sub-domain of their parents, where d is the physical dimension
! of the simulation. The linear resolution varies by a factor of 2
! between successive levels of refinement. At no point do we allow the
! resolution to jump by more than one level of refinement.
!
!
! In the following list the index i ranges from 1 to maxblocks.
!
! neigh(2,mfaces,i) local and processor ids of block i's neighbors,
! at i's refinement level. If a neighbor does
! not exist both values are set to -1, unless
! that face is at an external domain boundary
! where non-periodic boundary conditions are to
! be applied, in which case these are set to -20
! or less, depending on the boundary conditions
! to be applied on the boundary in question.
! child(2,mchild,i) local and processor ids of block i's children
! parent(2,i) local and processor ids of block i's parent
! coord(mdim,i) array storing x,y and z coordinates of the
! center of block i.
! bnd_box(2,mdim,i) bounding box information for block i. The
! lower edge of block i along the j-th coordinate
! axis is at bnd_box(1,j,i) and the upper edge
! at bnd_box(2,j,i).
! bsize(mdim,i) size of block i in the x, y and z directions.
! lrefine(i) refinement level of block i.
! nodetype(i) defines the node type, if 1 then the node is a
! leaf node, if 2 then the node is a parent but
! with at least 1 leaf child, otherwise it is
! set to 3 and it does not have any up-to-date
! data.
! empty(i) used to designate empty blocks, for example
! when an obstacle is inserted inside the
! computational domain. normal blocks have
! empty=0, empty blocks have empty=1.
!
! bflags(mflags,i) an array of integer flags which can be used
! to control computation on the grid blocks
! and which are inherited by children from
! their parents.
!
! which_child(i) an integer identifying which part of the
! parents volume this child corresponds to.
! new_child(i) if true then child has just been produced by
! a refinement step, otherwise false.
! lnblocks number of blocks on the local processor
! new_lnblocks the new number of blocks on the local
! processor after a refinement or derefinement
! step.
! refine(i) refinement flag. If set to .true. block i
! will be refined during the next call to
! REFINE_DEREFINE.
! derefine(i) derefinement flag. If set to .true. block i
! will be derefined during the next call to
! REFINE_DEREFINE, provided this blocks parent
! is not marked for refinement.
! stay(i) indicates block i refinement level unchanged.
! work_block() stores workload weighting associated with block i
!
!
!-----------------------------------------------------------------
end module tree