25 integer :: ig^
d, level, igrid, ipe
26 integer :: iside, i^
d, morton_no, isfc
49 call init_tree_leaf(
tree_root(ig^
d),ig^
d,level,igrid,ipe,.true.)
53 {
do ig^db=1,
ng^db(1)\}
55 i^dd=
kr(^dd,^
d)*(2*iside-3);
62 call amr_morton_order()
66 subroutine init_tree_leaf(tree,ig^D,level,igrid,ipe,active)
71 integer,
intent(in) :: ig^d, level, igrid, ipe
72 logical,
intent(in) :: active
84 tree%node%active=active
86 nullify(tree%node%parent%node)
88 nullify(tree%node%child(ic^d)%node)
91 call add_to_linked_list(level,tree)
94 nullify({tree%node%neighbor(1,^d)%node},{tree%node%neighbor(2,^d)%node})
96 igrid_to_node(igrid,ipe)%node => tree%node
98 end subroutine init_tree_leaf
104 integer,
intent(in) :: igrid, ipe
105 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
106 logical,
intent(out) :: active
109 integer :: level, ic^d, child_level, iside, iotherside, vote
113 tree%node =>
igrid_to_node(child_igrid(1^d&),child_ipe(1^d&))%node%parent%node
114 level=tree%node%level
116 call add_to_linked_list(level,tree)
122 child%node => tree%node%child(ic^d)%node
125 if(child%node%active) vote=vote+1
127 call delete_from_linked_list(child_level,child)
131 child_neighbor%node => child%node%neighbor(iside,^d)%node
132 if (
associated(child_neighbor%node))
then
133 if (child%node%ig^d==child_neighbor%node%ig^d)
then
134 nullify(child_neighbor%node%neighbor(iside,^d)%node)
137 nullify(child_neighbor%node%neighbor(iotherside,^d)%node)
141 nullify(tree%node%child(ic^d)%node)
142 deallocate(igrid_to_node(child_igrid(ic^d),child_ipe(ic^d))%node)
145 tree%node%leaf=.true.
146 tree%node%igrid=igrid
148 igrid_to_node(igrid,ipe)%node => tree%node
152 if (vote /= 2**^nd)
then
154 tree%node%active = .false.
155 nleafs_active = nleafs_active - vote
157 tree%node%active = .true.
158 nleafs_active = nleafs_active - vote + 1
160 active = tree%node%active
162 nleafs=nleafs-2**^nd+1
164 nleafs_level(child_level)=nleafs_level(child_level)-2**^nd
165 nleafs_level(level)=nleafs_level(level)+1
174 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
175 integer,
intent(in) :: igrid, ipe
176 logical,
intent(out):: active
178 integer :: ig^
d, level, i^
d, ic^
d, child_ig^
d, child_level, iside
179 integer :: my_neighbor_type
180 logical,
dimension(ndim) :: pole
186 level=tree%node%level
187 active=tree%node%active
191 tree%node%leaf=.false.
192 tree%node%active=.true.
194 call delete_from_linked_list(level,tree)
199 child_ig^
d=2*(ig^
d-1)+ic^
d;
200 call init_tree_leaf(child,child_ig^
d,child_level, &
201 child_igrid(ic^
d),child_ipe(ic^
d),active)
205 tree%node%child(ic^
d)%node => child%node
206 child%node%parent%node => tree%node
211 child%node => tree%node%child(ic^d)%node
213 i^dd=kr(^dd,^d)*(2*iside-3);
214 call find_neighbor(my_neighbor,my_neighbor_type,child,i^dd,pole)
215 select case (my_neighbor_type)
216 case (neighbor_sibling, neighbor_fine)
217 child%node%neighbor(iside,^d)%node => my_neighbor%node
219 my_neighbor%node%neighbor(iside,^d)%node => child%node
221 my_neighbor%node%neighbor(3-iside,^d)%node => child%node
224 nullify(child%node%neighbor(iside,^d)%node)
226 child%node%neighbor(3-ic^d,^d)%node=>tree%node%child(3-ic^d^d%ic^dd)%node\}
229 nleafs=nleafs+2**^nd-1
231 nleafs_level(child_level)=nleafs_level(child_level)+2**^nd
232 nleafs_level(level)=nleafs_level(level)-1
234 if (active) nleafs_active = nleafs_active + 2**^nd-1
242 integer,
intent(in) :: recv_igrid, recv_ipe, send_igrid, send_ipe
249 tree%node%igrid=recv_igrid
250 tree%node%ipe=recv_ipe
257 subroutine add_to_linked_list(level,tree)
261 integer,
intent(in) :: level
264 nullify(tree%node%next%node)
272 nullify(tree%node%prev%node)
275 end subroutine add_to_linked_list
277 subroutine delete_from_linked_list(level,tree)
281 integer,
intent(in) :: level
286 prev%node => tree%node%prev%node
287 next%node => tree%node%next%node
288 if (
associated(next%node).and.
associated(prev%node))
then
289 prev%node%next%node => next%node
290 next%node%prev%node => prev%node
291 else if (
associated(prev%node))
then
293 nullify(prev%node%next%node)
294 else if (
associated(next%node))
then
296 nullify(next%node%prev%node)
302 end subroutine delete_from_linked_list
308 integer,
intent(in) :: file_handle
310 integer,
dimension(MPI_STATUS_SIZE) :: status
327 call mpi_file_write(file_handle,tree%node%leaf,1,mpi_logical,status,
ierrmpi)
329 if (.not.tree%node%leaf)
then
347 integer,
intent(in) :: file_handle
349 integer,
dimension(MPI_STATUS_SIZE) :: status
351 integer :: ig^
d, level, morton_no, igrid, ipe, isfc
384 integer,
intent(in) :: ig^
d, level
386 integer :: ic^
d, child_ig^
d, child_level
390 call mpi_file_read(file_handle,leaf,1,mpi_logical, &
397 tree%node%level=level
398 tree%node%active=.true. .and. leaf
401 nullify(tree%node%child(ic^
d)%node)
403 nullify({tree%node%neighbor(1,^
d)%node},{tree%node%neighbor(2,^
d)%node})
404 nullify(tree%node%next%node,tree%node%prev%node)
409 call add_to_linked_list(level,tree)
412 morton_no=morton_no+1
415 tree%node%igrid=igrid
425 child_ig^
d=2*(ig^
d-1)+ic^
d;
426 allocate(tree%node%child(ic^
d)%node)
427 tree%node%child(ic^
d)%node%parent%node => tree%node
428 call read_node(tree%node%child(ic^
d),child_ig^
d,child_level)
recursive subroutine write_node(tree)
recursive subroutine read_node(tree, igd, level)
subroutine, public find_neighbor(my_neighbor, my_neighbor_type, tree, id, pole)
find neighors of all blocks
subroutine, public asign_tree_neighbor(tree)
asign tree node neighor
subroutine, public find_root_neighbor(tree_neighbor, tree, id)
find neighors of level-one root blocks
integer function, public getnode(ipe)
Get first available igrid on processor ipe.
Module with basic grid data structures.
integer(kind=8) particle_mesh_epoch
Replicated forest generation: topology or ownership changes invalidate cached particle locations and ...
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.
subroutine, public get_level_range
subroutine, public build_connectivity
subroutine, public getigrids
subroutine, public change_ipe_tree_leaf(recv_igrid, recv_ipe, send_igrid, send_ipe)
subroutine, public write_forest(file_handle)
subroutine, public read_forest(file_handle)
subroutine, public refine_tree_leaf(child_igrid, child_ipe, igrid, ipe, active)
subroutine, public coarsen_tree_leaf(igrid, ipe, child_igrid, child_ipe, active)
subroutine, public init_forest_root
build root forest
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.
double precision, dimension(:), allocatable, parameter d
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