!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSEND2DEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpsend2dew(var,nx,ny,nz,ebc,wbc,stagdim,mptag,tem) 68,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send east/west boundary data between processors to update the fake
!  zones.  Fake zone update is completed with a call to MPRECV2DEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v);
!              =3, staggered in the z-direction (e.g. w).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v);
                               !  =3, staggered in the z-direction (e.g. w).
  REAL :: var(nx,ny,nz)
  REAL :: tem((nx+ny)*nz)      ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k
  INTEGER :: si,sj,sk

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  sk = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1
  IF (stagdim == 3) sk = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        tem(j+ny*(k-1)) = var(nx-2,j,k)
      END DO
    END DO

    CALL mpi_send(tem,ny*nz,mpi_real,                                   &
        proc(loc_x+1+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, imstat)
    !wdt forced buffering
    !CALL mpi_bsend(tem,ny*nz,mpi_real,                                   &
    !    proc(loc_x+1+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_w, mpi_comm_world, imstat)

  ELSE IF(ebc == 2) THEN

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        tem(j+ny*(k-1)) = var(nx-2,j,k)
      END DO
    END DO

    CALL mpi_send(tem,ny*nz,mpi_real,proc(1+nproc_x*(loc_y-1)),         &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny*nz,mpi_real,proc(1+nproc_x*(loc_y-1)),         &
    !    mptag+tag_w, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        tem(j+ny*(k-1)) = var(2+si,j,k)
      END DO
    END DO

    CALL mpi_send(tem,ny*nz,mpi_real,                                   &
        proc(loc_x-1+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny*nz,mpi_real,                                   &
    !    proc(loc_x-1+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_e, mpi_comm_world, imstat)

  ELSE IF(wbc == 2) THEN

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        tem(j+ny*(k-1)) = var(2+si,j,k)
      END DO
    END DO

    CALL mpi_send(tem,ny*nz,mpi_real,                                   &
        proc(nproc_x+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, imstat)
    !wdt forced buffering
    !CALL mpi_bsend(tem,ny*nz,mpi_real,                                   &
    !    proc(nproc_x+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_e, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend2dew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECV2DEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv2dew(var,nx,ny,nz,ebc,wbc,stagdim,mptag,tem) 68
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive east/west boundary data between processors to update the fake
!  zones.  Fake zone updates are initiated with a call to MPSEND2DEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v);
!              =3, staggered in the z-direction (e.g. w).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v);
                               !  =3, staggered in the z-direction (e.g. w).
  REAL :: var(nx,ny,nz)
  REAL :: tem((nx+ny)*nz)      ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k
  INTEGER :: si,sj,sk

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  sk = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1
  IF (stagdim == 3) sk = 1

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    CALL mpi_recv(tem,ny*nz,mpi_real,                                   &
        proc(loc_x-1+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        var(1,j,k) = tem(j+ny*(k-1))
      END DO
    END DO

  ELSE IF(wbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny*nz,mpi_real,                                   &
        proc(nproc_x+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        var(1,j,k) = tem(j+ny*(k-1))
      END DO
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    CALL mpi_recv(tem,ny*nz,mpi_real,                                   &
        proc(loc_x+1+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        var(nx-1+si,j,k) = tem(j+ny*(k-1))
      END DO
    END DO

  ELSE IF(ebc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny*nz,mpi_real,proc(1+nproc_x*(loc_y-1)),         &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO j=1,ny-1+sj
        var(nx-1+si,j,k) = tem(j+ny*(k-1))
      END DO
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv2dew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSEND2DNS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsend2dns(var,nx,ny,nz,nbc,sbc,stagdim,mptag,tem) 68,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send north/south boundary data between processors to update the
!  fake zones.  Fake zone update is completed with a call to MPRECV2DNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v);
!              =3, staggered in the z-direction (e.g. w).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v);
                               !  =3, staggered in the z-direction (e.g. w).
  REAL :: var(nx,ny,nz)
  REAL :: tem((nx+ny)*nz)      ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k
  INTEGER :: si,sj,sk

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  sk = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1
  IF (stagdim == 3) sk = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        tem(i+nx*(k-1)) = var(i,2+sj,k)
      END DO
    END DO

    CALL mpi_send(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),     &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),     &
    !    mptag+tag_n, mpi_comm_world, imstat)

  ELSE IF(sbc == 2) THEN

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        tem(i+nx*(k-1)) = var(i,2+sj,k)
      END DO
    END DO

    CALL mpi_send(tem,nx*nz,mpi_real,                                   &
        proc(loc_x+nproc_x*(nproc_y-1)),                                &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx*nz,mpi_real,                                   &
    !    proc(loc_x+nproc_x*(nproc_y-1)),                                &
    !    mptag+tag_n, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        tem(i+nx*(k-1)) = var(i,ny-2,k)
      END DO
    END DO

    CALL mpi_send(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*loc_y),         &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*loc_y),         &
    !    mptag+tag_s, mpi_comm_world, imstat)

  ELSE IF(nbc == 2) THEN

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        tem(i+nx*(k-1)) = var(i,ny-2,k)
      END DO
    END DO

    CALL mpi_send(tem,nx*nz,mpi_real,proc(loc_x),                       &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx*nz,mpi_real,proc(loc_x),                       &
    !    mptag+tag_s, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend2dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECV2DNS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv2dns(var,nx,ny,nz,nbc,sbc,stagdim,mptag,tem) 68
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive north/south boundary data between processors to update the
!  fake zones.  Fake zone updates are initiated with a call to MPSEND2DNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v);
!              =3, staggered in the z-direction (e.g. w).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v);
                               !  =3, staggered in the z-direction (e.g. w).
  REAL :: var(nx,ny,nz)
  REAL :: tem((nx+ny)*nz)      ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k
  INTEGER :: si,sj,sk

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  sk = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1
  IF (stagdim == 3) sk = 1

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    CALL mpi_recv(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*loc_y),         &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        var(i,ny-1+sj,k) = tem(i+nx*(k-1))
      END DO
    END DO

  ELSE IF(nbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,nx*nz,mpi_real,proc(loc_x),                       &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)


    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        var(i,ny-1+sj,k) = tem(i+nx*(k-1))
      END DO
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    CALL mpi_recv(tem,nx*nz,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),     &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)

    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        var(i,1,k) = tem(i+nx*(k-1))
      END DO
    END DO

  ELSE IF(sbc == 2) THEN

    CALL mpi_recv(tem,nx*nz,mpi_real,                                   &
        proc(loc_x+nproc_x*(nproc_y-1)),                                &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)


    DO k=1,nz-1+sk
      DO i=1,nx-1+si
        var(i,1,k) = tem(i+nx*(k-1))
      END DO
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv2dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSEND1DEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsend1dew(var,nx,ny,ebc,wbc,stagdim,mptag,tem) 22,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send east/west boundary data between processors to update the fake
!  zones.  Fake zone update is completed with a call to MPRECV1DEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x and y
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  REAL :: var(nx,ny)
  REAL :: tem(nx+ny)           ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    DO j=1,ny-1+sj
      tem(j) = var(nx-2,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
    !    mptag+tag_w, mpi_comm_world, imstat)

  ELSE IF(ebc == 2) THEN

    DO j=1,ny-1+sj
      tem(j) = var(nx-2,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
    !    mptag+tag_w, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    DO j=1,ny-1+sj
      tem(j) = var(2+si,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
    !    mptag+tag_e, mpi_comm_world, imstat)

  ELSE IF(wbc == 2) THEN

    DO j=1,ny-1+sj
      tem(j) = var(2+si,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
    !    mptag+tag_e, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend1dew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECV1DEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv1dew(var,nx,ny,ebc,wbc,stagdim,mptag,tem) 22
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send east/west boundary data between processors to update the fake
!  zones.  Fake zone updates are initiated with a call to MPSEND1DEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x, and y
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  REAL :: var(nx,ny)
  REAL :: tem(nx+ny)           ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    CALL mpi_recv(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)

    DO j=1,ny-1+sj
      var(1,j) = tem(j)
    END DO

  ELSE IF(wbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)


    DO j=1,ny-1+sj
      var(1,j) = tem(j)
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    CALL mpi_recv(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO j=1,ny-1+sj
      var(nx-1+si,j) = tem(j)
    END DO

  ELSE IF(ebc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)


    DO j=1,ny-1+sj
      var(nx-1+si,j) = tem(j)
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv1dew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSEND1DNS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsend1dns(var,nx,ny,nbc,sbc,stagdim,mptag,tem) 22,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send north/south boundary data between processors to update the
!  fake zones.  Fake zone update is completed with a call to MPRECV1DNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x and y
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  REAL :: var(nx,ny)
  REAL :: tem(nx+ny)           ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,2+sj)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
    !    mptag+tag_n, mpi_comm_world, imstat)

  ELSE IF(sbc == 2) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,2+sj)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
    !    mptag+tag_n, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,ny-2)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
    !    mptag+tag_s, mpi_comm_world, imstat)

  ELSE IF(nbc == 2) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,ny-2)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x),                          &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x),                          &
    !    mptag+tag_s, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend1dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECV1DNS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv1dns(var,nx,ny,nbc,sbc,stagdim,mptag,tem) 22
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send north/south boundary data between processors to update the
!  fake zones.  Fake zone updates are initiated with a call to MPSEND1DNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/18
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x, and y
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  REAL :: var(nx,ny)
  REAL :: tem(nx+ny)           ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)

    DO i=1,nx-1+si
      var(i,ny-1+sj) = tem(i)
    END DO

  ELSE IF(nbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x),                          &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)


    DO i=1,nx-1+si
      var(i,ny-1+sj) = tem(i)
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)

    DO i=1,nx-1+si
      var(i,1) = tem(i)
    END DO

  ELSE IF(sbc == 2) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)


    DO i=1,nx-1+si
      var(i,1) = tem(i)
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv1dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######               SUBROUTINE MPSEND1DIEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsend1diew(var,nx,ny,ebc,wbc,stagdim,mptag,tem) 2,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send east/west boundary data between processors to update the fake zones.
!  Fake zone update is completed with a call to MPRECV1DIEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x and y
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  INTEGER :: var(nx,ny)
  INTEGER :: tem(nx+ny)        ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    DO j=1,ny-1+sj
      tem(j) = var(nx-2,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
    !    mptag+tag_w, mpi_comm_world, imstat)

  ELSE IF(ebc == 2) THEN

    DO j=1,ny-1+sj
      tem(j) = var(nx-2,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
    !    mptag+tag_w, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    DO j=1,ny-1+sj
      tem(j) = var(2+si,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
    !    mptag+tag_e, mpi_comm_world, imstat)

  ELSE IF(wbc == 2) THEN

    DO j=1,ny-1+sj
      tem(j) = var(2+si,j)
    END DO

    CALL mpi_send(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
    !    mptag+tag_e, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend1diew
!
!##################################################################
!##################################################################
!######                                                      ######
!######               SUBROUTINE MPRECV1DIEW                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv1diew(var,nx,ny,ebc,wbc,stagdim,mptag,tem) 2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive east/west boundary data between processors to update the fake zones.
!  Fake zone updates are initiated with a call to MPSEND1DIEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x, and y
                               ! directions
  INTEGER :: ebc,wbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  INTEGER :: var(nx,ny)
  INTEGER :: tem(nx+ny)        ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    CALL mpi_recv(tem,ny,mpi_real,proc(loc_x-1+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)

    DO j=1,ny-1+sj
      var(1,j) = tem(j)
    END DO

  ELSE IF(wbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny,mpi_real,proc(nproc_x+nproc_x*(loc_y-1)),      &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)


    DO j=1,ny-1+sj
      var(1,j) = tem(j)
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    CALL mpi_recv(tem,ny,mpi_real,proc(loc_x+1+nproc_x*(loc_y-1)),      &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO j=1,ny-1+sj
      var(nx-1+si,j) = tem(j)
    END DO

  ELSE IF(ebc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,ny,mpi_real,proc(1+nproc_x*(loc_y-1)),            &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)


    DO j=1,ny-1+sj
      var(nx-1+si,j) = tem(j)
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv1diew
!
!##################################################################
!##################################################################
!######                                                      ######
!######               SUBROUTINE MPSEND1DINS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsend1dins(var,nx,ny,nbc,sbc,stagdim,mptag,tem) 2,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send north/south boundary data between processors to update the fake zones.
!  Fake zone update is completed with a call to MPRECV1DINS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x and y
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  INTEGER :: var(nx,ny)
  INTEGER :: tem(nx+ny)        ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,2+sj)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
    !    mptag+tag_n, mpi_comm_world, imstat)

  ELSE IF(sbc == 2) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,2+sj)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
    !    mptag+tag_n, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,ny-2)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
    !    mptag+tag_s, mpi_comm_world, imstat)

  ELSE IF(nbc == 2) THEN

    DO i=1,nx-1+si
      tem(i) = var(i,ny-2)
    END DO

    CALL mpi_send(tem,nx,mpi_real,proc(loc_x),                          &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,nx,mpi_real,proc(loc_x),                          &
    !    mptag+tag_s, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsend1dins
!
!##################################################################
!##################################################################
!######                                                      ######
!######               SUBROUTINE MPRECV1DINS                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecv1dins(var,nx,ny,nbc,sbc,stagdim,mptag,tem) 2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive north/south boundary data between processors to update the 
!  fake zones.  Fake zone updates are initiated with a call to MPSEND1DINS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    stagdim  Dimension of grid staggering:
!              =0, no staggering;
!              =1, staggered in the x-direction (e.g. u);
!              =2, staggered in the y-direction (e.g. v).
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny             ! Number of grid points in x, and y
                               ! directions
  INTEGER :: nbc,sbc
  INTEGER :: stagdim           ! Dimension of grid staggering:
                               !  =0, no staggering;
                               !  =1, staggered in the x-direction (e.g. u);
                               !  =2, staggered in the y-direction (e.g. v).
  INTEGER :: var(nx,ny)
  INTEGER :: tem(nx+ny)        ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j
  INTEGER :: si,sj

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  si = 0
  sj = 0
  IF (stagdim == 1) si = 1
  IF (stagdim == 2) sj = 1

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*loc_y),            &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)

    DO i=1,nx-1+si
      var(i,ny-1+sj) = tem(i)
    END DO

  ELSE IF(nbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x),                          &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)


    DO i=1,nx-1+si
      var(i,ny-1+sj) = tem(i)
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*(loc_y-2)),        &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)

    DO i=1,nx-1+si
      var(i,1) = tem(i)
    END DO

  ELSE IF(sbc == 2) THEN

    CALL mpi_recv(tem,nx,mpi_real,proc(loc_x+nproc_x*(nproc_y-1)),      &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)


    DO i=1,nx-1+si
      var(i,1) = tem(i)
    END DO

  END IF

  RETURN
