Initialise decomposition for a given rank
Distributes remainder cells to the first ranks in each direction. rank is mapped to (rx, ry) using row-major order: rank = ry * px + rx
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(decomp_t), | intent(out) | :: | d |
Decomposition descriptor to populate |
||
| integer, | intent(in) | :: | nx_global |
Total physical cells in x |
||
| integer, | intent(in) | :: | ny_global |
Total physical cells in y |
||
| integer, | intent(in) | :: | px |
Process grid size in x |
||
| integer, | intent(in) | :: | py |
Process grid size in y |
||
| integer, | intent(in) | :: | rank |
MPI rank (0-based) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | base_nx | ||||
| integer, | private | :: | base_ny | ||||
| integer, | private | :: | rem_nx | ||||
| integer, | private | :: | rem_ny |
subroutine decomp_init(d, nx_global, ny_global, px, py, rank) !! Initialise decomposition for a given rank !! !! Distributes remainder cells to the first ranks in each direction. !! rank is mapped to (rx, ry) using row-major order: rank = ry * px + rx type(decomp_t), intent(out) :: d !! Decomposition descriptor to populate integer, intent(in) :: nx_global !! Total physical cells in x integer, intent(in) :: ny_global !! Total physical cells in y integer, intent(in) :: px !! Process grid size in x integer, intent(in) :: py !! Process grid size in y integer, intent(in) :: rank !! MPI rank (0-based) integer :: base_nx, rem_nx, base_ny, rem_ny d%px = px d%py = py d%nx_global = nx_global d%ny_global = ny_global ! Row-major mapping: rank = ry * px + rx d%rx = mod(rank, px) d%ry = rank/px ! Distribute cells with remainder going to first ranks base_nx = nx_global/px rem_nx = mod(nx_global, px) if (d%rx < rem_nx) then d%nx_local = base_nx + 1 d%i_start = d%rx*(base_nx + 1) + 1 else d%nx_local = base_nx d%i_start = rem_nx*(base_nx + 1) + (d%rx - rem_nx)*base_nx + 1 end if base_ny = ny_global/py rem_ny = mod(ny_global, py) if (d%ry < rem_ny) then d%ny_local = base_ny + 1 d%j_start = d%ry*(base_ny + 1) + 1 else d%ny_local = base_ny d%j_start = rem_ny*(base_ny + 1) + (d%ry - rem_ny)*base_ny + 1 end if ! Boundary flags d%has_west = (d%rx == 0) d%has_east = (d%rx == px - 1) d%has_south = (d%ry == 0) d%has_north = (d%ry == py - 1) end subroutine decomp_init