subroutine psichi2uv_reg_V2( psi, chi,  u, v, &
     coeffx,coeffy, &
     ids,ide, jds,jde, kds,kde,  &
     ims,ime, jms,jme, kms,kme,  &
     its,ite, jts,jte, kts,kte )
!$$$  subprogram documentation block
!                .      .    .                                       .
! subprogram:    psichi2uv_reg
!     prgmmr:    barker, d   org:  np22              date:  2000-02-03
!
! abstract:  Calculate wind components u and v from psi and chi 
!            (streamfunction and velocity potential, respectively)
!
! program history log:
!   2000/02/03   barker, dale - creation of F90 version
!   2001/10/30   barker       - parallel version
!   2003/09/05   parrish      - adapted to unified NCEP 3dvar
!   2003/10/17   wu, wanshu   - first index Y second X
!   2004-06-22   treadon      - update documentation
!
!   input argument list:
!     psi - streamfunction
!     chi - velocity potential
!     ids - starting index of first  dimension (latitude)  for full domain grid
!     ide - ending   index of first  dimension (latitude)  for full domain grid
!     jds - starting index of second dimension (longitude) for full domain grid
!     jde - ending   index of second dimension (longitude) for full domain grid
!     kds - starting index of third  dimension (vertical)  for full domain grid
!     kde - ending   index of third  dimension (vertical)  for full domain grid
!
!     ims - starting index of first  dimension for memory allocation
!     ime - ending   index of first  dimension for memory allocation
!     jms - starting index of second dimension for memory allocation
!     jme - ending   index of second dimension for memory allocation
!     kms - starting index of third  dimension for memory allocation
!     kme - ending   index of third  dimension for memory allocation
!
!     its - starting index of first  dimension for sub-domain (tile) grid
!     ite - ending   index of first  dimension for sub-domain (tile) grid
!     jts - starting index of second dimension for sub-domain (tile) grid
!     jte - ending   index of second dimension for sub-domain (tile) grid
!     kts - starting index of third  dimension for sub-domain (tile) grid
!     kte - ending   index of third  dimension for sub-domain (tile) grid
!
!   output argument list:
!     u - zonal wind component
!     v - meridional wind component
!
! remarks:
!    The method used is 
!       u = ( -dpsi/dy + dchi/dx )
!       v = (  dpsi/dx + dchi/dy )
!
!    The assumptions made in this routine are:
!       - unstaggered grid,
!       - lateral boundary conditions - dpsi/dn, dchi/dn = 0 (FCT)
!       - dy=rearth*dph , dx=cos(ph)*rearth*dlm (dx,dy is rotated grid)
!
! attributes:
!   language: f90
!   machine:  ibm rs/6000 sp
!
!$$$
  use kinds, only: r_kind,i_kind
  use constants, only: half
! use gridmod, only: coeffx,coeffy
  
  implicit none
  
  integer(i_kind), intent(in):: ids,ide, jds,jde, kds,kde    ! domain dims.
  integer(i_kind), intent(in):: ims,ime, jms,jme, kms,kme    ! memory dims.
  integer(i_kind), intent(in):: its,ite, jts,jte, kts,kte    ! tile   dims.
  
  real(r_kind), intent(in)   :: coeffx(ims:ime,jms:jme)           ! MPondeca , 10Apr2008
  real(r_kind), intent(in)   :: coeffy(ims:ime,jms:jme)           ! MPondeca , 10Apr2008

  real(r_kind), intent(in)   :: psi(ims:ime,jms:jme,kms:kme) ! Stream function
  real(r_kind), intent(in)   :: chi(ims:ime,jms:jme,kms:kme) ! Velocity potential
  real(r_kind), intent(out)  :: u(ims:ime,jms:jme,kms:kme)   ! u wind comp (m/s)
  real(r_kind), intent(out)  :: v(ims:ime,jms:jme,kms:kme)   ! v wind comp (m/s)
  
  integer(i_kind)            :: i, j, k                      ! Loop counters.
  integer(i_kind)            :: is, ie                       ! 1st dim. end points.
  integer(i_kind)            :: js, je                       ! 2nd dim. end points.
  integer(i_kind)            :: ks, ke                       ! 3rd dim. end points.
  
!------------------------------------------------------------------------------
!  [1.0] Initialise:
!------------------------------------------------------------------------------

!  Computation to check for edge of domain:
  is = its; ie = ite; js = jts; je = jte
  if ( its == ids ) is = ids+1; if ( ite == ide ) ie = ide-1
  if ( jts == jds ) js = jds+1; if ( jte == jde ) je = jde-1

  do k = kts, kte