END SUBROUTINE mprecv1dins
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSENDEXTEW                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsendextew(var,nx,ny,nz,ebc,wbc,mptag,tem) 1,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send east/west boundary data between processors to update the fake zones
!  for and extended array which has two instead of one fake zones
!  on each boundary (arrays run from 0:nx,0:ny,0:nz).
!  Fake zone update is completed with a call to MPRECVEXTEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: ebc,wbc
  REAL :: var(0:nx,0:ny,0:nz)
  REAL :: tem((nx+ny+1)*(nz+1)) ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    DO k=0,nz
      DO j=0,ny
        tem(j+1+(ny+1)*k) = var(nx-3,j,k)
      END DO
    END DO

    CALL mpi_send(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(loc_x+1+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(ny+1)*(nz+1),mpi_real,  &
    !    proc(loc_x+1+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_w, mpi_comm_world, imstat)

  ELSE IF(ebc == 2) THEN

    DO k=0,nz
      DO j=0,ny
        tem(j+1+(ny+1)*k) = var(nx-3,j,k)
      END DO
    END DO

    CALL mpi_send(tem,(ny+1)*(nz+1),mpi_real,proc(1+nproc_x*(loc_y-1)),  &
        mptag+tag_w, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(ny+1)*(nz+1),mpi_real,proc(1+nproc_x*(loc_y-1)),  &
    !    mptag+tag_w, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    DO k=0,nz
      DO j=0,ny
        tem(j+1+(ny+1)*k) = var(3,j,k)
      END DO
    END DO

    CALL mpi_send(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(loc_x-1+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(ny+1)*(nz+1),mpi_real,  &
    !    proc(loc_x-1+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_e, mpi_comm_world, imstat)

  ELSE IF(wbc == 2) THEN

    DO k=0,nz
      DO j=0,ny
        tem(j+1+(ny+1)*k) = var(3,j,k)
      END DO
    END DO

    CALL mpi_send(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(nproc_x+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(ny+1)*(nz+1),mpi_real,  &
    !    proc(nproc_x+nproc_x*(loc_y-1)),                                &
    !    mptag+tag_e, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsendextew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECVEXTEW                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecvextew(var,nx,ny,nz,ebc,wbc,mptag,tem) 1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive east/west boundary data between processors to update the fake zones
!  for and extended array which has two instead of one fake zones
!  on each boundary (arrays run from 0:nx,0:ny,0:nz).
!  Fake zone updates are initiated with a call to MPSENDEXTEW.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    ebc      East boundary condition
!    wbc      West boundary condition
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: ebc,wbc
  REAL :: var(0:nx,0:ny,0:nz)
  REAL :: tem((nx+ny+1)*(nz+1)) ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!-----------------------------------------------------------------------
!
!  Set the west boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= 1) THEN

    CALL mpi_recv(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(loc_x-1+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)

    DO k=0,nz
      DO j=0,ny
        var(0,j,k) = tem(j+1+(ny+1)*k)
      END DO
    END DO

  ELSE IF(wbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(nproc_x+nproc_x*(loc_y-1)),                                &
        mptag+tag_w, mpi_comm_world, mpi_status, imstat)


    DO k=0,nz
      DO j=0,ny
        var(0,j,k) = tem(j+1+(ny+1)*k)
      END DO
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the east boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_x /= nproc_x) THEN

    CALL mpi_recv(tem,(ny+1)*(nz+1),mpi_real,  &
        proc(loc_x+1+nproc_x*(loc_y-1)),                                &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO k=0,nz
      DO j=0,ny
        var(nx,j,k) = tem(j+1+(ny+1)*k)
      END DO
    END DO

  ELSE IF(ebc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,(ny+1)*(nz+1),mpi_real,proc(1+nproc_x*(loc_y-1)),  &
        mptag+tag_e, mpi_comm_world, mpi_status, imstat)

    DO k=0,nz
      DO j=0,ny
        var(nx,j,k) = tem(j+1+(ny+1)*k)
      END DO
    END DO

  END IF

  RETURN
END SUBROUTINE mprecvextew
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPSENDEXTNS                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpsendextns(var,nx,ny,nz,nbc,sbc,mptag,tem) 1,1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Send north/south boundary data between processors to update the fake zones
!  for and extended array which has two instead of one fake zones
!  on each boundary (arrays run from 0:nx,0:ny,0:nz).
!  Fake zone update is completed with a call to MPRECVEXTNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    tem      Work array.
!
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: nbc,sbc
  REAL :: var(0:nx,0:ny,0:nz)
  REAL :: tem((nx+ny+1)*(nz+1)) ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    DO k=0,nz
      DO i=0,nx
        tem(i+1+(nx+1)*k) = var(i,3,k)
      END DO
    END DO

    CALL mpi_send(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*(loc_y-2)),  &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*(loc_y-2)),  &
    !    mptag+tag_n, mpi_comm_world, imstat)

  ELSE IF(sbc == 2) THEN

    DO k=0,nz
      DO i=0,nx
        tem(i+1+(nx+1)*k) = var(i,3,k)
      END DO
    END DO

    CALL mpi_send(tem,(nx+1)*(nz+1),mpi_real,  &
        proc(loc_x+nproc_x*(nproc_y-1)),                                &
        mptag+tag_n, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(nx+1)*(nz+1),mpi_real,  &
    !    proc(loc_x+nproc_x*(nproc_y-1)),                                &
    !    mptag+tag_n, mpi_comm_world, imstat)

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    DO k=0,nz
      DO i=0,nx
        tem(i+1+(nx+1)*k) = var(i,ny-3,k)
      END DO
    END DO

    CALL mpi_send(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*loc_y),  &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*loc_y),  &
    !    mptag+tag_s, mpi_comm_world, imstat)

  ELSE IF(nbc == 2) THEN

    DO k=0,nz
      DO i=0,nx
        tem(i+1+(nx+1)*k) = var(i,ny-3,k)
      END DO
    END DO

    CALL mpi_send(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x),  &
        mptag+tag_s, mpi_comm_world, imstat)

    !wdt forced buffering
    !CALL mpi_bsend(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x),  &
    !    mptag+tag_s, mpi_comm_world, imstat)

  END IF

  RETURN
END SUBROUTINE mpsendextns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPRECVEXTNS                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mprecvextns(var,nx,ny,nz,nbc,sbc,mptag,tem) 1
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Receive north/south boundary data between processors to update the fake
!  zones for and extended array which has two instead of one fake zones
!  on each boundary (arrays run from 0:nx,0:ny,0:nz).
!  Fake zone updates are initiated with a call to MPSENDEXTNS.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/09/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable for which boundaries need updating.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    nbc      North boundary condition
!    sbc      South boundary condition
!
!    mptag     Unique MPI id used for this BC update.
!
!    tem      Work array.
!
!  OUTPUT:
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: nbc,sbc
  REAL :: var(0:nx,0:ny,0:nz)
  REAL :: tem((nx+ny+1)*(nz+1)) ! Work array.

  INTEGER :: mptag             ! Unique MPI id used for this BC update.

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!-----------------------------------------------------------------------
!
!  Set the north boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= nproc_y) THEN

    CALL mpi_recv(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*loc_y),  &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)

    DO k=0,nz
      DO i=0,nx
        var(i,ny,k) = tem(i+1+(nx+1)*k)
      END DO
    END DO

  ELSE IF(nbc == 2) THEN         ! Periodic boundary condition.

    CALL mpi_recv(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x),  &
        mptag+tag_n, mpi_comm_world, mpi_status, imstat)


    DO k=0,nz
      DO i=0,nx
        var(i,ny,k) = tem(i+1+(nx+1)*k)
      END DO
    END DO

  END IF

