SUBROUTINE ppinit ! Parallel environment USE basic use prec_const IMPLICIT NONE INTEGER :: version_prov=-1 ! Variables for cartesian domain decomposition INTEGER, PARAMETER :: ndims=3 ! p, kx and z INTEGER, DIMENSION(ndims) :: dims=0, coords=0, coords_L=0, coords_R=0 LOGICAL :: periods(ndims) = .FALSE., reorder=.FALSE. CHARACTER(len=32) :: str INTEGER :: nargs, i, l, r_ INTEGER, DIMENSION(:), ALLOCATABLE :: rank2exclude CALL MPI_INIT(ierr) CALL MPI_COMM_RANK (MPI_COMM_WORLD, my_id, ierr) CALL MPI_COMM_SIZE (MPI_COMM_WORLD, num_procs, ierr) nargs = COMMAND_ARGUMENT_COUNT() ! IF( nargs .GT. 1 ) THEN DO i=1,ndims CALL GET_COMMAND_ARGUMENT(i, str, l, ierr) READ(str(1:l),'(i3)') dims(i) END DO IF( PRODUCT(dims) .NE. num_procs ) THEN IF(my_id .EQ. 0) WRITE(*, '(a,i4,a,i4)') 'Product of dims: ', PRODUCT(dims), " is not consistent WITH NPROCS=",num_procs CALL MPI_ABORT(MPI_COMM_WORLD, -2, ierr) END IF ELSE ! CALL MPI_DIMS_CREATE(num_procs, ndims, dims, ierr) dims(1) = 1 dims(2) = num_procs dims(3) = 1 END IF num_procs_p = dims(1) ! Number of processes along p num_procs_ky = dims(2) ! Number of processes along kx num_procs_z = dims(3) ! Number of processes along z ! !periodicity in p periods(1)=.FALSE. !periodicity in ky periods(2)=.FALSE. !periodicity in z periods(3)=.TRUE. CALL MPI_CART_CREATE(MPI_COMM_WORLD, ndims, dims, periods, reorder, comm0, ierr) CALL MPI_COMM_GROUP(comm0,group0, ierr) CALL MPI_COMM_RANK(comm0, rank_0, ierr) CALL MPI_CART_COORDS(comm0,rank_0,ndims,coords,ierr) ! ! Partitions 3-dim cartesian topology of comm0 into 1-dim cartesian subgrids ! CALL MPI_CART_SUB (comm0, (/.TRUE.,.FALSE.,.FALSE./), comm_p, ierr) CALL MPI_CART_SUB (comm0, (/.FALSE.,.TRUE.,.FALSE./), comm_ky, ierr) CALL MPI_CART_SUB (comm0, (/.FALSE.,.FALSE.,.TRUE./), comm_z, ierr) ! Find id inside the 1d-sub communicators CALL MPI_COMM_RANK(comm_p, rank_p, ierr) CALL MPI_COMM_RANK(comm_ky, rank_ky, ierr) CALL MPI_COMM_RANK(comm_z, rank_z, ierr) ! 2D communicator CALL MPI_CART_SUB (comm0, (/.TRUE.,.FALSE.,.TRUE./), comm_pz, ierr) CALL MPI_CART_SUB (comm0, (/.FALSE.,.TRUE.,.TRUE./), comm_kyz, ierr) ! Count the number of processes in 2D comms CALL MPI_COMM_SIZE(comm_pz, num_procs_pz, ierr) CALL MPI_COMM_SIZE(comm_kyz,num_procs_kyz,ierr) ! Find id inside the 1d-sub communicators CALL MPI_COMM_RANK(comm_pz, rank_pz, ierr) CALL MPI_COMM_RANK(comm_kyz, rank_kyz, ierr) ! Find neighbours CALL MPI_CART_SHIFT(comm0, 0, 1, nbr_L, nbr_R, ierr) !left right neighbours CALL MPI_CART_SHIFT(comm0, 1, 1, nbr_B, nbr_T, ierr) !bottom top neighbours CALL MPI_CART_SHIFT(comm0, 2, 1, nbr_D, nbr_U, ierr) !down up neighbours ! Create the communicator for groups used in gatherv ! CALL MPI_COMM_GROUP(comm0,group_ky0) ! ALLOCATE(rank2include(0:num_procs_ky)) ! DO r_ = 0,rank_0 ! IF(rank_y .EQ. 0) & ! rank2exclude ! ENDDO ! CALL MPI_COMM_CREATE_GROUPE(comm0, group_p0, comm_ky0) END SUBROUTINE ppinit