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)
214 subroutine proper_nesting
219 logical,
dimension(:,:),
allocatable :: refine2
220 integer :: iigrid, igrid, level, ic^
d, inp^
d, i^
d, my_neighbor_type,ipe
222 type(
tree_node_ptr) :: tree, p_neighbor, my_parent, sibling, my_neighbor, &
239 if (.not.
associated(tree%node))
exit
241 if (
refine(tree%node%igrid,tree%node%ipe))
then
242 ic^
d=1+modulo(tree%node%ig^
d-1,2);
243 {
do inp^db=ic^db-2,ic^db-1\}
244 if (inp^
d==0|.and.) cycle
245 p_neighbor%node => tree%node%parent%node
247 p_neighbor%node => p_neighbor%node%neighbor(ic^
d,^
d)%node
248 if (.not.
associated(p_neighbor%node)) cycle
250 if (p_neighbor%node%leaf)
then
251 refine(p_neighbor%node%igrid,p_neighbor%node%ipe)=.true.
256 tree%node => tree%node%next%node
263 do iigrid=1,igridstail; igrid=igrids(iigrid);
264 if (refine(igrid,mype).and.coarsen(igrid,mype)) coarsen(igrid,mype)=.false.
268 sendbuf(:)=coarsen(:,mype)
269 call mpi_allgather(sendbuf,max_blocks,mpi_logical,coarsen,max_blocks, &
270 mpi_logical,icomm,ierrmpi)
272 do level=levmax,max(2,levmin),-1
273 tree%node => level_head(level)%node
275 if (.not.
associated(tree%node))
exit
277 if (coarsen(tree%node%igrid,tree%node%ipe))
then
279 my_parent%node => tree%node%parent%node
282 check1: {
do ic^db=1,2\}
283 sibling%node => my_parent%node%child(ic^d)%node
284 if (sibling%node%leaf)
then
285 if (coarsen(sibling%node%igrid,sibling%node%ipe)) cycle
294 check2: {
do ic^db=1,2\}
295 sibling%node => my_parent%node%child(ic^d)%node
296 {
do i^db=ic^db-2,ic^db-1\}
297 if (i^d==0|.and.) cycle
298 call find_neighbor(my_neighbor,my_neighbor_type, &
300 select case (my_neighbor_type)
301 case (neighbor_sibling)
302 if (refine(my_neighbor%node%igrid, &
303 my_neighbor%node%ipe))
then
310 neighborchild%node=>my_neighbor%node%child(1^d&)%node
311 if (neighborchild%node%leaf)
then
312 if (coarsen(neighborchild%node%igrid, &
313 neighborchild%node%ipe))
then
326 tree%node => tree%node%next%node
335 type(tree_node_ptr) :: sibling
338 sibling%node => my_parent%node%child(ic^d)%node
339 if (sibling%node%leaf)
then
340 coarsen(sibling%node%igrid,sibling%node%ipe)=.false.
347 end subroutine proper_nesting
350 subroutine coarsen_grid_siblings(igrid,ipe,child_igrid,child_ipe,active)
356 integer,
intent(in) :: igrid, ipe
357 integer,
dimension(2^D&),
intent(in) :: child_igrid, child_ipe
358 logical,
intent(in) :: active
360 integer :: igridFi, ipeFi, ixCo^L, ixCoG^L, ixCoM^L, ic^D, idir
365 if (.not. active)
then
366 if (ipe ==
mype)
then
369 igridfi=child_igrid(ic^d)
370 ipefi=child_ipe(ic^d)
381 igridfi=child_igrid(ic^d)
382 ipefi=child_ipe(ic^d)
384 if (ipefi==mype)
then
385 ^d&dxlevel(^d)=rnode(rpdx^d_,igridfi);
387 ixcomin^d=ixmlo^d+(ic^d-1)*(ixmhi^d-ixmlo^d+1)/2;
388 ixcomax^d=ixmhi^d+(ic^d-2)*(ixmhi^d-ixmlo^d+1)/2;
390 call coarsen_grid(ps(igridfi),ixg^ll,ixm^ll,ps(igrid),ixg^ll,ixco^l)
395 ixcogmax^d=ixghi^d/2+nghostcells;
396 ixcom^l=ixcog^l^lsubnghostcells;
397 call coarsen_grid(ps(igridfi),ixg^ll,ixm^ll,psc(igridfi), &
403 call mpi_isend(psc(igridfi)%w,1,type_coarse_block,ipe,itag, &
404 icomm,sendrequest(isend),ierrmpi)
405 if(stagger_grid)
then
408 itag_stg=(npe+ipefi+1)+igridfi*(ndir-1+idir)
409 call mpi_isend(psc(igridfi)%ws,1,type_coarse_block_stg(idir,ic^d),ipe,itag_stg, &
410 icomm,sendrequest_stg(isend),ierrmpi)
419 call mpi_irecv(ps(igrid)%w,1,type_sub_block(ic^d),ipefi,itag, &
420 icomm,recvrequest(irecv),ierrmpi)
421 if(stagger_grid)
then
424 itag_stg=(npe+ipefi+1)+igridfi*(ndir-1+idir)
425 call mpi_irecv(ps(igrid)%ws,1,type_sub_block_stg(idir,ic^d),ipefi,itag_stg, &
426 icomm,recvrequest_stg(irecv),ierrmpi)
433 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
Equation of state for AMRVAC, handled through a single eos_container object.
subroutine, public prepare_eos_w_fields(psx)
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