!-----------------------------------------------------------------------
!
!  Set the south boundary conditions
!
!-----------------------------------------------------------------------

  IF(loc_y /= 1) THEN

    CALL mpi_recv(tem,(nx+1)*(nz+1),mpi_real,proc(loc_x+nproc_x*(loc_y-2)),  &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)

    DO k=0,nz
      DO i=0,nx
        var(i,0,k) = tem(i+1+(nx+1)*k)
      END DO
    END DO

  ELSE IF(sbc == 2) THEN

    CALL mpi_recv(tem,(nx+1)*(nz+1),mpi_real,  &
        proc(loc_x+nproc_x*(nproc_y-1)),                                &
        mptag+tag_s, mpi_comm_world, mpi_status, imstat)


    DO k=0,nz
      DO i=0,nx
        var(i,0,k) = tem(i+1+(nx+1)*k)
      END DO
    END DO

  END IF

  RETURN
END SUBROUTINE mprecvextns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPUPDATER                  ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpupdater(var,num) 611
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Broadcast the value of var from process 0 to all other processes.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/24
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT/OUTPUT :
!
!    var      Array to update (INPUT on proc 0, OUTPUT for rest).
!    num      Number of elements in the array.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: num
  REAL :: var(num)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: imstat

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL mpi_bcast(var,num,mpi_real,0,mpi_comm_world,imstat)
  IF (imstat /= 0) THEN
    WRITE (6,*) "MPUPDATER: error on processor",myproc
  END IF

  RETURN
