blob: d3f3b362066178d4405d7fe3615ca0920e71fd6b [file] [log] [blame]
c---------------------------------------------------------------------
c---------------------------------------------------------------------
subroutine make_set
c---------------------------------------------------------------------
c---------------------------------------------------------------------
c---------------------------------------------------------------------
c This function allocates space for a set of cells and fills the set
c such that communication between cells on different nodes is only
c nearest neighbor
c---------------------------------------------------------------------
include 'header.h'
include 'mpinpb.h'
integer p, i, j, c, dir, size, excess, ierr,ierrcode
c---------------------------------------------------------------------
c compute square root; add small number to allow for roundoff
c (note: this is computed in setup_mpi.f also, but prefer to do
c it twice because of some include file problems).
c---------------------------------------------------------------------
ncells = dint(dsqrt(dble(no_nodes) + 0.00001d0))
c---------------------------------------------------------------------
c this makes coding easier
c---------------------------------------------------------------------
p = ncells
c---------------------------------------------------------------------
c determine the location of the cell at the bottom of the 3D
c array of cells
c---------------------------------------------------------------------
cell_coord(1,1) = mod(node,p)
cell_coord(2,1) = node/p
cell_coord(3,1) = 0
c---------------------------------------------------------------------
c set the cell_coords for cells in the rest of the z-layers;
c this comes down to a simple linear numbering in the z-direct-
c ion, and to the doubly-cyclic numbering in the other dirs
c---------------------------------------------------------------------
do c=2, p
cell_coord(1,c) = mod(cell_coord(1,c-1)+1,p)
cell_coord(2,c) = mod(cell_coord(2,c-1)-1+p,p)
cell_coord(3,c) = c-1
end do
c---------------------------------------------------------------------
c offset all the coordinates by 1 to adjust for Fortran arrays
c---------------------------------------------------------------------
do dir = 1, 3
do c = 1, p
cell_coord(dir,c) = cell_coord(dir,c) + 1
end do
end do
c---------------------------------------------------------------------
c slice(dir,n) contains the sequence number of the cell that is in
c coordinate plane n in the dir direction
c---------------------------------------------------------------------
do dir = 1, 3
do c = 1, p
slice(dir,cell_coord(dir,c)) = c
end do
end do
c---------------------------------------------------------------------
c fill the predecessor and successor entries, using the indices
c of the bottom cells (they are the same at each level of k
c anyway) acting as if full periodicity pertains; note that p is
c added to those arguments to the mod functions that might
c otherwise return wrong values when using the modulo function
c---------------------------------------------------------------------
i = cell_coord(1,1)-1
j = cell_coord(2,1)-1
predecessor(1) = mod(i-1+p,p) + p*j
predecessor(2) = i + p*mod(j-1+p,p)
predecessor(3) = mod(i+1,p) + p*mod(j-1+p,p)
successor(1) = mod(i+1,p) + p*j
successor(2) = i + p*mod(j+1,p)
successor(3) = mod(i-1+p,p) + p*mod(j+1,p)
c---------------------------------------------------------------------
c now compute the sizes of the cells
c---------------------------------------------------------------------
do dir= 1, 3
c---------------------------------------------------------------------
c set cell_coord range for each direction
c---------------------------------------------------------------------
size = grid_points(dir)/p
excess = mod(grid_points(dir),p)
do c=1, ncells
if (cell_coord(dir,c) .le. excess) then
cell_size(dir,c) = size+1
cell_low(dir,c) = (cell_coord(dir,c)-1)*(size+1)
cell_high(dir,c) = cell_low(dir,c)+size
else
cell_size(dir,c) = size
cell_low(dir,c) = excess*(size+1)+
> (cell_coord(dir,c)-excess-1)*size
cell_high(dir,c) = cell_low(dir,c)+size-1
endif
if (cell_size(dir, c) .le. 2) then
write(*,50)
50 format(' Error: Cell size too small. Min size is 3')
ierrcode = 1
call MPI_Abort(mpi_comm_world,ierrcode,ierr)
stop
endif
end do
end do
return
end