























































































































 


































































































































































 
































































































































































































































 




















































































 










 








































































































































































































































 










                                
                                

                                
                                

                                
                                

                                





































subroutine splitregions_recursively ( &
     cxx_superregs, nsuperregs, &
     cxx_regs, &
     nprocs, &
     ghostsize_, alpha_, limit_size_, &
     procid_)
  use carpet_boxtypes
  implicit none
  
  integer,      intent(in) :: nsuperregs
  integer*8, intent(in) :: cxx_superregs
  integer*8, intent(in) :: cxx_regs
  integer,      intent(in) :: nprocs
  integer,      intent(in) :: ghostsize_
  REAL*8,    intent(in) :: alpha_
  integer,      intent(in) :: limit_size_
  integer,      intent(in) :: procid_
  
  type(ptr), allocatable :: sregions(:)
  type(boundary)         :: outbound
  
  integer*8 :: cxx_superreg
  integer*8 :: cxx_tree
  type(bbox)   :: box
  integer      :: i
  
  
  
  
  interface
     
     subroutine carpet_get_region (cxx_superregs, i, cxx_superreg)
       use carpet_boxtypes
       implicit none
       integer*8, intent(in)  :: cxx_superregs
       integer,      intent(in)  :: i
       integer*8, intent(out) :: cxx_superreg
     end subroutine carpet_get_region
     
     subroutine carpet_get_bbox (cxx_superreg, box, obound)
       use carpet_boxtypes
       implicit none
       integer*8,   intent(in)  :: cxx_superreg
       type(bbox),     intent(out) :: box
       type(boundary), intent(out) :: obound
     end subroutine carpet_get_bbox
     
     subroutine carpet_insert_region (cxx_regs, reg)
       use carpet_boxtypes
       implicit none
       integer*8,           intent(in) :: cxx_regs
       type(superregion2slim), intent(in) :: reg
     end subroutine carpet_insert_region
     
     subroutine carpet_create_tree_branch &
          (nch, dir, bounds, cxx_subtrees, cxx_tree)
       use carpet_boxtypes
       implicit none
       integer,      intent(in) :: nch
       integer,      intent(in) :: dir
       integer,      intent(in) :: bounds(nch+1)
       integer*8, intent(in) :: cxx_subtrees(nch)
       integer*8, intent(in) :: cxx_tree
     end subroutine carpet_create_tree_branch
     
     subroutine carpet_create_tree_leaf (sreg, cxx_tree)
       use carpet_boxtypes
       implicit none
       type(superregion2slim), intent(in)  :: sreg
       integer*8,           intent(out) :: cxx_tree
     end subroutine carpet_create_tree_leaf
     
  end interface
  
  
  
  
  ghostsize  = ghostsize_
  alpha      = alpha_
  limit_size = limit_size_ /= 0
  procid     = procid_
  
  
  
  allocate (sregions(nsuperregs))
  do i=1, nsuperregs
     call carpet_get_region (cxx_superregs, i-1, cxx_superreg)
     call carpet_get_bbox (cxx_superreg, box, outbound)
     call create_sregion (box, outbound, i-1, sregions(i)%point)
  end do
  
  call SplitSuperRegions (sregions, nprocs)
  
  do i=1, nsuperregs
     call carpet_get_region (cxx_superregs, i-1, cxx_superreg)
     call insert_region (sregions(i)%point, cxx_tree, cxx_regs)
     call carpet_set_tree (cxx_superreg, cxx_tree)
  end do
  
  do i=1, nsuperregs
     call destroy_sregion (sregions(i)%point)
  end do
  deallocate (sregions)
  
contains
  
  recursive subroutine insert_region (sreg, cxx_tree, cxx_regs)


    type(superregion2), pointer  :: sreg
    integer*8,                intent(in)  :: cxx_regs
    integer*8,                intent(out) :: cxx_tree
    
    integer                   :: nch, ich
    integer                   :: dir
    integer                   :: mydir
    integer,      allocatable :: bounds(:)
    integer*8, allocatable :: cxx_subtrees(:)
    type(superregion2slim)    :: sregslim
    
    
    
    if (associated(sreg%children)) then
       
       nch = size(sreg%children)
       allocate (bounds(nch+1))
       allocate (cxx_subtrees(nch))
       if (nch /= 2) then
          call CCTK_Warn(0,131,"splitregions_recursively.F90","Carpet", "number of children is not 2")
       end if
       mydir = -1
       do dir=1, 3
          if (sreg%children(1)%point%extent%dim(dir)%upper + &
               sreg%children(2)%point%extent%dim(dir)%stride == &
               sreg%children(2)%point%extent%dim(dir)%lower) then
             
             if (mydir > 0) then
                call CCTK_Warn(0,140,"splitregions_recursively.F90","Carpet", "could not determine direction")
             end if
             mydir = dir
          else
             if (sreg%children(1)%point%extent%dim(dir)%lower /= &
                  sreg%children(2)%point%extent%dim(dir)%lower .or. &
                  sreg%children(1)%point%extent%dim(dir)%upper /= &
                  sreg%children(2)%point%extent%dim(dir)%upper) then
                call CCTK_Warn(0,148,"splitregions_recursively.F90","Carpet", "children differ in unexpected ways")
             end if
          end if
       end do
       if (mydir < 0) then
          call CCTK_Warn(0,153,"splitregions_recursively.F90","Carpet", "could not determine direction")
       end if
       bounds(1) = sreg%children(1)%point%extent%dim(mydir)%lower
       bounds(2) = sreg%children(2)%point%extent%dim(mydir)%lower
       bounds(3) = sreg%children(2)%point%extent%dim(mydir)%upper + &
            sreg%children(2)%point%extent%dim(mydir)%stride
       do ich=1, nch
          call insert_region &
               (sreg%children(ich)%point, cxx_subtrees(ich), cxx_regs)
       end do
       call carpet_create_tree_branch &
            (nch, mydir-1, bounds, cxx_subtrees, cxx_tree)
    else
       
       sregslim%extent           = sreg%extent
       sregslim%outer_boundaries = sreg%outer_boundaries
       sregslim%map              = sreg%map
       sregslim%processor        = sreg%processor
       call carpet_create_tree_leaf (sregslim, cxx_tree)
       call carpet_insert_region (cxx_regs, sregslim)
    end if
  end subroutine insert_region
  
end subroutine splitregions_recursively