END SUBROUTINE mpupdater
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPUPDATEI                  ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpupdatei(var,num) 1162
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Broadcast the value of var from process 0 to all other processes.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/24
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT/OUTPUT :
!
!    var      Variable to update (INPUT on proc 0, OUTPUT for rest).
!    num      Number of elements in the array.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: num
  INTEGER :: var(num)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: imstat

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL mpi_bcast(var,num,mpi_integer,0,mpi_comm_world,imstat)
  IF (imstat /= 0) THEN
    WRITE (6,*) "MPUPDATEI: error on processor",myproc
  END IF

  RETURN
END SUBROUTINE mpupdatei
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPUPDATEC                  ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpupdatec(str,lenstr) 45
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Broadcast the string str from process 0 to all other processes.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Gene Bassett
!  2000/04/24
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT/OUTPUT :
!
!    str      String to update (INPUT on proc 0, OUTPUT for rest).
!    lenstr   Length of str.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: lenstr
  CHARACTER (LEN=lenstr) :: str

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: imstat

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL mpi_bcast(str,lenstr,mpi_character,0,mpi_comm_world,imstat)
  IF (imstat /= 0) THEN
    WRITE (6,*) "MPUPDATEC: error on processor",myproc
  END IF

  RETURN
END SUBROUTINE mpupdatec

 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!     Miscellaneous MPI subroutines (not in ARPS standard format)
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


SUBROUTINE mpexit(errcode) 9

  IMPLICIT NONE

  INCLUDE 'mpif.h'
  INTEGER :: errcode
  INTEGER :: imstat

  IF (errcode == 0) THEN
    CALL mpi_finalize (imstat)
  ELSE
    CALL mpi_abort (mpi_comm_world, errcode, imstat)
  ENDIF

  RETURN
END SUBROUTINE mpexit



SUBROUTINE inctag 33

  IMPLICIT NONE

  INCLUDE 'mp.inc'

  IF (gentag < 100 .OR. gentag > 60000) gentag = 100
  gentag = gentag + 100

  RETURN
END SUBROUTINE inctag



SUBROUTINE mpbarrier 48

  INCLUDE 'mpif.h'
  INTEGER :: imstat

  CALL mpi_barrier (mpi_comm_world, imstat)

  RETURN
END SUBROUTINE mpbarrier




SUBROUTINE mptotal(var) 14

  IMPLICIT NONE

  INCLUDE 'mpif.h'

  REAL :: var, vartm
  INTEGER :: i,j,imstat

  CALL mpi_allreduce (var, vartm, 1, mpi_real, mpi_sum,                 &
       mpi_comm_world, imstat)

  var = vartm

  RETURN
END SUBROUTINE mptotal

!  subroutine mpmax0(amax,amin)

!  implicit none

!  include 'mpif.h'
!  include 'par.inc'

!  real amin, amax
!  real amintm, amaxtm

!  call mpi_allreduce (amax, amaxtm, 1, MPI_REAL, MPI_MAX,
!    :     MPI_COMM_WORLD, imstat)

!  amax = amaxtm

!  call mpi_allreduce (amin, amintm, 1, MPI_REAL, MPI_MIN,
!    :     MPI_COMM_WORLD, imstat)

!  amin = amintm

!  return
!  end



SUBROUTINE mpmax0(amax,amin) 9

!
!  Modified by Dan Weber, May 4, 1998
!  Replaces code above for use on t3d/t3e system.
!  mpi_allreduce is not working properly...
!
  IMPLICIT NONE

  INTEGER :: itema,itemb
  REAL :: amax,amin
  INTEGER :: imstat

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'

  REAL :: maxtm, mintm
!
!    start of executable code....
!

!  CALL mpi_allreduce (amax, maxtm, 1, MPI_REAL, MPI_MAX,
!    :     MPI_COMM_WORLD, imstat)  ! commented out because the T3E
                                 ! has trouble with mpi_allreduce
  CALL mpi_reduce(amax,maxtm,1,mpi_real,mpi_max,0,                      &
                  mpi_comm_world,imstat)
  CALL mpi_bcast(maxtm,1,mpi_real,0,mpi_comm_world,imstat)

  amax = maxtm

!  CALL mpi_allreduce (amin, mintm, 1, MPI_REAL, MPI_MIN,
!    :     MPI_COMM_WORLD, imstat)  ! commented out because the T3E
                                 ! has trouble with mpi_allreduce
  CALL mpi_reduce(amin,mintm,1,mpi_real,mpi_min,0,                      &
                  mpi_comm_world,imstat)
  CALL mpi_bcast(mintm,1,mpi_real,0,mpi_comm_world,imstat)

  amin = mintm

  RETURN
END SUBROUTINE mpmax0


SUBROUTINE mpmax(amax,amin,nx,ny,nz,imax,jmax,kmax,imin,jmin,kmin) 1,1

!
!  Modified by Dan Weber, October 23, 1997
!

  IMPLICIT NONE

  INTEGER :: nx,ny,nz,imax,jmax,kmax,imin,jmin,kmin,itema,itemb
  REAL :: amax,amin
  INTEGER :: imstat

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  INTEGER :: mpi_status(mpi_status_size)
  REAL :: maxarr (2), minarr(2)
  REAL :: maxtm  (2), mintm(2)
  INTEGER :: maxpack (3), maxunpack(3)
  INTEGER :: minpack (3), minunpack(3)

!
!    start of executable code....
!

  CALL inctag
  maxtm(1) = 0.0
  maxtm(2) = 0.0
  maxarr(1) = amax
  maxarr(2) = FLOAT(myproc)
!  CALL mpi_allreduce (maxarr, maxtm, 1, MPI_2REAL, MPI_MAXLOC,
!    :     MPI_COMM_WORLD, imstat)  ! commented out because the T3E
                                 ! has trouble with mpi_allreduce
  CALL mpi_reduce(maxarr,maxtm,1,mpi_2real,mpi_maxloc,0,                &
                  mpi_comm_world,imstat)
  CALL mpi_bcast(maxtm,1,mpi_2real,0,                                   &
                 mpi_comm_world,imstat)

  itema = nint(maxtm(2))
  IF(myproc == itema.AND.itema /= 0)THEN    ! send only if
    maxpack(1) = imax + (nx-3)*(loc_x-1)  ! itema .ne. myproc=0!!!
    maxpack(2) = jmax + (ny-3)*(loc_y-1)
    maxpack(3) = kmax
    CALL mpi_send (maxpack,3,mpi_integer,0,                             &
                   gentag,mpi_comm_world,imstat)
    !wdt forced buffering
    !CALL mpi_bsend (maxpack,3,mpi_integer,0,                             &
    !               gentag,mpi_comm_world,imstat)

  END IF

  IF(myproc == 0.AND.myproc /= itema)THEN ! receive only if
                                          ! itema .ne. myproc=0
    CALL mpi_recv (maxunpack,3,mpi_integer,itema,                       &
                   gentag,mpi_comm_world,mpi_status,imstat)
    imax = maxunpack(1)
    jmax = maxunpack(2)
    kmax = maxunpack(3)
    amax = maxtm(1)
  END IF


  mintm(1) = 0.0
  mintm(2) = 0.0
  minarr(1) = amin
  minarr(2) = FLOAT(myproc)

