mod_coarsen_refine Module

Module to coarsen and refine grids for AMR


Uses

  • module~~mod_coarsen_refine~~UsesGraph module~mod_coarsen_refine mod_coarsen_refine module~mod_mpi_wrapper mod_mpi_wrapper module~mod_coarsen_refine->module~mod_mpi_wrapper mpi mpi module~mod_mpi_wrapper->mpi

Used by

  • module~~mod_coarsen_refine~~UsedByGraph module~mod_coarsen_refine mod_coarsen_refine proc~resettree resettree proc~resettree->module~mod_coarsen_refine proc~resettree_convert resettree_convert proc~resettree_convert->module~mod_coarsen_refine proc~settree settree proc~settree->module~mod_coarsen_refine

Variables

Type Visibility Attributes Name Initial
integer, private, allocatable, dimension(:) :: cf_rcv_ibuf
integer, private, allocatable, dimension(:,:) :: cf_rcv_ic
integer, private, allocatable, dimension(:) :: cf_rcv_igrid
integer, private, allocatable, dimension(:) :: cf_rcv_key
integer, private, allocatable, dimension(:) :: cf_rcv_src
integer, private, allocatable, dimension(:) :: cf_recv_pe
integer, private, allocatable, dimension(:) :: cf_recv_pe_len
integer, private, allocatable, dimension(:) :: cf_recv_pe_off
integer, private, allocatable, dimension(:) :: cf_send_pe
integer, private, allocatable, dimension(:) :: cf_send_pe_len
integer, private, allocatable, dimension(:) :: cf_send_pe_off
integer, private, allocatable, dimension(:) :: cf_snd_dest
integer, private, allocatable, dimension(:) :: cf_snd_ibuf
integer, private, allocatable, dimension(:) :: cf_snd_igrid
integer, private, allocatable, dimension(:) :: cf_snd_key
integer, private :: irecv

MPI recv send variables for AMR. One request per neighbouring rank now, not one per chunk, so these are sized by npe.

integer, private :: isend

MPI recv send variables for AMR. One request per neighbouring rank now, not one per chunk, so these are sized by npe.

integer, private :: itag

MPI recv send variables for AMR. One request per neighbouring rank now, not one per chunk, so these are sized by npe.

integer, private :: itag_stg

MPI recv send variables for staggered-variable AMR

integer, private, parameter :: max_buff = 1024

maximum number of coarse blocks that can be sent after coarsening

integer, private :: n_cf_rcv

Per outgoing / incoming chunk, appended by coarsen_grid_siblings during the walk and turned into per-peer runs by exchange_coarsened_blocks. cf_snd_igrid / cf_snd_ibuf and the rcv counterparts are read by the pack and unpack kernels and are therefore device-resident; cf_snd_dest, cf_snd_key, cf_rcv_src and cf_rcv_key are the host-side working set the layout is derived from.

integer, private :: n_cf_recv_pe

The peers themselves, ascending, with the extent of each one's run. Host only: these drive the MPI calls and nothing else.

integer, private :: n_cf_send_pe

The peers themselves, ascending, with the extent of each one's run. Host only: these drive the MPI calls and nothing else.

integer, private :: n_cf_snd

Per outgoing / incoming chunk, appended by coarsen_grid_siblings during the walk and turned into per-peer runs by exchange_coarsened_blocks. cf_snd_igrid / cf_snd_ibuf and the rcv counterparts are read by the pack and unpack kernels and are therefore device-resident; cf_snd_dest, cf_snd_key, cf_rcv_src and cf_rcv_key are the host-side working set the layout is derived from.

double precision, private, allocatable, dimension(:) :: rcv_buff_cf

MPI buffers to send non-local coarsened grids.

The exchange is aggregated per destination rank: every coarsened child bound for one peer occupies a contiguous run of snd_buff_cf and travels in a single Isend, so the message count is the number of neighbouring ranks rather than the number of (parent, child) pairs. That is also what lets the tag be a constant; it used to be itag=ipeFi+igridFi, which is unique only because the matching Irecv names ipeFi as its source, and was itself a workaround for MPI_TAG_UB.

Both ranks order a peer's run by the key

ikey = 8*(igridCo-1) + (ic1-1) + 2*(ic2-1) + 4*(ic3-1)

built from the receiving parent's block index: the sender has it as the igrid argument of coarsen_grid_siblings, the receiver as its own igrid. Both know it because amr_coarsen_refine walks the globally replicated coarsen() table in the same order on every rank and calls getnode() for every event, so the free-node bookkeeping is replicated too. Sorting by the key makes the two layouts agree element for element with no handshake.

Aggregation gives up MPI's own mismatch detection, so the arrival lengths are checked against the layout in exchange_coarsened_blocks.

integer, private, dimension(:), allocatable :: recvrequest
integer, private, dimension(:), allocatable :: recvrequest_stg
integer, private, dimension(:,:), allocatable :: recvstatus
integer, private, dimension(:,:), allocatable :: recvstatus_stg
integer, private, dimension(:), allocatable :: sendrequest
integer, private, dimension(:), allocatable :: sendrequest_stg
integer, private, dimension(:,:), allocatable :: sendstatus
integer, private, dimension(:,:), allocatable :: sendstatus_stg
double precision, private, allocatable, dimension(:) :: snd_buff_cf

MPI buffers to send non-local coarsened grids.

The exchange is aggregated per destination rank: every coarsened child bound for one peer occupies a contiguous run of snd_buff_cf and travels in a single Isend, so the message count is the number of neighbouring ranks rather than the number of (parent, child) pairs. That is also what lets the tag be a constant; it used to be itag=ipeFi+igridFi, which is unique only because the matching Irecv names ipeFi as its source, and was itself a workaround for MPI_TAG_UB.

Both ranks order a peer's run by the key

ikey = 8*(igridCo-1) + (ic1-1) + 2*(ic2-1) + 4*(ic3-1)

built from the receiving parent's block index: the sender has it as the igrid argument of coarsen_grid_siblings, the receiver as its own igrid. Both know it because amr_coarsen_refine walks the globally replicated coarsen() table in the same order on every rank and calls getnode() for every event, so the free-node bookkeeping is replicated too. Sorting by the key makes the two layouts agree element for element with no handshake.

Aggregation gives up MPI's own mismatch detection, so the arrival lengths are checked against the layout in exchange_coarsened_blocks.


Subroutines

public subroutine amr_coarsen_refine()

coarsen and refine blocks to update AMR grid

Arguments

None

private subroutine coarsen_grid_siblings(igrid, ipe, child_igrid, child_ipe, active)

coarsen sibling blocks into one block

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: igrid
integer, intent(in) :: ipe
integer, intent(in), dimension(2,2,2) :: child_igrid
integer, intent(in), dimension(2,2,2) :: child_ipe
logical, intent(in) :: active

private subroutine exchange_coarsened_blocks()

Exchange and apply the non-local half of a coarsening step, one message per neighbouring rank.

Read more…

Arguments

None

private subroutine proper_nesting()

For all grids on all processors, do a check on refinement flags. Make sure that neighbors will not differ more than one level of refinement.

Arguments

None