7 integer :: ig^D, level, igrid, ipe
8 integer :: iside, i^D, Morton_no, isfc
10 integer,
external :: getnode
36 {
do ig^db=1,
ng^db(1)\}
38 i^dd=
kr(^dd,^d)*(2*iside-3);
45 call amr_morton_order()
54 integer,
intent(in) :: ig^D, level, igrid, ipe
55 logical,
intent(in) :: active
66 tree%node%active=active
68 nullify(tree%node%parent%node)
70 nullify(tree%node%child(ic^d)%node)
76 nullify({tree%node%neighbor(1,^d)%node},{tree%node%neighbor(2,^d)%node})
78 igrid_to_node(igrid,ipe)%node => tree%node
86 integer,
intent(in) :: igrid, ipe
87 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
88 logical,
intent(out) :: active
91 integer :: level, ic^D, child_level, iside, iotherside, vote
94 tree%node =>
igrid_to_node(child_igrid(1^d&),child_ipe(1^d&))%node%parent%node
103 child%node => tree%node%child(ic^d)%node
106 if(child%node%active) vote=vote+1
112 child_neighbor%node => child%node%neighbor(iside,^d)%node
113 if (
associated(child_neighbor%node))
then
114 if (child%node%ig^d==child_neighbor%node%ig^d)
then
115 nullify(child_neighbor%node%neighbor(iside,^d)%node)
118 nullify(child_neighbor%node%neighbor(iotherside,^d)%node)
122 nullify(tree%node%child(ic^d)%node)
123 deallocate(igrid_to_node(child_igrid(ic^d),child_ipe(ic^d))%node)
126 tree%node%leaf=.true.
127 tree%node%igrid=igrid
129 igrid_to_node(igrid,ipe)%node => tree%node
133 if (vote /= 2**^nd)
then
135 tree%node%active = .false.
136 nleafs_active = nleafs_active - vote
138 tree%node%active = .true.
139 nleafs_active = nleafs_active - vote + 1
141 active = tree%node%active
143 nleafs=nleafs-2**^nd+1
145 nleafs_level(child_level)=nleafs_level(child_level)-2**^nd
146 nleafs_level(level)=nleafs_level(level)+1
154 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
155 integer,
intent(in) :: igrid, ipe
156 logical,
intent(out):: active
158 integer :: ig^D, level, i^D, ic^D, child_ig^D, child_level, iside
159 integer :: my_neighbor_type
160 logical,
dimension(ndim) :: pole
165 level=tree%node%level
166 active=tree%node%active
170 tree%node%leaf=.false.
171 tree%node%active=.true.
178 child_ig^d=2*(ig^d-1)+ic^d;
180 child_igrid(ic^d),child_ipe(ic^d),active)
182 igrid_to_node(child_igrid(ic^d),child_ipe(ic^d))%node => child%node
184 tree%node%child(ic^d)%node => child%node
185 child%node%parent%node => tree%node
190 child%node => tree%node%child(ic^d)%node
192 i^dd=kr(^dd,^d)*(2*iside-3);
193 call find_neighbor(my_neighbor,my_neighbor_type,child,i^dd,pole)
194 select case (my_neighbor_type)
195 case (neighbor_sibling, neighbor_fine)
196 child%node%neighbor(iside,^d)%node => my_neighbor%node
198 my_neighbor%node%neighbor(iside,^d)%node => child%node
200 my_neighbor%node%neighbor(3-iside,^d)%node => child%node
203 nullify(child%node%neighbor(iside,^d)%node)
205 child%node%neighbor(3-ic^d,^d)%node=>tree%node%child(3-ic^d^d%ic^dd)%node\}
208 nleafs=nleafs+2**^nd-1
210 nleafs_level(child_level)=nleafs_level(child_level)+2**^nd
211 nleafs_level(level)=nleafs_level(level)-1
213 if (active) nleafs_active = nleafs_active + 2**^nd-1
221 integer,
intent(in) :: recv_igrid, recv_ipe, send_igrid, send_ipe
227 tree%node%igrid=recv_igrid
228 tree%node%ipe=recv_ipe
239 integer,
intent(in) :: level
242 nullify(tree%node%next%node)
250 nullify(tree%node%prev%node)
259 integer,
intent(in) :: level
264 prev%node => tree%node%prev%node
265 next%node => tree%node%next%node
266 if (
associated(next%node).and.
associated(prev%node))
then
267 prev%node%next%node => next%node
268 next%node%prev%node => prev%node
269 else if (
associated(prev%node))
then
271 nullify(prev%node%next%node)
272 else if (
associated(next%node))
then
274 nullify(next%node%prev%node)
286 integer,
intent(in) :: file_handle
288 integer,
dimension(MPI_STATUS_SIZE) :: status
305 call mpi_file_write(file_handle,tree%node%leaf,1,mpi_logical,status,
ierrmpi)
307 if (.not.tree%node%leaf)
then
322 integer,
intent(in) :: file_handle
324 integer,
dimension(MPI_STATUS_SIZE) :: status
326 integer :: ig^D, level, Morton_no, igrid, ipe, isfc
327 integer,
external :: getnode
340 nullify(
tree_root(ig^d)%node%parent%node)
359 integer,
intent(in) :: ig^d, level
362 integer :: ic^d, child_ig^d, child_level
365 call mpi_file_read(file_handle,leaf,1,mpi_logical, &
372 tree%node%level=level
373 tree%node%active=.true. .and. leaf
376 nullify(tree%node%child(ic^d)%node)
378 nullify({tree%node%neighbor(1,^d)%node},{tree%node%neighbor(2,^d)%node})
379 nullify(tree%node%next%node,tree%node%prev%node)
387 morton_no=morton_no+1
390 tree%node%igrid=igrid
400 child_ig^d=2*(ig^d-1)+ic^d;
401 allocate(tree%node%child(ic^d)%node)
402 tree%node%child(ic^d)%node%parent%node => tree%node
403 call read_node(tree%node%child(ic^d),child_ig^d,child_level)
subroutine find_root_neighbor(tree_neighbor, tree, iD)
find neighors of level-one root blocks
subroutine asign_tree_neighbor(tree)
asign tree node neighor
subroutine find_neighbor(my_neighbor, my_neighbor_type, tree, iD, pole)
find neighors of all blocks
integer function getnode(ipe)
Get first available igrid on processor ipe.
subroutine build_connectivity
subroutine get_level_range
subroutine init_tree_leaf(tree, igD, level, igrid, ipe, active)
subroutine delete_from_linked_list(level, tree)
recursive subroutine write_node(tree)
subroutine coarsen_tree_leaf(igrid, ipe, child_igrid, child_ipe, active)
subroutine refine_tree_leaf(child_igrid, child_ipe, igrid, ipe, active)
subroutine init_forest_root
build root forest
subroutine read_forest(file_handle)
subroutine write_forest(file_handle)
subroutine change_ipe_tree_leaf(recv_igrid, recv_ipe, send_igrid, send_ipe)
subroutine add_to_linked_list(level, tree)
recursive subroutine read_node(tree, igD, level)
Module with basic grid data structures.
integer, dimension(:), allocatable, save nleafs_level
How many leaves are present per refinement level.
integer, dimension(:), allocatable, save sfc_to_igrid
Go from a Morton number to an igrid index (for a single processor)
integer, save nleafs
Number of leaf block.
integer, dimension(:), allocatable, save igrid_to_sfc
Go from a grid index to Morton number (for a single processor)
integer, dimension(:,:), allocatable, save sfc_iglevel1
Space filling curve for level 1 grid. sfc_iglevel1(^D, MN) gives ig^D (the spatial index of the grid)
type(tree_node_ptr), dimension(:), allocatable, save level_tail
The tail pointer of the linked list per refinement level.
integer, dimension(:), allocatable, save morton_stop
Last Morton number per processor.
type(tree_node_ptr), dimension(:^d &), allocatable, save tree_root
Pointers to the coarse grid.
integer, save nparents
Number of parent blocks.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
type(tree_node_ptr), dimension(:), allocatable, save level_head
The head pointer of the linked list per refinement level.
This module contains definitions of global parameters and variables and some generic functions/subrou...
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer, parameter nlevelshi
The maximum number of levels in the grid refinement.
integer icomm
The MPI communicator.
integer, dimension(:), allocatable ng
number of grid blocks in domain per dimension, in array over levels
integer mype
The rank of the current MPI task.
integer ierrmpi
A global MPI error return code.
integer npe
The number of MPI tasks.
subroutine get_morton_range
Set the Morton range for each processor.
subroutine amr_morton_order
Construct Morton-order as a global recursive lexicographic ordering.
subroutine level1_morton_order
build Morton space filling curve for level 1 grid