!  CALL mpi_allreduce (minarr, mintm, 1, MPI_2REAL, MPI_MINLOC,
!    :     MPI_COMM_WORLD, imstat)  ! commented out because the T3E
                                 ! has trouble with mpi_allreduce
  CALL mpi_reduce(minarr,mintm,1,mpi_2real,mpi_minloc,0,                &
                  mpi_comm_world,imstat)
  CALL mpi_bcast(mintm,1,mpi_2real,0,                                   &
                 mpi_comm_world,imstat)

  itemb = nint(mintm(2))
  IF(myproc == itemb.AND.itemb /= 0)THEN    ! send only if
    minpack(1) = imin + (nx-3)*(loc_x-1)  ! itema .ne. myproc=0!!!
    minpack(2) = jmin + (ny-3)*(loc_y-1)
    minpack(3) = kmin
    CALL mpi_send (minpack,3,mpi_integer,0,                             &
                     gentag+1,mpi_comm_world,imstat)
    !wdt forced buffering
    !CALL mpi_bsend (minpack,3,mpi_integer,0,                             &
    !                 gentag+1,mpi_comm_world,imstat)
  END IF

  IF(myproc == 0.AND.myproc /= itemb)THEN ! receive only if
                                          ! itemb .ne. myproc=0
    CALL mpi_recv (minunpack,3,mpi_integer,itemb,                       &
                     gentag+1,mpi_comm_world,mpi_status,imstat)
    imin = minunpack(1)
    jmin = minunpack(2)
    kmin = minunpack(3)
    amin = mintm(1)
  END IF

  RETURN
END SUBROUTINE mpmax


SUBROUTINE mpinit_proc 3

  IMPLICIT NONE

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  INTEGER :: imstat

  mp_opt = 1

  CALL mpi_init( imstat )

  CALL mpi_comm_rank( mpi_comm_world, myproc, imstat )

  RETURN
END SUBROUTINE mpinit_proc


