6 integer :: itag, irecv, isend
7 integer,
dimension(:),
allocatable :: recvrequest, sendrequest
8 integer,
dimension(:,:),
allocatable :: recvstatus, sendstatus
11 integer,
dimension(:),
allocatable :: recvrequest_stg, sendrequest_stg
12 integer,
dimension(:,:),
allocatable :: recvstatus_stg, sendstatus_stg
38 integer :: iigrid, igrid, ipe, igridco, ipeco, level, ic^
d
39 integer,
dimension(2^D&) :: igridfi, ipefi
40 integer :: n_coarsen, n_refine
51 n_coarsen = count(
coarsen(:, :))
52 n_refine = count(
refine(:, :))
59 recvrequest=mpi_request_null
60 sendrequest=mpi_request_null
65 recvrequest_stg=mpi_request_null
66 sendrequest_stg=mpi_request_null
76 sibling%node => tree%node%child(ic^
d)%node
77 ipefi(ic^
d)=sibling%node%ipe
78 igridfi(ic^
d)=sibling%node%igrid
82 igridco=getnode(ipeco)
84 call coarsen_tree_leaf(igridco,ipeco,igridfi,ipefi,active)
86 call coarsen_grid_siblings(igridco,ipeco,igridfi,ipefi,active)
90 if (ipefi(ic^d)==ipeco)
then
91 call putnode(igridfi(ic^d),ipefi(ic^d))
92 coarsen(igridfi(ic^d),ipefi(ic^d))=.false.
100 call mpi_waitall(irecv,recvrequest,recvstatus,ierrmpi)
101 if(stagger_grid)
call mpi_waitall(irecv,recvrequest_stg,recvstatus_stg,ierrmpi)
104 call mpi_waitall(isend,sendrequest,sendstatus,ierrmpi)
105 if(stagger_grid)
call mpi_waitall(isend,sendrequest_stg,sendstatus_stg,ierrmpi)
108 deallocate(recvstatus,recvrequest,sendstatus,sendrequest)
109 if(stagger_grid)
deallocate(recvstatus_stg,recvrequest_stg,sendstatus_stg,sendrequest_stg)
113 do igrid=1,max_blocks
114 if (coarsen(igrid,ipe))
then
120 call putnode(igrid,ipe)
121 coarsen(igrid,ipe)=.false.
127 do igrid=1,max_blocks
128 if (refine(igrid,ipe))
then
131 igridfi(ic^d)=getnode(ipe)
135 call refine_tree_leaf(igridfi,ipefi,igrid,ipe,active)
137 if (ipe==mype)
call refine_grids(igridfi,ipefi,igrid,ipe,active)
140 call putnode(igrid,ipe)
141 refine(igrid,ipe)=.false.
150 if(.not.time_advance)
call mpi_barrier(icomm,ierrmpi)
152 if(stagger_grid)
call end_comm_faces
157 call amr_morton_order()
163 call build_connectivity
171 call getbc(global_time,0.d0,ps,iwstart,nwgc)
173 if (use_multigrid)
call mg_update_refinement(n_coarsen, n_refine)
175 if (
associated(usr_after_refine))
then
176 call usr_after_refine(n_coarsen, n_refine)
210 subroutine proper_nesting
215 logical,
dimension(:,:),
allocatable :: refine2
216 integer :: iigrid, igrid, level, ic^
d, inp^
d, i^
d, my_neighbor_type,ipe
218 type(
tree_node_ptr) :: tree, p_neighbor, my_parent, sibling, my_neighbor, &
235 if (.not.
associated(tree%node))
exit
237 if (
refine(tree%node%igrid,tree%node%ipe))
then
238 ic^
d=1+modulo(tree%node%ig^
d-1,2);
239 {
do inp^db=ic^db-2,ic^db-1\}
240 if (inp^
d==0|.and.) cycle
241 p_neighbor%node => tree%node%parent%node
243 p_neighbor%node => p_neighbor%node%neighbor(ic^
d,^
d)%node
244 if (.not.
associated(p_neighbor%node)) cycle
246 if (p_neighbor%node%leaf)
then
247 refine(p_neighbor%node%igrid,p_neighbor%node%ipe)=.true.
252 tree%node => tree%node%next%node
259 do iigrid=1,igridstail; igrid=igrids(iigrid);
260 if (refine(igrid,mype).and.coarsen(igrid,mype)) coarsen(igrid,mype)=.false.
264 sendbuf(:)=coarsen(:,mype)
265 call mpi_allgather(sendbuf,max_blocks,mpi_logical,coarsen,max_blocks, &
266 mpi_logical,icomm,ierrmpi)
268 do level=levmax,max(2,levmin),-1
269 tree%node => level_head(level)%node
271 if (.not.
associated(tree%node))
exit
273 if (coarsen(tree%node%igrid,tree%node%ipe))
then
275 my_parent%node => tree%node%parent%node
278 check1: {
do ic^db=1,2\}
279 sibling%node => my_parent%node%child(ic^d)%node
280 if (sibling%node%leaf)
then
281 if (coarsen(sibling%node%igrid,sibling%node%ipe)) cycle
290 check2: {
do ic^db=1,2\}
291 sibling%node => my_parent%node%child(ic^d)%node
292 {
do i^db=ic^db-2,ic^db-1\}
293 if (i^d==0|.and.) cycle
294 call find_neighbor(my_neighbor,my_neighbor_type, &
296 select case (my_neighbor_type)
297 case (neighbor_sibling)
298 if (refine(my_neighbor%node%igrid, &
299 my_neighbor%node%ipe))
then
306 neighborchild%node=>my_neighbor%node%child(1^d&)%node
307 if (neighborchild%node%leaf)
then
308 if (coarsen(neighborchild%node%igrid, &
309 neighborchild%node%ipe))
then
322 tree%node => tree%node%next%node
331 type(tree_node_ptr) :: sibling
334 sibling%node => my_parent%node%child(ic^d)%node
335 if (sibling%node%leaf)
then
336 coarsen(sibling%node%igrid,sibling%node%ipe)=.false.
343 end subroutine proper_nesting
346 subroutine coarsen_grid_siblings(igrid,ipe,child_igrid,child_ipe,active)
352 integer,
intent(in) :: igrid, ipe
353 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
354 logical,
intent(in) :: active
356 integer :: igridFi, ipeFi, ixCo^L, ixCoG^L, ixCoM^L, ic^D, idir
361 if (.not. active)
then
362 if (ipe ==
mype)
then
365 igridfi=child_igrid(ic^d)
366 ipefi=child_ipe(ic^d)
377 igridfi=child_igrid(ic^d)
378 ipefi=child_ipe(ic^d)
380 if (ipefi==mype)
then
381 ^d&dxlevel(^d)=rnode(rpdx^d_,igridfi);
383 ixcomin^d=ixmlo^d+(ic^d-1)*(ixmhi^d-ixmlo^d+1)/2;
384 ixcomax^d=ixmhi^d+(ic^d-2)*(ixmhi^d-ixmlo^d+1)/2;
386 call coarsen_grid(ps(igridfi),ixg^ll,ixm^ll,ps(igrid),ixg^ll,ixco^l)
391 ixcogmax^d=ixghi^d/2+nghostcells;
392 ixcom^l=ixcog^l^lsubnghostcells;
393 call coarsen_grid(ps(igridfi),ixg^ll,ixm^ll,psc(igridfi), &
399 call mpi_isend(psc(igridfi)%w,1,type_coarse_block,ipe,itag, &
400 icomm,sendrequest(isend),ierrmpi)
401 if(stagger_grid)
then
404 itag_stg=(npe+ipefi+1)+igridfi*(ndir-1+idir)
405 call mpi_isend(psc(igridfi)%ws,1,type_coarse_block_stg(idir,ic^d),ipe,itag_stg, &
406 icomm,sendrequest_stg(isend),ierrmpi)
415 call mpi_irecv(ps(igrid)%w,1,type_sub_block(ic^d),ipefi,itag, &
416 icomm,recvrequest(irecv),ierrmpi)
417 if(stagger_grid)
then
420 itag_stg=(npe+ipefi+1)+igridfi*(ndir-1+idir)
421 call mpi_irecv(ps(igrid)%ws,1,type_sub_block_stg(idir,ic^d),ipefi,itag_stg, &
422 icomm,recvrequest_stg(irecv),ierrmpi)
429 end subroutine coarsen_grid_siblings
subroutine unflag_coarsen_siblings
subroutine, public store_faces
To achive consistency and thus conservation of divergence, when refining a block we take into account...
subroutine, public comm_faces
When refining a coarse block with fine neighbours, it is necessary prolong consistently with the alre...
subroutine, public end_comm_faces
subroutine, public find_neighbor(my_neighbor, my_neighbor_type, tree, id, pole)
find neighors of all blocks
subroutine, public putnode(igrid, ipe)
subroutine, public alloc_node(igrid)
allocate arrays on igrid node
integer function, public getnode(ipe)
Get first available igrid on processor ipe.
Module to coarsen and refine grids for AMR.
subroutine, public amr_rebalance
Cost-weighted rebalance without refine/coarsen. For static/uniform grids (refine_max_level=1) amr_coa...
subroutine, public amr_coarsen_refine
coarsen and refine blocks to update AMR grid
subroutine, public coarsen_grid(sfi, ixfigl, ixfil, sco, ixcogl, ixcol)
coarsen one grid to its coarser representative
Module with basic grid data structures.
logical, dimension(:,:), allocatable, save refine
logical, dimension(:,:), allocatable, save coarsen
AMR flags and grids-in-use identifier per processor (igrid,ipe)
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 refine_tree_leaf(child_igrid, child_ipe, igrid, ipe, active)
subroutine, public coarsen_tree_leaf(igrid, ipe, child_igrid, child_ipe, active)
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision global_time
The global simulation time.
integer, parameter ndim
Number of spatial dimensions for grid variables.
logical stagger_grid
True for using stagger grid.
integer icomm
The MPI communicator.
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.
integer nbufferx
Number of cells as buffer zone.
integer refine_max_level
Maximal number of AMR levels.
integer max_blocks
The maximum number of grid blocks in a processor.
subroutine, public initial_condition(igrid)
fill in initial condition
subroutine load_balance
reallocate blocks into processors for load balance
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
subroutine, public refine_grids(child_igrid, child_ipe, igrid, ipe, active)
refine one block to its children blocks
subroutine, public selectgrids
subroutine amr_morton_order
Construct Morton-order as a global recursive lexicographic ordering.
Module with all the methods that users can customize in AMRVAC.
procedure(after_refine), pointer usr_after_refine