!------------------------------------------------------------------------------
!  [2.0] Compute u, v at interior points (2nd order central finite diffs):
!------------------------------------------------------------------------------

     do j = js, je
        do i = is, ie
           u(i,j,k) = -( psi(i+1,j  ,k) - psi(i-1,j  ,k) )*coeffy(i,j) + &
                ( chi(i  ,j+1,k) - chi(i  ,j-1,k) )*coeffx(i,j)
           
           v(i,j,k) = ( psi(i  ,j+1,k) - psi(i  ,j-1,k) )*coeffx(i,j) + &
                ( chi(i+1,j  ,k) - chi(i-1,j  ,k) ) * coeffy(i,j)
        end do
     end do
     

!------------------------------------------------------------------------------
!  [3.0] Compute u, v at domain boundaries:
!------------------------------------------------------------------------------

!    [3.1] Western boundaries:

     if ( jts == jds ) then
        j = jts
        do i = is, ie
           u(i,j,k) = -( psi(i+1,j  ,k) - psi(i-1,j  ,k) )*coeffy(i,j) + &
                ( chi(i  ,j+2,k) - chi(i  ,j  ,k) )*coeffx(i,j)
           v(i,j,k) = ( psi(i  ,j+2,k) - psi(i  ,j  ,k) )*coeffx(i,j) + &
                ( chi(i+1,j  ,k) - chi(i-1,j  ,k) ) * coeffy(i,j)
        end do
     end if
     
!    [3.2] Eastern boundaries:

     if ( jte == jde ) then
        j = jte
        do i = is, ie
           u(i,j,k) = -( psi(i+1,j  ,k) - psi(i-1,j  ,k) )*coeffy(i,j) + &
                ( chi(i  ,j  ,k) - chi(i  ,j-2,k) )*coeffx(i,j)
           v(i,j,k) = ( psi(i  ,j  ,k) - psi(i  ,j-2,k) )*coeffx(i,j) + &
                ( chi(i+1,j  ,k) - chi(i-1,j  ,k) ) * coeffy(i,j)
        end do
     end if
     
!    [3.3] Southern boundaries:

     if ( its == ids ) then
        i = its
        do j = js, je
           u(i,j,k) = -( psi(i+2,j  ,k) - psi(i  ,j  ,k) )*coeffy(i,j) + &
                ( chi(i  ,j+1,k) - chi(i  ,j-1,k) )*coeffx(i,j)
           
           v(i,j,k) = ( psi(i  ,j+1,k) - psi(i  ,j-1,k) )*coeffx(i,j) + &
                ( chi(i+2,j  ,k) - chi(i  ,j  ,k) ) * coeffy(i,j)
           
        end do
     end if
     
!    [3.4] Northern boundaries:

     if ( ite == ide ) then
        i = ite
        do j = js, je
           u(i,j,k) = -( psi(i  ,j  ,k) - psi(i-2,j  ,k) )*coeffy(i,j) + &
                ( chi(i  ,j+1,k) - chi(i  ,j-1,k) )*coeffx(i,j)
           
           v(i,j,k) = ( psi(i  ,j+1,k) - psi(i  ,j-1,k) )*coeffx(i,j) + &
                ( chi(i  ,j  ,k) - chi(i-2,j  ,k) ) * coeffy(i,j)
        end do
     end if
     
!------------------------------------------------------------------------------
!    [4.0] Corner points (assume average of surrounding points - poor?):
!------------------------------------------------------------------------------

!    [4.1] Bottom-left point:

     if ( its == ids .AND. jts == jds ) then
        u(its,jts,k) = half * ( u(its+1,jts,k) + u(its,jts+1,k) )
        v(its,jts,k) = half * ( v(its+1,jts,k) + v(its,jts+1,k) )
     end if
  
!    [4.2] Top-left point:

     if ( ite == ide .AND. jts == jds ) then
        u(ite,jts,k) = half * ( u(ite-1,jts,k) + u(ite,jts+1,k) )
        v(ite,jts,k) = half * ( v(ite-1,jts,k) + v(ite,jts+1,k) )
     end if
     
!    [4.3] Bottom-right point:

     if ( its == ids .AND. jte == jde ) then
        u(its,jte,k) = half * ( u(its+1,jte,k) + u(its,jte-1,k) )
        v(its,jte,k) = half * ( v(its+1,jte,k) + v(its,jte-1,k) )
     end if
     
!    [4.4] Top-right point:

     if ( ite == ide .AND. jte == jde ) then
        u(ite,jte,k) = half * ( u(ite-1,jte,k) + u(ite,jte-1,k) )
        v(ite,jte,k) = half * ( v(ite-1,jte,k) + v(ite,jte-1,k) )
     end if
     
  end do
  
end subroutine psichi2uv_reg_V2