SUBROUTINE mpinit_var 3

  IMPLICIT NONE

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'bndry.inc'
  INCLUDE 'mp.inc'

  INTEGER :: i,j,k,l,numg,parent
  INTEGER :: mytid,nprocs0
  INTEGER :: imstat

  CALL mpi_comm_size( mpi_comm_world, nprocs0, imstat )

  nprocs = nproc_x * nproc_y

  IF(nprocs > max_proc) THEN

    WRITE (6,*) "ERROR: number of processors exceeds maximum ",     &
                "specified in mp.inc:"
    WRITE (6,*) "nprocs =",nprocs
    WRITE (6,*) "max_proc (in mp.inc) =",max_proc
    CALL arpsstop ("arpsstop called from mpinit_var mismatch in   &
                   & number of processors-too many",1)

  END IF

!
!  This subroutine defines the proc(nproc_x+nproc_x*(nproc_y-1)) array
!  and the myproc variable for each process.
!
  IF(nprocs /= nprocs0)THEN  ! test to see if the input file
                             ! number of processors = nprocs
                             ! and set on the command line.
    IF(myproc == 0)THEN
      PRINT *,'Number of processors chosen on the command line '
      PRINT *,'is different from that given in arps.input, EXITING'
      PRINT *,'requested: ', nprocs0
      PRINT *,'in arps.input: ', nprocs, ' = ',nproc_x,' * ',nproc_y
    END IF
    CALL arpsstop ("arpsstop called from mpinit_var mismatch in   &
                   & number of processors",1)

  END IF

  l = 0
  DO j = 1, nproc_y
    DO i = 1, nproc_x
      proc(i+nproc_x*(j-1)) = l
      l = l + 1
    END DO
  END DO

  loc_x = MOD(myproc, nproc_x) + 1
  loc_y = myproc / nproc_x + 1

  gentag = 0

  RETURN
END SUBROUTINE mpinit_var
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE                   ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge(locvar,nx,ny,nz,nt,char1,length,tem1),2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global data files from a multiprocessor run to be compared 
!  with a single processor file.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Dan Weber
!  2001/04/11
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    var      Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!    tem      Work array.
!
!    char1    filename.
!  OUTPUT:
!
!    mptag     Unique MPI id used for this BC update.
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER :: nx,ny,nz          ! Number of grid points in x, y and z
                               ! directions
  INTEGER :: nt
  INTEGER :: length            ! Character string length
  REAL :: locvar(nx,ny,nz,nt)
  REAL :: tem1(nx,ny,nz)

  INTEGER :: mptag             ! Unique MPI id used for this BC update.
  INTEGER :: ia,ja, ic,jc,itemc,itemb,itema,fzone
  CHARACTER*80 :: char1
!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  INTEGER :: stat(mpi_status_size)

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nz)   ! Work array.
  INTEGER :: mpi_status(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k
  INTEGER :: si,sj,sk

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  DO k=1,nz        ! each processor stores the locvar into tem1
    DO j=1,ny
      DO i=1,nx
        tem1(i,j,k) = locvar(i,j,k,nt)
      END DO
    END DO
  END DO
 
  DO jc=1,nproc_y
  DO ic=1,nproc_x

!   message passing section...

    itemb = mptag + 100 + ic + jc
    IF(ic /=1 .or. jc /=1)THEN     !  pass data to processor 0
      IF(myproc.eq.(ic+(jc-1)*nproc_x-1))THEN
      itema = 0 
!     print *,'sending data',itema,itemb,myproc
      call mpi_send (tem1,nx*ny*nz,MPI_REAL,itema,  &
                       itemb,MPI_COMM_WORLD,imstat) 
      !wdt forced buffering
      !call mpi_bsend (tem1,nx*ny*nz,MPI_REAL,itema,  &
      !                 itemb,MPI_COMM_WORLD,imstat) 
      END IF

      itemc = ic+(jc-1)*nproc_x-1
      IF(myproc == 0)THEN            ! receive data
!     print *,'receiving data',itemc,itemb,myproc
        call mpi_recv (tem1,nx*ny*nz,MPI_REAL,itemc,  &
                       itemb,MPI_COMM_WORLD,stat,imstat)
      END IF

    END IF

!  storage section

    IF(myproc == 0)THEN  ! store data into globvar

      DO k=1,nz
        DO j=1,ny
          ja = j + (jc-1)*(ny-fzone)
          DO i=1,nx
            ia = i + (ic-1)*(nx-fzone)
!           print *,ic,jc,ia,ja,i,j,k
            globvar(ia,ja,k) = tem1(i,j,k)
          END DO          
        END DO      
      END DO      

    END IF

    call mpbarrier

  END DO      
  END DO      

  IF(myproc ==0 ) THEN   !  write the file.....

     write(char1(length+1:length+5),'(a5)')  '.form'
!    itemc = 80
!    CALL strlnth(char1,itemc)
!    CALL comlnth(char1,itemc)
!    print *,'inside mpimerge', length,char1(1:length+5)
     open(10,file=char1(1:length+5),form= 'formatted',status='unknown')
     DO k=1,nz
     DO j=1,(ny-3)*nproc_y+3
     DO i=1,(nx-3)*nproc_x+3
     write(10,'(3(i5),2x,g17.11)') i,j,k,globvar(i,j,k)
     END DO
     END DO
     END DO
     close (10)

     write(char1(length+1:length+7),'(a7)')  '.unform'
!    itemc = 80
!    CALL comlnth(char1,itemc)
!    CALL strlnth(char1,itemc)
!    print *,'inside mpimerge', itemc,length,char1(1:itemc)
!    print *,'inside mpimerge', length,char1(1:length+7)
     open(11,file=char1(1:length+7),form= 'unformatted',status='unknown')
     write (11) globvar
     close (11)

  END IF

   RETURN
END SUBROUTINE mpimerge
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE1dx                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge1dx(locvar,nx,globvar) 5,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Dimension of the array
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: nx
  REAL, INTENT(IN) :: locvar(nx)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  REAL, INTENT(OUT):: globvar((nx-3)*nproc_x+3)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(nx)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia, ic,jc, i0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i 

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:) = locvar(:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(jc == 1) THEN 

      IF(ic /= 1) THEN     !  pass data to processor 0
      
        mytag = mptag + 100 + ic + 1
        IF( myproc == ic-1 )THEN
          CALL mpi_send (tem,nx,MPI_REAL,master,                     &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny*nz,MPI_REAL,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data
          source = ic - 1
          CALL mpi_recv (tem,nx,MPI_REAL,source,                    &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar
      
        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        DO i=i0,nx
          ia = i + (ic-1)*(nx-fzone)
          globvar(ia) = tem(i)
        END DO          
      
      END IF

      END IF    ! jc == 1

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge1dx
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE1dy                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge1dy(locvar,ny,globvar) 5,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    ny       Dimension of the array
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: ny
  REAL, INTENT(IN) :: locvar(ny)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  REAL, INTENT(OUT):: globvar((ny-3)*nproc_y+3)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(ny)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ja, ic,jc, j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: j 

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:) = locvar(:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic == 1) THEN 

      IF(jc /= 1) THEN     !  pass data to processor 0
      
        mytag = mptag + 100 + jc + 1
        IF(myproc ==  (jc-1)*nproc_x )THEN
          CALL mpi_send (tem,ny,MPI_REAL,master,                     &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny*nz,MPI_REAL,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data
          source = (jc-1)*nproc_x
          CALL mpi_recv (tem,ny,MPI_REAL,source,                    &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar
      
        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO j=j0,ny
          ja = j + (jc-1)*(ny-fzone)
          globvar(ja) = tem(j)
        END DO          
      
      END IF

      END IF    ! ic == 1

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge1dy

!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE2D                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge2d(locvar,nx,ny,globvar) 46,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: nx,ny
                            ! Number of grid points in x, y and z
  REAL, INTENT(IN) :: locvar(nx,ny)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'


  REAL, INTENT(OUT):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3)
                            ! Output array in global domain.
!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(nx,ny)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia,ja, ic,jc, i0,j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:) = locvar(:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  pass data to processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_send (tem,nx*ny,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny,MPI_REAL,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data

          source = ic+(jc-1)*nproc_x-1

          CALL mpi_recv (tem,nx*ny,MPI_REAL,source,               &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar

        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO j=j0,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=i0,nx
              ia = i + (ic-1)*(nx-fzone)
              globvar(ia,ja) = tem(i,j)
            END DO          
        END DO      

      END IF

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge2d
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE2di                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge2di(locvar,nx,ny,globvar) 4,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny
                            ! Number of grid points in x, y and z
  INTEGER, INTENT(IN) :: locvar(nx,ny)

  INTEGER, INTENT(OUT):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: tem(nx,ny)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia,ja, ic,jc, i0,j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:) = locvar(:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  pass data to processor 0
        
        mytag = mptag + 100 + ic + jc
        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_send (tem,nx*ny,MPI_INTEGER,master,               &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny,MPI_INTEGER,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data

          source = ic+(jc-1)*nproc_x-1

          CALL mpi_recv (tem,nx*ny,MPI_INTEGER,source,               &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar

        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO j=j0,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=i0,nx
              ia = i + (ic-1)*(nx-fzone)
              globvar(ia,ja) = tem(i,j)
            END DO          
        END DO      

      END IF

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge2di
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE3d                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge3d(locvar,nx,ny,nz,globvar) 195,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: nx,ny,nz          
                            ! Number of grid points in x, y and z
  REAL, INTENT(IN) :: locvar(nx,ny,nz)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'


  REAL, INTENT(OUT):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nz)
                            ! Output array in global domain.
!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(nx,ny,nz)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia,ja, ic,jc, i0,j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:,:) = locvar(:,:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  pass data to processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_send (tem,nx*ny*nz,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny*nz,MPI_REAL,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data

          source = ic+(jc-1)*nproc_x-1

          CALL mpi_recv (tem,nx*ny*nz,MPI_REAL,source,               &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar

        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO k=1,nz
          DO j=j0,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=i0,nx
              ia = i + (ic-1)*(nx-fzone)
              globvar(ia,ja,k) = tem(i,j,k)
            END DO          
          END DO      
        END DO      

      END IF

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge3d
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE3di                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge3di(locvar,nx,ny,nz,globvar) 8,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny,nz          
                            ! Number of grid points in x, y and z
  INTEGER, INTENT(IN) :: locvar(nx,ny,nz)

  INTEGER, INTENT(OUT):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nz)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER :: tem(nx,ny,nz)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia,ja, ic,jc, i0,j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:,:) = locvar(:,:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  pass data to processor 0
        
        mytag = mptag + 100 + ic + jc
        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_send (tem,nx*ny*nz,MPI_INTEGER,master,               &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny*nz,MPI_INTEGER,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data

          source = ic+(jc-1)*nproc_x-1

          CALL mpi_recv (tem,nx*ny*nz,MPI_INTEGER,source,               &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar

        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO k=1,nz
          DO j=j0,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=i0,nx
              ia = i + (ic-1)*(nx-fzone)
              globvar(ia,ja,k) = tem(i,j,k)
            END DO          
          END DO      
        END DO      

      END IF

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge3di
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE4d                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpimerge4d(locvar,nx,ny,nzsoil,nstyps,globvar) 9,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/15
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       Number of grid points in the vertical
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny,nzsoil, nstyps
                            ! Number of grid points in x, y and z
  REAL, INTENT(IN) :: locvar(nx,ny,nzsoil,nstyps)

  REAL, INTENT(OUT):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nzsoil,nstyps)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(nx,ny,nzsoil,nstyps)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia,ja, ic,jc, i0,j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k, n

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:,:,:) = locvar(:,:,:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  pass data to processor 0

        mytag = mptag + 100 + ic + jc
        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_send (tem,nx*ny*nzsoil*nstyps,MPI_REAL,master,    &
                         mytag,MPI_COMM_WORLD,imstat) 

          !CALL mpi_bsend (tem,nx*ny*nz,MPI_REAL,master,             &
          !                mytag,MPI_COMM_WORLD,imstat) 
                                                    !forced buffering
        END IF

        IF(myproc == 0)THEN          ! receive data

          source = ic+(jc-1)*nproc_x-1

          CALL mpi_recv (tem,nx*ny*nzsoil*nstyps,MPI_REAL,source,    &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar

        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO n=1,nstyps
        DO k=1,nzsoil
          DO j=j0,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=i0,nx
              ia = i + (ic-1)*(nx-fzone)
              globvar(ia,ja,k,n) = tem(i,j,k,n)
            END DO          
          END DO      
        END DO      
        END DO      

      END IF

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge4d
!
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT1DX                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit1dx(globvar,nx,var) 3,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Dimension of the array in subdomain.
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx
  REAL, INTENT(IN):: globvar((nx-3)*nproc_x+3)

  REAL, INTENT(OUT) :: var(nx)


!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into var

        DO i=1,nx
           ia = i + (ic-1)*(nx-fzone)
           var(i) = globvar(ia)
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /= 1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx,MPI_REAL,target,                 &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:) = globvar(1:nx)     

  RETURN
END SUBROUTINE mpisplit1dx
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT1DY                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit1dy(globvar,ny,var) 3,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    ny       Number of grid points in the y-direction (north/south)
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: ny
  REAL, INTENT(IN):: globvar((ny-3)*nproc_y+3)

  REAL, INTENT(OUT) :: var(ny)

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: j

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into tem

          DO j=1,ny
            ja = j + (jc-1)*(ny-fzone)
            var(j) = globvar(ja)
          END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,ny,MPI_REAL,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,ny,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:) = globvar(1:ny)     

  RETURN
END SUBROUTINE mpisplit1dy
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT2d                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit2d(globvar,nx,ny,var) 16,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny
                            ! Number of grid points in x and y
  REAL, INTENT(IN):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3)

  REAL, INTENT(OUT) :: var(nx,ny)


!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into var

        DO j=1,ny
          ja = j + (jc-1)*(ny-fzone)
          DO i=1,nx
            ia = i + (ic-1)*(nx-fzone)
            var(i,j) = globvar(ia,ja)
          END DO          
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*ny,MPI_REAL,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*ny,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:) = globvar(1:nx,1:ny)     

  RETURN
END SUBROUTINE mpisplit2d
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT2DI                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit2di(globvar,nx,ny,var) 2,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny
                            ! Number of grid points in x and y
  INTEGER, INTENT(IN):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3)

  INTEGER, INTENT(OUT) :: var(nx,ny)


!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into tem

        DO j=1,ny
          ja = j + (jc-1)*(ny-fzone)
          DO i=1,nx
            ia = i + (ic-1)*(nx-fzone)
            var(i,j) = globvar(ia,ja)
          END DO          
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*ny,MPI_INTEGER,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*ny,MPI_INTEGER,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:) = globvar(1:nx,1:ny)     

  RETURN
END SUBROUTINE mpisplit2di
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT3d                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit3d(globvar,nx,ny,nz,var) 222,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       3rd dimension of the subdomain array, possible value are
!             vertical grid points (nz in other subroutines), nzsoil,
!             nstyps+1, or 4 (prcrate) or 1 (for 2D arrays)
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny,nz          
                            ! Number of grid points in x, y and z
  REAL, INTENT(IN):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nz)

  REAL, INTENT(OUT) :: var(nx,ny,nz)


!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into tem

        DO k=1,nz
          DO j=1,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=1,nx
              ia = i + (ic-1)*(nx-fzone)
              var(i,j,k) = globvar(ia,ja,k)
            END DO          
          END DO      
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*ny*nz,MPI_REAL,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*ny*nz,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:,:) = globvar(1:nx,1:ny,1:nz)     

  RETURN
END SUBROUTINE mpisplit3d

!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT3DI                ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit3di(globvar,nx,ny,nz,var) 14,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nz       3rd dimension of the subdomain array, possible value are
!             vertical grid points (nz in other subroutines), nzsoil,
!             nstyps+1, or 4 (prcrate) or 1 (for 2D arrays)
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny,nz          
                            ! Number of grid points in x, y and z
  INTEGER, INTENT(IN):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nz)

  INTEGER, INTENT(OUT) :: var(nx,ny,nz)

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into var

        DO k=1,nz
          DO j=1,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=1,nx
              ia = i + (ic-1)*(nx-fzone)
              var(i,j,k) = globvar(ia,ja,k)
            END DO          
          END DO      
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*ny*nz,MPI_INTEGER,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*ny*nz,MPI_INTEGER,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:,:) = globvar(1:nx,1:ny,1:nz)     

  RETURN
