module mpiset
  
  use mpi
  
  implicit none
  
  integer, save :: nprocs, myrank
  
  
  interface mpii_isend
    module procedure &
      mpii_isend_dble_2d, &
      mpii_isend_dble_3d
  end interface

  interface mpii_irecv
    module procedure &
      mpii_irecv_dble_2d, &
      mpii_irecv_dble_3d
  end interface


    !**************************************************************************

  contains

    !**************************************************************************

    subroutine mpii_init


      !
      ! local variables
      !
      integer :: ierr


      call mpi_init( ierr )
      call mpi_comm_size( mpi_comm_world, nprocs, ierr )
      call mpi_comm_rank( mpi_comm_world, myrank, ierr )


    end subroutine mpii_init

    !**************************************************************************

    subroutine mpii_end


      !
      ! local variables
      !
      integer :: ierr


      call mpi_finalize( ierr )


    end subroutine mpii_end

    !**************************************************************************

    !**************************************************************************

    subroutine mpii_wait( ireq )


      integer, intent(in) :: ireq


      !
      ! local variables
      !
      integer :: ierr
      integer :: istatus( MPI_STATUS_SIZE )


      call mpi_wait( ireq, istatus, ierr )


    end subroutine mpii_wait

    !**************************************************************************

    subroutine mpii_isend_dble_2d( idest, im, jm, buf, ireq )


      integer, intent(in ) :: idest
      integer, intent(in ) :: im, jm
      real(8)    , intent(in ) :: buf( im, jm )
      integer, intent(out) :: ireq


      !
      ! local variables
      !
      integer :: ierr
      integer :: isize


      isize = size( buf )

      call mpi_isend( buf, isize, &
           mpi_double_precision, idest, 1, mpi_comm_world, &
           ireq, ierr )


    end subroutine mpii_isend_dble_2d

    !**************************************************************************

    subroutine mpii_irecv_dble_2d( idep, im, jm, buf, ireq )


      integer, intent(in ) :: idep
      integer, intent(in ) :: im, jm
      real(8)    , intent(out) :: buf( im, jm )
      integer, intent(out) :: ireq


      !
      ! local variables
      !
      integer :: ierr
      integer :: isize


      isize = size( buf )

      call mpi_irecv( buf, isize, &
           mpi_double_precision, idep, 1, mpi_comm_world, &
           ireq, ierr )


    end subroutine mpii_irecv_dble_2d

    !**************************************************************************

    subroutine mpii_isend_dble_3d( idest, im, jm, km, buf, ireq )


      integer, intent(in ) :: idest
      integer, intent(in ) :: im, jm, km
      real(8)    , intent(in ) :: buf( im, jm, km )
      integer, intent(out) :: ireq


      !
      ! local variables
      !
      integer :: ierr
      integer :: isize


      isize = size( buf )

      call mpi_isend( buf, isize, &
           mpi_double_precision, idest, 1, mpi_comm_world, &
           ireq, ierr )


    end subroutine mpii_isend_dble_3d

    !**************************************************************************

    subroutine mpii_irecv_dble_3d( idep, im, jm, km, buf, ireq )


      integer, intent(in ) :: idep
      integer, intent(in ) :: im, jm, km
      real(8)    , intent(out) :: buf( im, jm, km )
      integer, intent(out) :: ireq


      !
      ! local variables
      !
      integer :: ierr
      integer :: isize


      isize = size( buf )

      call mpi_irecv( buf, isize, &
           mpi_double_precision, idep, 1, mpi_comm_world, &
           ireq, ierr )


    end subroutine mpii_irecv_dble_3d

    !**************************************************************************

  end module mpiset