END SUBROUTINE mpisplit3di
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT4d                 ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit4d(globvar,nx,ny,nzsoil,nstyps,var) 9,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Number of grid points in the x-direction (east/west)
!    ny       Number of grid points in the y-direction (north/south)
!    nzsoil   3rd dimension of the subdomain array, possible value may be
!             as nzsoil in other subroutines. 
!    nstyps   4rd dimentsion of the 4D array, possible value may be
!             nstyps (in other subroutines) + 1.
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx,ny,nzsoil, nstyps
  REAL, INTENT(IN):: globvar((nx-3)*nproc_x+3,(ny-3)*nproc_y+3,nzsoil,nstyps)

  REAL, INTENT(OUT) :: var(nx,ny,nzsoil,nstyps)

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i, j, k, l

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into tem

        DO l=1,nstyps
        DO k=1,nzsoil
          DO j=1,ny
            ja = j + (jc-1)*(ny-fzone)
            DO i=1,nx
              ia = i + (ic-1)*(nx-fzone)
              var(i,j,k,l) = globvar(ia,ja,k,l)
            END DO          
          END DO      
        END DO      
        END DO      

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*ny*nzsoil*nstyps,MPI_REAL,target,     &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*ny*nzsoil*nstyps,MPI_REAL,master,     &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:,:,:) = globvar(1:nx,1:ny,1:nzsoil,1:nstyps)  

  RETURN
END SUBROUTINE mpisplit4d
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE2dns               ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge2dns(locvar,nx,nz,globvar) 4,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run.
!  for North/South boundary 2D array. 
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2003/02/25
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    nx       Local dimension of the array
!    nz       This dimension will not change.
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: nx
  INTEGER, INTENT(IN) :: nz
  REAL, INTENT(IN) :: locvar(nx,nz)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  REAL, INTENT(OUT):: globvar((nx-3)*nproc_x+3,nz)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(nx,nz)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ia, ic,jc, i0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i,k 

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:) = locvar(:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(jc == 1) THEN

      IF(ic /= 1) THEN     !  pass data to processor 0
      
        mytag = mptag + 100 + ic + 1
        IF( myproc == ic-1 )THEN
          CALL mpi_send (tem,nx*nz,MPI_REAL,master,            &
                         mytag,MPI_COMM_WORLD,imstat) 

        END IF

        IF(myproc == 0)THEN          ! receive data
          source = ic - 1
          CALL mpi_recv (tem,nx*nz,MPI_REAL,source,            &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar
      
        IF (ic == 1) THEN
          i0 = 1
        ELSE
          i0 = 2
        END IF

        DO k=1,nz
        DO i=i0,nx
          ia = i + (ic-1)*(nx-fzone)
          globvar(ia,k) = tem(i,k)
        END DO          
        END DO
      
      END IF

      END IF    ! jc == 1

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge2dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPIMERGE2dew               ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!

SUBROUTINE mpimerge2dew(locvar,ny,nz,globvar) 4,2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Generate global array from a multiprocessor run 
!  for East/West boundary 2D array.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2003/02/25
!  Based on subroutine mpimerge
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    localvar Variable to be written.
!
!    ny       Dimension of the array
!    nz
!
!  OUTPUT:
!
!    globvar  global variable to be output
!
!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

  INTEGER, INTENT(IN) :: ny
  INTEGER, INTENT(IN) :: nz
  REAL, INTENT(IN) :: locvar(ny,nz)

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

  REAL, INTENT(OUT):: globvar((ny-3)*nproc_y+3,nz)
                            ! Output array in global domain.

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  REAL :: tem(ny,nz)

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER, PARAMETER :: master = 0
  INTEGER :: source
  INTEGER :: ja, ic,jc, j0, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: j,k 

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3 !  arps.

  tem(:,:) = locvar(:,:) ! each processor stores the locvar into tem
 
  DO jc=1,nproc_y
    DO ic=1,nproc_x

      ! message passing section...

      IF(ic == 1) THEN 

      IF(jc /= 1) THEN     !  pass data to processor 0
      
        mytag = mptag + 100 + jc + 1
        IF(myproc ==  (jc-1)*nproc_x )THEN
          CALL mpi_send (tem,ny*nz,MPI_REAL,master,                  &
                         mytag,MPI_COMM_WORLD,imstat) 
        END IF

        IF(myproc == 0)THEN          ! receive data
          source = (jc-1)*nproc_x
          CALL mpi_recv (tem,ny*nz,MPI_REAL,source,                 &
                         mytag, MPI_COMM_WORLD,stat,imstat)
        END IF

      END IF

      !  storage section

      IF(myproc == 0)THEN  ! store data into globvar
      
        IF (jc == 1) THEN
          j0 = 1
        ELSE
          j0 = 2
        END IF

        DO k=1,nz
        DO j=j0,ny
          ja = j + (jc-1)*(ny-fzone)
          globvar(ja,k) = tem(j,k)
        END DO          
        END DO
      
      END IF

      END IF    ! ic == 1

      CALL mpbarrier

    END DO      
  END DO      

  RETURN
END SUBROUTINE mpimerge2dew
!
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT2DNS               ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit2dns(globvar,nx,nz,var) 4,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!  for North/South boundary arrays.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2003/02/26
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    nx       Dimension of the array in subdomain.
!    nz
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: nx
  INTEGER, INTENT(IN) :: nz
  REAL, INTENT(IN):: globvar((nx-3)*nproc_x+3,nz)

  REAL, INTENT(OUT) :: var(nx,nz)


!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ia,ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: i,k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into var

        DO k=1,nz
        DO i=1,nx
           ia = i + (ic-1)*(nx-fzone)
           var(i,k) = globvar(ia,k)
        END DO      
        END DO

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /= 1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,nx*nz,MPI_REAL,target,                &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,nx*nz,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:) = globvar(1:nx,:)     

  RETURN
END SUBROUTINE mpisplit2dns
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE MPISPLIT2DEW               ######
!######                                                      ######
!######                     Developed by                     ######
!######     Center for Analysis and Prediction of Storms     ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE mpisplit2dew(globvar,ny,nz,var) 4,2

!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Split the global array and scatter to each processor.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: Yunheng Wang
!  2002/08/20
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    globvar  Global array passed in from processor 0.
!
!    ny       Number of grid points in the y-direction (north/south)
!    nz
!
!  OUTPUT:
!
!    var      Subdomain variable in each process.
!
!-----------------------------------------------------------------------

  IMPLICIT NONE

!-----------------------------------------------------------------------
!
!  Include files.
!
!-----------------------------------------------------------------------

  INCLUDE 'mpif.h'
  INCLUDE 'globcst.inc'
  INCLUDE 'mp.inc'

!-----------------------------------------------------------------------
!
!  Variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, INTENT(IN) :: ny
  INTEGER, INTENT(IN) :: nz
  REAL, INTENT(IN):: globvar((ny-3)*nproc_y+3,nz)

  REAL, INTENT(OUT) :: var(ny,nz)

!-----------------------------------------------------------------------
!
!  Local variable declarations.
!
!-----------------------------------------------------------------------

  INTEGER, PARAMETER :: master = 0

  INTEGER :: mptag        ! Unique MPI id.
  INTEGER :: mytag
  INTEGER :: target
  INTEGER :: ja, ic,jc, fzone
  INTEGER :: stat(mpi_status_size)
  INTEGER :: imstat
  INTEGER :: j,k

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  CALL inctag
  mptag = gentag

!-----------------------------------------------------------------------
!
!  fill the globvar array
!
!-----------------------------------------------------------------------

  fzone = 3        !  arps.

  DO jc=1,nproc_y
    DO ic=1,nproc_x

      !  storage section

      IF(myproc == 0)THEN  ! store data into tem

          DO k = 1,nz
          DO j=1,ny
            ja = j + (jc-1)*(ny-fzone)
            var(j,k) = globvar(ja,k)
          END DO      
          END DO

      END IF

      ! message passing section...

      IF(ic /=1 .OR. jc /=1)THEN     !  receive data from processor 0

        mytag = mptag + 100 + ic + jc

        IF(myproc == 0)THEN          ! send data

          target = ic+(jc-1)*nproc_x-1

          CALL mpi_send (var,ny*nz,MPI_REAL,target,               &
                         mytag, MPI_COMM_WORLD,imstat)
        END IF

        IF(myproc == (ic+(jc-1)*nproc_x-1))THEN
       
          CALL mpi_recv (var,ny*nz,MPI_REAL,master,               &
                         mytag,MPI_COMM_WORLD,stat,imstat) 

        END IF

      END IF

      CALL mpbarrier
 
    END DO      
  END DO      

!At the end, make sure processor 0 contains correct varlue (ic=1,jc=1)
  IF(myproc == 0) var(:,:) = globvar(1:ny,:)     

  RETURN
END SUBROUTINE mpisplit2dew
!
!
!######################################################################
!
! Wrap subroutines added for ARPSPLT_mpi
! 
!   mpsendr  -- CALL mpi_send, REAL array
!   mprecvr  -- CALL mpi_recv, REAL array
!   mpsendi  -- CALL mpi_send, INTEGER scalar
!   mprecvi  -- CALL mpi_recv, INTEGER scalar
!
!#####################################################################


SUBROUTINE mpsendr(a,size,dest,itag,ierror) 19

  IMPLICIT NONE

  INCLUDE 'mpif.h'

  INTEGER :: size, dest, itag, ierror
  REAL :: a(size)

  CALL mpi_send(a,size,MPI_REAL,dest,itag,MPI_COMM_WORLD,ierror)

  RETURN

END SUBROUTINE mpsendr


SUBROUTINE mpsendi(m,dest,itag,ierror) 8

  IMPLICIT NONE

  INCLUDE 'mpif.h'

  INTEGER :: m
  INTEGER :: dest, itag, ierror

  CALL mpi_send(m,1,MPI_INTEGER,dest,itag,MPI_COMM_WORLD,ierror)

  RETURN

END SUBROUTINE mpsendi


SUBROUTINE mprecvr(a,size,source,itag,ierror) 19

  IMPLICIT NONE

  INCLUDE 'mpif.h'

  INTEGER :: size, source, itag, ierror
  REAL :: a(size)

  INTEGER :: stat(MPI_STATUS_SIZE)

  CALL mpi_recv(a,size,MPI_REAL,source,itag,MPI_COMM_WORLD,stat,ierror)

  RETURN

END SUBROUTINE mprecvr


SUBROUTINE mprecvi(m,source,itag,ierror) 8

  IMPLICIT NONE

  INCLUDE 'mpif.h'

  INTEGER :: m
  INTEGER :: size, source, itag, ierror

  INTEGER :: stat(MPI_STATUS_SIZE)

  CALL mpi_recv(m,1,MPI_INTEGER,source,itag,MPI_COMM_WORLD,stat,ierror)

  RETURN

END SUBROUTINE mprecvi


SUBROUTINE mpmaxi(imax) 4

!
!  Find the maximum integer of all processors
!
  IMPLICIT NONE

  REAL :: imax

  INTEGER :: imstat

  INCLUDE 'mpif.h'

  REAL :: maxtm

!---------------------------------------------------------
!
! Start of executable code....
!
!---------------------------------------------------------

  CALL MPI_REDUCE(imax,maxtm,1,MPI_INTEGER,MPI_MAX,0,     &
                  MPI_COMM_WORLD,imstat)
  CALL MPI_BCAST(maxtm,1,MPI_REAL,0,MPI_COMM_WORLD,imstat)

  imax = maxtm

  RETURN
END SUBROUTINE mpmaxi