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


SUBROUTINE mixuvw(nx,ny,nz, exbcbufsz,                                  & 1,10
           u,v,w,ptprt,pprt,qv,qc,qr,qi,qs,qh,tke,pbldpth,              &
           ubar,vbar,ptbar,pbar,rhostr,qvbar,                           &
           usflx,vsflx, x,y,z,zp,mapfct,                                &
           j1,j2,j3,aj3x,aj3y,aj3z,j3inv,ptsfc,                         &
           umix,vmix,wmix,kmh,kmv,rprntl,lenscl,defsq,                  &
           exbcbuf,                                                     &
           tem1,tem2,tem3,tem4,tem5,tem6,                               &
           tem7,tem8,tem9,tem10,tem11,tem12)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the total mixing (turbulent mixing and the externally
!  imposed computational mixing) for the momentum equations. This
!  subroutine also calculates the turbulent mixing coefficient ,km,
!  which is used to calculate mixing terms for temperature and
!  water quantities. The mixing coefficient is based on Smagorinsky's
!  formulation. For the computational mixing, there are two options:
!  second order and fourth order mixing. The mixing applies only to
!  the perturbations quantities.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/6/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  4/22/96 (M. Xue)
!  Modified the calls to computational mixing routines to pass
!  in rhostr instead of rhobar. Effectively, J3 is included in the
!  formulation as was in ARPS version 3.0.
!
!  11/06/97 (D. Weber)
!  Added three additional levels to the mapfct array.  The three
!  levels (4,5,6) represent the inverse of the first three in order.
!  The inverse map factors are computed to improve efficiency.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tem12
!  -added aj3x,y,z
!  -added mapfct(i,j,7) = mapfct(i,j,1)*mapfct(i,j,1)
!  -added mapfct(i,j,8) = 0.25*mapfct(i,j,1)
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    u        x component of velocity at a given time level (m/s)
!    v        y component of velocity at a given time level (m/s)
!    w        Vertical component of velocity in Cartesian
!             coordinates at a given time level (m/s)
!    ptprt    Perturbation potential temperature at a given time level (K)
!    pprt     Perturbation pressure at a given time level (Pascal)
!    qv       Water vapor specific humidity at a given time level (kg/kg)
!    qc       Cloud water mixing ratio at a given time level (kg/kg)
!    qr       Rainwater mixing ratio at a given time level (kg/kg)
!    qi       Cloud ice mixing ratio at a given time level (kg/kg)
!    qs       Snow mixing ratio at a given time level (kg/kg)
!    qh       Hail mixing ratio at a given time level (kg/kg)
!    tke      Turbulent Kinetic Energy ((m/s)**2)
!    pbldpth  Planetary boundary layer depth (m)
!
!    ubar     Base state x velocity component (m/s)
!    vbar     Base state y velocity component (m/s)
!    ptbar    Base state potential temperature (K)
!    pbar     Base state pressure (Pascal)
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!    qvbar    Base state water vapor specific humidity (kg/kg)
!
!    usflx    Surface flux of u-momentum
!    vsflx    Surface flux of v-momentum
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar, u and v points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    aj3z     Avgz of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    umix     Total mixing in u equation (kg/(m*s)**2)
!    vmix     Total mixing in v equation (kg/(m*s)**2)
!    wmix     Total mixing in w equation (kg/(m*s)**2)
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!    lenscl   Turbulent mixing length scale (m)
!    defsq    Deformation squared (1/s**2)
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!    tem4     Temporary work array.
!    tem5     Temporary work array.
!    tem6     Temporary work array.
!    tem7     Temporary work array.
!    tem8     Temporary work array.
!    tem9     Temporary work array.
!    tem10    Temporary work array.
!    tem11    Temporary work array.
!    tem12    Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  INCLUDE 'timelvls.inc'

  REAL :: u     (nx,ny,nz)     ! Total u-velocity (m/s)
  REAL :: v     (nx,ny,nz)     ! Total v-velocity (m/s)
  REAL :: w     (nx,ny,nz)     ! Total w-velocity (m/s)
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature (K)
  REAL :: pprt  (nx,ny,nz)     ! Perturbation pressure (Pascal)
!
  REAL :: qv    (nx,ny,nz)     ! Water vapor specific humidity (kg/kg)
  REAL :: qc    (nx,ny,nz)     ! Cloud water mixing ratio (kg/kg)
  REAL :: qr    (nx,ny,nz)     ! Rain water mixing ratio (kg/kg)
  REAL :: qi    (nx,ny,nz)     ! Cloud ice mixing ratio (kg/kg)
  REAL :: qs    (nx,ny,nz)     ! Snow mixing ratio (kg/kg)
  REAL :: qh    (nx,ny,nz)     ! Hail mixing ratio (kg/kg)
  REAL :: tke   (nx,ny,nz,nt)  ! Turbulent Kinetic Energy ((m/s)**2)
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)
!
  REAL :: ubar  (nx,ny,nz)     ! Base state u-velocity (m/s)
  REAL :: vbar  (nx,ny,nz)     ! Base state v-velocity (m/s)
  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: pbar  (nx,ny,nz)     ! Base state pressure (Pascal).
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.
  REAL :: qvbar (nx,ny,nz)     ! Base state water vapor specific humidity
                               ! (kg/kg)

  REAL :: usflx (nx,ny)        ! surface flux of u-momentum (kg/(m*s**2))
  REAL :: vsflx (nx,ny)        ! surface flux of v-momentum (kg/(m*s**2))
  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.

                                ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u and v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: aj3z  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR.

  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
  REAL :: ptsfc  (nx,ny)       ! Ground surface potential temperature (K)

  REAL :: umix  (nx,ny,nz)     ! Turbulent mixing on u-momentum.
  REAL :: vmix  (nx,ny,nz)     ! Turbulent mixing on v-momentum.
  REAL :: wmix  (nx,ny,nz)     ! Turbulent mixing on w-momentum.

  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number
  REAL :: lenscl(nx,ny,nz)     ! Turbulent mixing length scale (m)
  REAL :: defsq (nx,ny,nz)     ! Deformation squared (1/s**2)

  INTEGER :: exbcbufsz         ! EXBC buffer size
  REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array

  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
  REAL :: tem6  (nx,ny,nz)     ! Temporary work array
  REAL :: tem7  (nx,ny,nz)     ! Temporary work array
  REAL :: tem8  (nx,ny,nz)     ! Temporary work array
  REAL :: tem9  (nx,ny,nz)     ! Temporary work array
  REAL :: tem10 (nx,ny,nz)     ! Temporary work array
  REAL :: tem11 (nx,ny,nz)     ! Temporary work array
  REAL :: tem12 (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: nxyz
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!

!
!-----------------------------------------------------------------------
!
!  Control parameters for subgrid scalar turbulent mixing are passed
!  in globcst.inc, these include:
!
!  tmixopt: Tubulent mixing option
!           = 0, zero turbulent mixing.
!           = 1, constant mixing coefficient.
!           = 2, Smagorinsky mixing coefficient.
!           = 3, Smagorinsky + constant coefficient mixing.
!           = 4, 1.5 order TKE turbulence
!  tmixcst: Constant mixing coefficient. (Options 1 and 3)
!
!-----------------------------------------------------------------------
!
  CALL set_acct(tmix_acct)

  IF( tmixopt == 0 .AND. sfcphy == 0 ) THEN

    nxyz = nx*ny*nz
    CALL flzero(umix,nxyz)
    CALL flzero(vmix,nxyz)
    CALL flzero(wmix,nxyz)

  ELSE

    CALL tmixuvw(nx,ny,nz,                                              &
         u,v,w,ptprt,pprt,qv,qc,qr,qi,qs,qh,tke,pbldpth,                &
         ubar,vbar,ptbar,pbar,rhostr,qvbar,                             &
         usflx,vsflx, x,y,z,zp,mapfct,                                  &
         j1,j2,j3,aj3x,aj3y,aj3z,j3inv,ptsfc,                           &
         umix,vmix,wmix,kmh,kmv,rprntl,lenscl,defsq,                    &
         tem1,tem2,tem3,tem4,tem5,tem6,tem7,                            &
         tem8,tem9,tem10,tem11,tem12)
!call test_dump (umix,"XXXAtmixuvw_umix",nx,ny,nz,1,0)

  END IF

  CALL set_acct(cmix_acct)

  IF( cmix2nd == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the second order computational mixing terms and add
!  them to the turbulent mixing terms umix, vmix, wmix.
!
!-----------------------------------------------------------------------
!
    CALL cmix2uvw(nx,ny,nz,                                             &
                  u,v,w, ubar,vbar,rhostr,                              &
                  umix,vmix,wmix,                                       &
                  tem1,tem2,tem3)
!call test_dump (umix,"XXXAcmix2uvw_umix",nx,ny,nz,1,0)

  END IF

  IF( cmix4th == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the fourth order computational mixing terms and add
!  them to the turbulent mixing terms umix, vmix, wmix.
!
!-----------------------------------------------------------------------
!
    CALL cmix4uvw(nx,ny,nz,                                             &
                  u,v,w, ubar,vbar,rhostr,                              &
                  umix,vmix,wmix,                                       &
                  tem1,tem2,tem3,tem4,tem5)
!call test_dump (umix,"XXXAcmix4uvw_umix",nx,ny,nz,1,0)
  END IF

  IF( raydmp /= 0) THEN
    CALL set_acct(raydmp_acct)
!
!-----------------------------------------------------------------------
!
!    Calculate the upper level Rayleigh damping on u, v and w perturbations.
!    The terms are accumulated in arrays umix, vmix and wmix.
!
!-----------------------------------------------------------------------
!
    CALL rdmpuvw(nx,ny,nz,exbcbufsz,                                    &
                 u,v,w, ubar,vbar,rhostr, zp,                           &
                 umix,vmix,wmix,                                        &
                 exbcbuf,tem1,tem2,tem3,                                &
                 tem4,tem5,tem6,tem7)
!call test_dump (umix,"XXXArdmpuvw_umix",nx,ny,nz,1,0)

  END IF

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


SUBROUTINE mixpt(nx,ny,nz, exbcbufsz,                                   & 1,8
           ptprt,ptbar,rhostr,kmh,kmv,rprntl,                           &
           usflx,vsflx,ptsflx,pbldpth,                                  &
           x,y,z,zp,mapfct,j1,j2,j3,aj3x,aj3y,j3inv,ptsfc,              &
           ptmix, exbcbuf,                                              &
           tem1,tem2,tem3,tem4,tem5,tem6)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the total mixing (turbulent mixing and an externally imposed
!  computational mixing) for the potential temperature equation.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/6/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  4/22/96 (M. Xue)
!  Modified the calls to computational mixing routines to pass
!  in rhostr instead of rhobar. Effectively, J3 is included in the
!  formulation as was in ARPS version 3.0.
!
!  9/18/98 (D. Weber)
!  Added arrays aj3x,y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    ptprt    Perturbation potential temperature at a given time level (K)
!    ptbar    Base state potential temperature (K)
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    usflx    Surface u-momentum flux
!    vsflx    Surface v-momentum flux
!    ptsflx   Surface heat flux (K*kg/(m**2*s))
!    pbldpth  Planetary boundary layer depth (m)
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!    ptsfc    Ground surface potential temperature (K)
!
!  OUTPUT:
!
!    ptmix    Total mixing in potential temperature equation
!             (K*kg/(m**3 * s))
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!    tem4     Temporary work array.
!    tem5     Temporary work array.
!    tem6     Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature (K)
  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.

  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: usflx(nx,ny)         ! surface flux of u-momentum
  REAL :: vsflx(nx,ny)         ! surface flux of v-momentum
  REAL :: ptsflx(nx,ny)        ! surface flux of heat (K*kg/(m**2*s))
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
  REAL :: ptsfc  (nx,ny)       ! Ground surface potential temperature (K)

  REAL :: ptmix(nx,ny,nz)      ! Mixing on potential
                               ! temperature (K*kg/(m**3 * s))

  INTEGER :: exbcbufsz         ! EXBC buffer size
  REAL :: exbcbuf( exbcbufsz ) ! EXBC buffer array

  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
  REAL :: tem6  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: nxyz
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  CALL set_acct(tmix_acct)

  IF( tmixopt == 0 .AND. sfcphy == 0 ) THEN

    nxyz = nx*ny*nz
    CALL flzero(ptmix,nxyz)

  ELSE

    CALL tmixpt(nx,ny,nz, ptprt,ptbar,rhostr,kmh,kmv,rprntl,            &
               usflx,vsflx,ptsflx,pbldpth,                              &
               x,y,z,zp,mapfct, j1,j2,j3,aj3x,aj3y,j3inv,ptsfc,         &
               ptmix,                                                   &
               tem1,tem2,tem3,tem4,tem5,tem6)

  END IF

  CALL set_acct(cmix_acct)

  IF( cmix2nd == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the second order computational mixing term, ptmix, for
!  the potential temperature equation.
!
!-----------------------------------------------------------------------
!
    CALL cmix2s(nx,ny,nz, ptprt,rhostr, ptmix, tem1,tem2,tem3)

  END IF

  IF( cmix4th == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the fourth order computational mixing term, ptmix, for
!  the potential temperature equation.
!
!-----------------------------------------------------------------------
!

    CALL cmix4s(nx,ny,nz, ptprt,rhostr, ptmix, tem1,tem2,tem3,tem4)

  END IF

  IF( raydmp /= 0) THEN
!
!-----------------------------------------------------------------------
!
!    Calculate the upper level Rayleigh damping on the potential temperature
!    perturbations. The term is accumulated in array ptmix.
!
!-----------------------------------------------------------------------
!
    CALL set_acct(raydmp_acct)

    CALL rdmppt(nx,ny,nz, exbcbufsz,                                    &
                ptprt ,rhostr, zp,                                      &
                ptmix,                                                  &
                exbcbuf,tem1,                                           &
                tem2,tem3)

  END IF


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


SUBROUTINE mixqv(nx,ny,nz,                                              & 1,6
           qv,rhostr,qvbar,kmh,kmv,rprntl,qvsflx,pbldpth,               &
           x,y,z,zp,mapfct,j1,j2,j3,aj3x,aj3y,j3inv,                    &
           usflx,vsflx,ptsflx,ptsfc,qvsfc,ptbar,ptprt,                  &
           qvmix,                                                       &
           tem1,tem2,tem3,tem4,tem5,tem6)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the total mixing (externally imposed computational mixing
!  and turbulent mixing) for the water vapor mixing ratio equation.
!  This mixing term is different from those of other water quantities
!  since QV has a base state.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/6/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  4/22/96 (M. Xue)
!  Modified the calls to computational mixing routines to pass
!  in rhostr instead of rhobar. Effectively, J3 is included in the
!  formulation as was in ARPS version 3.0.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added arrays aj3x,y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    qv       Water vapor specific humidity at a given time level (kg/kg)
!    qvbar    Base state water vapor specific humidity (kg/kg)
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    qvsflx   Surface moisture flux (K*kg/(m**2*s))
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    qvmix    Total mixing in water vapor equation (kg/(m**3 * s))
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!    tem4     Temporary work array.
!    tem5     Temporary work array.
!    tem6     Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: qv    (nx,ny,nz)     ! Water vapor specific humidity (kg/kg)
  REAL :: qvbar (nx,ny,nz)     ! Base state water vapor specific humidity
                               ! (kg/kg)
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: qvsflx(nx,ny)        ! surface flux of moisture (kg/(m**2*s))
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature
  REAL :: ptsfc(nx,ny)         ! Temperature at ground (K) (in top 1 cm layer)
  REAL :: qvsfc(nx,ny)         ! Effective qv at the surface (kg/kg)

  REAL :: usflx(nx,ny)         ! Surface u-momentum flux
  REAL :: vsflx(nx,ny)         ! Surface v-momentum flux
  REAL :: ptsflx(nx,ny)        ! Surface heat flux (K*kg/(m**2*s))

!
  REAL :: qvmix(nx,ny,nz)      ! Mixing on water vapor specific humidity
                               ! (kg/(m**3 *s))

  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
  REAL :: tem6  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i, j, k
  INTEGER :: nxyz
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
!
!-----------------------------------------------------------------------
!

!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  CALL set_acct(tmix_acct)

  IF( tmixopt == 0 .AND. sfcphy == 0 ) THEN

    nxyz = nx*ny*nz
    CALL flzero(qvmix,nxyz)

  ELSE

    CALL tmixqv(nx,ny,nz, qv,rhostr,kmh,kmv,rprntl,qvsflx,pbldpth,      &
               x,y,z,zp,mapfct, j1,j2,j3,aj3x,aj3y,j3inv,               &
               usflx,vsflx,ptsflx,ptsfc,qvsfc,ptbar,ptprt,              &
               qvmix,                                                   &
               tem1,tem2,tem3,tem4,tem5,tem6)


  END IF

  CALL set_acct(cmix_acct)

  IF( cmix2nd == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the second order computational mixing term, qvmix,
!  for the qv equation.
!
!-----------------------------------------------------------------------
!
    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tem5(i,j,k)=qv(i,j,k)-qvbar(i,j,k)
        END DO
      END DO
    END DO

    CALL cmix2s(nx,ny,nz, tem5 ,rhostr, qvmix, tem1,tem2,tem3)

  END IF

  IF( cmix4th == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the fourth order computational mixing term, qvmix,
!  for qv equation.
!
!-----------------------------------------------------------------------
!
    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tem5(i,j,k)=qv(i,j,k)-qvbar(i,j,k)
        END DO
      END DO
    END DO

    CALL cmix4s(nx,ny,nz, tem5 ,rhostr, qvmix, tem1,tem2,tem3,tem4)

  END IF

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


SUBROUTINE mixq(nx,ny,nz,                                               & 1,6
           q,rhostr,kmh,kmv,rprntl,x,y,z,zp,mapfct,j1,j2,j3,            &
           aj3x,aj3y,j3inv,                                             &
           qmix,                                                        &
           tem1,tem2,tem3,tem4,tem5,tem6)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the total mixing (which includes the turbulent mixing
!  as well as externally imposed computational mixing) for all water
!  substance equations except water vapor.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/6/92 (D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  4/22/96 (M. Xue)
!  Modified the calls to computational mixing routines to pass
!  in rhostr instead of rhobar. Effectively, J3 is included in the
!  formulation as was in ARPS version 3.0.
!
!  9/18/98 (D. Weber)
!  Added arrays aj3x and aj3y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    q        water/ice mixing ratio (kg/kg)
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    qmix     Total mixing in water/ice substance
!             equation (kg/(m**3 * s))
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!    tem4     Temporary work array.
!    tem5     Temporary work array.
!    tem6     Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: q     (nx,ny,nz)     ! Water/ice quantity (kg/kg)
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.
  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
!
  REAL :: qmix(nx,ny,nz)       ! Water/ice mixing
!
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
  REAL :: tem6  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: nxyz
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!

  INCLUDE 'globcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  CALL set_acct(tmix_acct)

  IF( tmixopt == 0) THEN

    nxyz = nx*ny*nz
    CALL flzero(qmix,nxyz)

  ELSE

    CALL tmixq(nx,ny,nz, q,rhostr,kmh,kmv,rprntl,                       &
               x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,j3inv,              &
               qmix,                                                    &
               tem1,tem2,tem3,tem4,tem5,tem6)

  END IF

  CALL set_acct(cmix_acct)

  IF( cmix2nd == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the second order computational mixing term, qmix,
!  for the q equation.
!
!-----------------------------------------------------------------------
!
    CALL cmix2s(nx,ny,nz, q ,rhostr, qmix, tem1,tem2,tem3)

  END IF

  IF( cmix4th == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the fourth order computational mixing term, qmix,
!  for the q equation.
!
!-----------------------------------------------------------------------

    CALL cmix4s(nx,ny,nz, q ,rhostr, qmix, tem1,tem2,tem3,tem4)

  END IF

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


SUBROUTINE mixtke(nx,ny,nz,                                             & 1,6
           tke,rhostr,kmh,kmv,x,y,z,zp,mapfct,                          &
           j1,j2,j3,aj3x,aj3y,j3inv,                                    &
           tkemix, tem1,tem2,tem3,tem4,tem5,tem6,tem7)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the mixing term in TKE equation.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  8/15/95
!
!  MODIFICATION HISTORY:
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  4/22/96 (M. Xue)
!  Modified the calls to computational mixing routines to pass
!  in rhostr instead of rhobar. Effectively, J3 is included in the
!  formulation as was in ARPS version 3.0.
!
!  07/10/97 (Fanyou Kong - CMRP)
!  Change the upper limit in DO LOOP 210 to nx-1, ny-1, and nz-1
!  to avoid possible floating overflow
!
!  8/27/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added aj3x,y arrays
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    tke      Turbulent kinetic energy
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    tkemix   Mixing term in TKE equation
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!    tem4     Temporary work array.
!    tem5     Temporary work array.
!    tem6     Temporary work array.
!    tem7     Temporary work array.
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: tke   (nx,ny,nz)     ! Turbulent kinetic energy
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.
  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: tkemix(nx,ny,nz)     ! Mixing term in TKE equation.

  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
  REAL :: tem6  (nx,ny,nz)     ! Temporary work array
  REAL :: tem7  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: nxyz,i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!

  INCLUDE 'globcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  CALL set_acct(tmix_acct)

  IF( tmixopt == 0) THEN

    nxyz = nx*ny*nz
    CALL flzero(tkemix,nxyz)

  ELSE

    DO k=1,nz
      DO j=1,ny
        DO i=1,nx
          tem7(i,j,k)=1.0
        END DO
      END DO
    END DO

    CALL tmixq(nx,ny,nz,tke,rhostr,kmh,kmv, tem7,                       &
               x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,j3inv,              &
               tkemix,                                                  &
               tem1,tem2,tem3,tem4,tem5,tem6)


    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tkemix(i,j,k)= 2.0*tkemix(i,j,k)
        END DO
      END DO
    END DO

  END IF

  CALL set_acct(cmix_acct)

  IF( cmix2nd == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the second order computational mixing term, tkemix,
!  for the TKE equation.
!
!-----------------------------------------------------------------------
!
    CALL cmix2s(nx,ny,nz, tke ,rhostr, tkemix, tem1,tem2,tem3)

  END IF

  IF( cmix4th == 1) THEN
!
!-----------------------------------------------------------------------
!
!  Calculate the fourth order computational mixing term, tkemix,
!  for the tke equation.
!
!-----------------------------------------------------------------------
!
    CALL cmix4s(nx,ny,nz, tke ,rhostr, tkemix, tem1,tem2,tem3,tem4)

  END IF

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


SUBROUTINE tmixuvw(nx,ny,nz,                                            & 1,7
           u,v,w,ptprt,pprt,qv,qc,qr,qi,qs,qh,tke,pbldpth,              &
           ubar,vbar,ptbar,pbar,rhostr,qvbar,                           &
           usflx,vsflx, x,y,z,zp, mapfct,                               &
           j1,j2,j3,aj3x,aj3y,aj3z,j3inv,ptsfc,                         &
           umix,vmix,wmix,kmh,kmv,rprntl,lenscl,defsq,                  &
           nsqed,tau11,tau12,tau13,tau22,tau23,tau33,                   &
           tem1,tem2,tem3,tem4,tem5)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing terms for the momentum equations. These
!  terms are expressed in the form of a stress tensor.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  6/25/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  3/16/96 (Ming Xue)
!  The model can now include the surface fluxes with the turbulent
!  mxing option off (tmixopt=0).
!
!  6/5/96 (Donghai Wang, M. Xue and X. Song)
!  Fixed a minor bug related to the vertical implicit treatment of
!  turbulence mixing. Should not affect the results much.
!
!  11/06/97 (D. Weber)
!  Added three additional levels to the mapfct array.  The three
!  levels (4,5,6) represent the inverse of the first three in order.
!  The inverse map factors are computed to improve efficiency.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tem5
!  -added aj3x,y,z
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    u        x component of velocity at a given time level (m/s)
!    v        y component of velocity at a given time level (m/s)
!    w        Vertical component of velocity in Cartesian
!             coordinates at a given time level (m/s)
!    ptprt    Perturbation potential temperature at a given time level (K)
!    pprt     Perturbation pressure at a given time level (Pascal)
!    qv       Water vapor specific humidity at a given time level (kg/kg)
!    qc       Cloud water mixing ratio at a given time level (kg/kg)
!    qr       Rainwater mixing ratio at a given time level (kg/kg)
!    qi       Cloud ice mixing ratio at a given time level (kg/kg)
!    qs       Snow mixing ratio at a given time level (kg/kg)
!    qh       Hail mixing ratio at a given time level (kg/kg)
!    tke      Turbulent Kinetic Energy ((m/s)**2)
!    pbldpth  Planetary boundary layer depth (m)
!
!    ubar     Base state x velocity component (m/s)
!    vbar     Base state y velocity component (m/s)
!    ptbar    Base state potential temperature (K)
!    pbar     Base state pressure (Pascal)
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!    qvbar    Base state water vapor specific humidity (kg/kg)
!
!    usflx    Surface flux of u-momentum
!    vsflx    Surface flux of v-momentum
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar, u and v points
!
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    aj3z     Avgz of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    umix     Total mixing in u equation (kg/(m*s)**2)
!    vmix     Total mixing in v equation (kg/(m*s)**2)
!    wmix     Total mixing in w equation (kg/(m*s)**2)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!    lenscl   Turbulent mixing length scale (m)
!    defsq    Deformation squared (1/s**2)
!
!  WORK ARRAYS:
!
!    real nsqed  Temporary array containing the Brunt Vaisala frquency
!    real tau11  Temporary work array
!    real tau12  Temporary work array
!    real tau13  Temporary work array
!    real tau22  Temporary work array
!    real tau23  Temporary work array
!    real tau33  Temporary work array
!    real tem1   Temporary work array
!    real tem2   Temporary work array
!    real tem3   Temporary work array
!    real tem4   Temporary work array
!    real tem5   Temporary work array
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  INCLUDE 'timelvls.inc'

  REAL :: u     (nx,ny,nz)     ! Total u-velocity (m/s)
  REAL :: v     (nx,ny,nz)     ! Total v-velocity (m/s)
  REAL :: w     (nx,ny,nz)     ! Total w-velocity (m/s)
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature (K)
  REAL :: pprt  (nx,ny,nz)     ! Perturbation pressure (Pascal)
!
  REAL :: qv    (nx,ny,nz)     ! Water vapor specific humidity (kg/kg)
  REAL :: qc    (nx,ny,nz)     ! Cloud water mixing ratio (kg/kg)
  REAL :: qr    (nx,ny,nz)     ! Rain water mixing ratio (kg/kg)
  REAL :: qi    (nx,ny,nz)     ! Cloud ice mixing ratio (kg/kg)
  REAL :: qs    (nx,ny,nz)     ! Snow mixing ratio (kg/kg)
  REAL :: qh    (nx,ny,nz)     ! Hail mixing ratio (kg/kg)
  REAL :: tke   (nx,ny,nz,nt)  ! Turbulent Kinetic Energy ((m/s)**2)
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)
!
  REAL :: ubar  (nx,ny,nz)     ! Base state u-velocity (m/s)
  REAL :: vbar  (nx,ny,nz)     ! Base state v-velocity (m/s)
  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: pbar  (nx,ny,nz)     ! Base state pressure (Pascal).
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.
  REAL :: qvbar (nx,ny,nz)     ! Base state water vapor specific humidity
                               ! (kg/kg)

  REAL :: usflx (nx,ny)        ! surface flux of u-momentum (kg/(m*s**2))
  REAL :: vsflx (nx,ny)        ! surface flux of v-momentum (kg/(m*s**2))
  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u and v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: aj3z  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: ptsfc  (nx,ny)       ! Ground surface potential temperature (K)
!
  REAL :: umix  (nx,ny,nz)     ! Turbulent mixing on u-momentum.
  REAL :: vmix  (nx,ny,nz)     ! Turbulent mixing on v-momentum.
  REAL :: wmix  (nx,ny,nz)     ! Turbulent mixing on w-momentum.

  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number
  REAL :: lenscl(nx,ny,nz)     ! Turbulent mixing length scale (m)
  REAL :: defsq (nx,ny,nz)     ! Deformation squared (1/s**2)
!
  REAL :: nsqed (nx,ny,nz)     ! Temporary work array
  REAL :: tau11 (nx,ny,nz)     ! Temporary work array
  REAL :: tau12 (nx,ny,nz)     ! Temporary work array
  REAL :: tau13 (nx,ny,nz)     ! Temporary work array
  REAL :: tau22 (nx,ny,nz)     ! Temporary work array
  REAL :: tau23 (nx,ny,nz)     ! Temporary work array
  REAL :: tau33 (nx,ny,nz)     ! Temporary work array
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
  REAL :: tem4  (nx,ny,nz)     ! Temporary work array
  REAL :: tem5  (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i, j, k
  REAL :: zpup,zplow
  INTEGER :: cdiszero
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'phycst.inc'

!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  IF( tmixopt == 0 )  THEN

    DO k=1,nz
      DO j=1,ny
        DO i=1,nx
          wmix(i,j,k)=0.0
          tau13(i,j,k)=0.0
          tau23(i,j,k)=0.0
          kmh(i,j,k)=0.0
          kmv(i,j,k)=0.0
        END DO
      END DO
    END DO

  ELSE
!
!-----------------------------------------------------------------------
!
!  Calculate the static stability parameter N squared (Brunt-Vaisala
!  frequency). The arrays tem1,tem2,tau11,tau12 are used as work
!  arrays for the following call.
!
!-----------------------------------------------------------------------
!
    CALL stabnsq(nx,ny,nz,                                              &
                 ptprt,pprt,qv,qc,qr,qi,qs,qh,ptbar,qvbar,pbar,         &
                 j3,j3inv,nsqed,tem1,tem2,tau11,tau12)
!
!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor components Dij, which are stored
!  in arrays Tauij.
!
!  Please note umix and vmix are used here to temporarily store
!  d31 and d32.
!
!-----------------------------------------------------------------------
!
    CALL deform(nx,ny,nz,u,v,w,mapfct,j1,j2,j3,aj3x,aj3y,aj3z,j3inv,    &
                tau11,tau12,tau13,tau22,tau23,tau33,umix,vmix,defsq,    &
                tem1,tem2,tem3,tem4,tem5)
!
!-----------------------------------------------------------------------
!
!  Calculate the turbulent mixing coefficient, km, using the modified
!  Smagorinsky and TKE formulations.
!
!-----------------------------------------------------------------------
!
    CALL cftmix(nx,ny,nz,                                               &
                nsqed,zp,tke,pbldpth,defsq, kmh,kmv,rprntl,lenscl,      &
                tem1,tem2)
!
!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tauij = km * (rhostr/j3) * Dij.
!
!  Please note umix and vmix are used here to temporarily store
!  tau31 and tau32, which are used immediatedly by wmixtrm.
!  umix and vmix are freed afterwards.
!
!
!-----------------------------------------------------------------------
!
    CALL stress(nx,ny,nz,j3,j3inv,                                      &
                kmh,kmv,rhostr,tau11,tau12,tau13,tau22,tau23,tau33,     &
                umix,vmix,                                              &
                tem1,tem2,tem3,tem4,tem5)

    CALL wmixtrm(nx,ny,nz, mapfct(1,1,1), j1,j2,j3,aj3x,aj3y,           &
                 umix,vmix,tau33,                                       &
                 wmix, tem1, tem2)

  END IF
!
!-----------------------------------------------------------------------
!
!  Set the surface momentum fluxes:
!
!  When sfcphy = 0, the internally calculated (from SGS turbulence
!  parameterization) surface fluxes are used.
!  Otherwise, pre-calculated fluxes usflx and vsflx are used.
!
!-----------------------------------------------------------------------
!

  IF( (landwtr == 0.AND.cdmlnd == 0.0).OR.                              &
        (landwtr == 1.AND.cdmlnd == 0.0.AND.cdmwtr == 0.0) ) THEN
    cdiszero = 1
  ELSE
    cdiszero = 0
  END IF

  IF( (sfcphy == 1.OR.sfcphy == 3) .AND. cdiszero == 1) GO TO 111

  IF( sfcphy /= 0 ) THEN
    IF ( (sflxdis == 0) .OR. (sflxdis == 1 .AND.                        &
           (sfcphy == 1.OR.sfcphy == 3).AND.cdiszero == 1) .OR.         &
           (sflxdis == 2) .OR. (sflxdis == 3) ) THEN
!
!-----------------------------------------------------------------------
!
!  tau13 at the surface = usflx.
!
!-----------------------------------------------------------------------
!
      DO j=2,ny-2
        DO i=2,nx-1
          tau13(i,j,2) = usflx(i,j)
        END DO
      END DO
!
!-----------------------------------------------------------------------
!
!  tau23 at the surface = vsflx.
!
!-----------------------------------------------------------------------
!
      DO j=2,ny-1
        DO i=2,nx-2
          tau23(i,j,2) = vsflx(i,j)
        END DO
      END DO

    ELSE IF (sflxdis == 1)  THEN

      DO j=2,ny-2
        DO i=2,nx-1

          tau13(i,j,2) = usflx(i,j)
          zplow=0.5*(zp(i,j,2)+zp(i-1,j,2))

          IF(ptsfc(i,j)+ptsfc(i-1,j) > ptprt(i,j,2)                     &
                +ptbar(i,j,2)+ptprt(i-1,j,2)+ptbar(i-1,j,2))THEN

            DO k=3,nz-1
              zpup =0.5*(zp(i,j,k)+zp(i-1,j,k))
              IF ( (zpup-zplow) <= pbldpth(i,j) ) tau13(i,j,k)=usflx(i,j)* &
                  (1.0-(zpup-zplow)/pbldpth(i,j))**2
            END DO

          END IF
        END DO
      END DO
!call test_dump (usflx,"XXX_usflx",nx,ny,1,1,0)
!call test_dump (pbldpth,"XXX_pbldpth",nx,ny,1,1,0)

      DO j=2,ny-1
        DO i=2,nx-2

          tau23(i,j,2) = vsflx(i,j)
          zplow=0.5*(zp(i,j,2)+zp(i,j-1,2))

          IF(ptsfc(i,j)+ptsfc(i,j-1) > ptprt(i,j,2)+ptbar(i,j,2)        &
                +ptprt(i,j-1,2)+ptbar(i,j-1,2))THEN

            DO k=3,nz-1
              zpup =0.5*(zp(i,j,k)+zp(i,j-1,k))
              IF ( (zpup-zplow) <= pbldpth(i,j) ) tau23(i,j,k)=vsflx(i,j)* &
                  (1.0-(zpup-zplow)/pbldpth(i,j))**2
            END DO

          END IF
        END DO
      END DO

    END IF

  END IF

  111   CONTINUE

  IF(tmixopt == 0) THEN

    DO k=2,nz-2
      DO j=1,ny-1
        DO i=2,nx-1
          umix(i,j,k)=(tau13(i,j,k+1)-tau13(i,j,k))*dzinv
        END DO
      END DO
    END DO
!call test_dump (umix,"XXXtm0_umix",nx,ny,nz,1,0)

    DO k=2,nz-2
      DO j=2,ny-1
        DO i=1,nx-1
          vmix(i,j,k)=(tau23(i,j,k+1)-tau23(i,j,k))*dzinv
        END DO
      END DO
    END DO

  ELSE
!
!-----------------------------------------------------------------------
!
!  Calculate the divergence of the stresses. This is the turbulent
!  mixing on u and v momentum (umix and vmix).
!
!-----------------------------------------------------------------------
!
    CALL umixtrm(nx,ny,nz, mapfct(1,1,2),j1,j2,j3,aj3y,                 &
                 tau11,tau12,tau13,                                     &
                 umix, tem1, tem2)
!call test_dump (umix,"XXXAumixtrm_umix",nx,ny,nz,1,0)

    CALL vmixtrm(nx,ny,nz, mapfct(1,1,3),j1,j2,j3,aj3x,                 &
                 tau12,tau22,tau23,                                     &
                 vmix, tem1, tem2)

  END IF
!
!-----------------------------------------------------------------------
!
!  Set the normal gradient of the mixing terms on the lateral
!  boundaries to zero
!
!  The umix and vmix terms are set for completness, they are not
!  used in any calculations.
!
!-----------------------------------------------------------------------

!  DO 51 k=2,nz-2
!  DO 51 j=1,ny-1
!    umix(1,j,k)=umix(2,j,k)
!    umix(nx,j,k)=umix(nx-1,j,k)
! 51    CONTINUE

!  DO 52 k=2,nz-2
!  DO 52 i=1,nx-1
!    vmix(i,1,k)=vmix(i,2,k)
!    vmix(i,ny,k)=vmix(i,ny-1,k)
!  52    CONTINUE


!
!-----------------------------------------------------------------------
!
!  Set the mixing terms at the lateral boundaries equal to those
!  at the neighboring interior points.  This is done to essure
!  the boundary points get a similar amount of mixing as the interior
!  points. The boundary values will be used only in the case of
!  radiation lateral boundary conditions.
!
!-----------------------------------------------------------------------
!
  DO k=1,nz-1
    DO i=1,nx
      umix(i,   1,k)=umix(i,   2,k)
      umix(i,ny-1,k)=umix(i,ny-2,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      umix( 1,j,k)=umix(   2,j,k)
      umix(nx,j,k)=umix(nx-1,j,k)
    END DO
  END DO

  DO k=1,nz-1
    DO i=1,nx-1
      vmix(i, 1,k)=vmix(i,   2,k)
      vmix(i,ny,k)=vmix(i,ny-1,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny
      vmix(   1,j,k)=vmix(   2,j,k)
      vmix(nx-1,j,k)=vmix(nx-2,j,k)
    END DO
  END DO

  DO k=1,nz-1
    DO i=1,nx-1
      wmix(i,   1,k)=wmix(i,   2,k)
      wmix(i,ny-1,k)=wmix(i,ny-2,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      wmix(   1,j,k)=wmix(   2,j,k)
      wmix(nx-1,j,k)=wmix(nx-2,j,k)
    END DO
  END DO

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


SUBROUTINE stabnsq(nx,ny,nz,                                            & 1,1
           ptprt,pprt,qv,qc,qr,qi,qs,qh,ptbar,qvbar,pbar,j3,j3inv,      &
           nsqed, tmprtr,qvs,qw,pt)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the static stability parameter N-squared (Brunt-Vaisala
!  frequency squared).
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  9/15/1992
!
!  MODIFICATION HISTORY:
!
!  3/25/94 (G. Bassett)
!  The condition for using saturated or nonsaturated formulation for
!  nsqed is changed from qc > 0 to qc >= 1e-06 in order to avoid
!  fluctuations in Km when very small values of qc are present.
!
!  6/7/94 (M. Xue)
!  Correction to the calculation of nsqed for the dry area inside
!  loop 3100. The error was introduced when modifications were made
!  on 3/25/94. Variable pt in that line was mistakenly written as ptbar.
!
!  3/4/96 (M. Xue)
!  Restructured so that no moisture related calculation is done
!  when moist=0.
!
!  3/14/96 (M. Xue)
!  Corrected a bug introduced on 3/4/96. dzinvd2 was not set for
!  moist=0 case.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    ptprt    Perturbation potential temperature (K)
!    pprt     Perturbation pressure (Pascal)
!    ptbar    Base state potential temperature (K)
!    qv       Water vapor specific humidity (kg/kg)
!    qc       Cloud water mixing ratio (kg/kg)
!    qr       Rainwater mixing ratio (kg/kg)
!    qi       Cloud ice mixing ratio (kg/kg)
!    qs       Snow mixing ratio (kg/kg)
!    qh       Hail mixing ratio (kg/kg)
!    qvbar    Base state water vapor specific humidity (kg/kg)
!    pbar     Base state pressure (Pascal)
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    nsqed    Brunt-Vaisala frequency squared (1/s**2), a local array
!
!  WORK ARRAYS:
!
!    tmprtr   Work array for temperature
!    qvs      work array for saturation specific humidity
!    qw       Work array for total water mixing ratio
!    pt       Work arrays for total potential temperature
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature (K)
  REAL :: pprt  (nx,ny,nz)     ! Perturbation pressure (Pascal)
  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: qv    (nx,ny,nz)     ! Water vapor specific humidity (kg/kg)
  REAL :: qc    (nx,ny,nz)     ! Cloud water mixing ratio (kg/kg)
  REAL :: qr    (nx,ny,nz)     ! Rain water mixing ratio (kg/kg)
  REAL :: qi    (nx,ny,nz)     ! Cloud ice mixing ratio (kg/kg)
  REAL :: qs    (nx,ny,nz)     ! Snow mixing ratio (kg/kg)
  REAL :: qh    (nx,ny,nz)     ! Hail mixing ratio (kg/kg)
  REAL :: qvbar (nx,ny,nz)     ! Base state water vapor specific humidity
  REAL :: pbar  (nx,ny,nz)     ! Base state pressure (Pascal)
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: nsqed (nx,ny,nz)     ! Brunt-Vaisala frequency squared (1/s**2)

  REAL :: tmprtr(nx,ny,nz)     ! Temporary work array
  REAL :: qvs   (nx,ny,nz)     ! Temporary work array
  REAL :: qw    (nx,ny,nz)     ! Temporary work array
  REAL :: pt    (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i, j, k
!
  REAL :: ppi, dzinvd2, p0inv
  REAL :: eps   ! A small value of qc above which cloudwater is
                ! regarded as present.
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'phycst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  p0inv = 1.0/p0
!
!-----------------------------------------------------------------------
!
!  Calculate the static stability N**2.
!  The moist static stability follows that of Durran and Klemp (1982)
!
!-----------------------------------------------------------------------
!
  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1

        pt(i,j,k) =  ptbar(i,j,k)+ptprt(i,j,k)

      END DO
    END DO
  END DO

  dzinvd2=1.0/(2*dz)

  IF( moist == 0 ) THEN

    DO k=2,nz-2
      DO j=1,ny-1
        DO i=1,nx-1
          nsqed(i,j,k)=g*(pt(i,j,k+1)-pt(i,j,k-1))*dzinvd2              &
                       /(pt(i,j,k)*j3(i,j,k))
        END DO
      END DO
    END DO

  ELSE

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1

          ppi   = ((pbar(i,j,k)+pprt(i,j,k))*p0inv) ** rddcp
          tmprtr(i,j,k) = (ptbar(i,j,k)+ptprt(i,j,k)) * ppi

        END DO
      END DO
    END DO


    CALL getqvs(nx,ny,nz, 1,nx-1,1,ny-1,1,nz-1, pbar, tmprtr,qvs)

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1

          qw(i,j,k) = qvs(i,j,k)+qc(i,j,k)+qr(i,j,k)

        END DO
      END DO
    END DO

    eps = 1.0E-6

    DO k=2,nz-2
      DO j=1,ny-1
        DO i=1,nx-1

          IF( qc(i,j,k) <= eps ) THEN

            nsqed(i,j,k)=g*(pt(i,j,k+1)-pt(i,j,k-1))*dzinvd2            &
                         /(pt(i,j,k)*j3(i,j,k))

          ELSE

            nsqed(i,j,k)= g * j3inv(i,j,k) *                            &
                ((1+lathv*qvs(i,j,k)/(rd*tmprtr(i,j,k)))/               &
                (1+rd/rv*lathv*lathv*qvs(i,j,k)/(cp*rd*tmprtr(i,j,k)**2)) &
                *((pt(i,j,k+1)-pt(i,j,k-1))/pt(i,j,k)                   &
                +lathv/(cp*tmprtr(i,j,k))*(qvs(i,j,k+1)-qvs(i,j,k-1)) ) &
                -(qw(i,j,k+1)-qw(i,j,k-1)) ) *dzinvd2

          END IF

        END DO
      END DO
    END DO

  END IF

  DO j=1,ny-1
    DO i=1,nx-1
      nsqed(i,j,  1 )=nsqed(i,j,2)
      nsqed(i,j,nz-1)=nsqed(i,j,nz-2)
    END DO
  END DO

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


SUBROUTINE cftmix(nx,ny,nz,                                             & 1,19
           nsqed,zp,tke,pbldpth,defsq, kmh,kmv,rprntl,lenscl,           &
           grdscl,tem1)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing coefficient, km, with the modified
!  Smagorinsky and TKE formulations.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  6/1/93 (M. Xue)
!  Calculation of delta from dzp rather than dz.
!
!  6/16/93 (M. Xue)
!  The values of KM at the lateral boundaries are explicitly set.
!  The calculated values are overwritten.
!
!  4/20/1995 (M. Xue)
!  Added an upper limit on KM in ensure numerical stability.
!
!  3/8/96 (M. Xue, X. Song and V. Wong)
!  Add parameter tkeopt for three versions of 1.5 order TKE schemes.
!  They differ mainly in the specification of turbulent mixing length.
!
!  tkeopt = 1, Wyngaard formulation;
!         = 2, Deardroff/Moeng formulation;
!         = 3, Sun and Chang formulation.
!
!  3/11/96 (M. Xue)
!  Rewrote most of this subroutine.
!  Introduced kmh, kmv and rprntl arrays
!
!  3/21/96 (M. Xue)
!  Moved the calculation of magnitude of deformation (defsq) to
!  DEFORM.
!
!  8/5/96 (M. Xue and J. Zong)
!  Set an upper limit of 3.0 on the inverse Prandtl number for the
!  Sun and Chang formulation (tkeopt=3).
!
!  2/2/1998 (M. Xue and D. Weber)
!  Fixed a problem with mixing length calculation at the PBL top
!  when Sun and Chang scheme is used.
!
!  4/19/1999 (Pengfei Zhang)
!  Changed the calculation of Kmh and Kmv as frstep=1 and
!  tmixopt=4 by using Kmh=0.1*tke**2*lh and Kmv=0.1*tke**2*lv
!  in order to be consistent with future values.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    nsqed    Brunt-Vaisala frequency (1/s**2), a local array
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    tke      Turbulent Kinetic Energy ((m/s)**2)
!    pbldpth  Planetary boundary layer depth (m)
!    defsq    Deformation squared (1/s**2)
!
!  OUTPUT:
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!    lenscl   Turbulent mixing length scale (m)
!
!  WORK ARRAYS:
!
!    grdscl   Work array to store grid scale.
!    tem1     Temporary array
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  INCLUDE 'timelvls.inc'
!
  REAL :: nsqed (nx,ny,nz)     ! Brunt-Vaisala frequency (1/s**2)
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.
!
  REAL :: tke   (nx,ny,nz,nt)  ! Turbulent Kinetic Energy ((m/s)**2)
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)
  REAL :: defsq (nx,ny,nz)     ! Deformation squared (1/s**2)
!
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number
  REAL :: lenscl(nx,ny,nz)     ! Turbulent mixing length scale (m)

  REAL :: grdscl(nx,ny,nz)     ! Array to store grid scale

  REAL :: tem1(nx,ny,nz)       ! Temporary array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i, j, k
!
  REAL :: tema, temb
  REAL :: prinv, one3rd, km_nd_min,km_nd_max,km_nd_max2
  REAL :: deltah,deltah2, lpbltf, zs
  INTEGER :: frstep
  INTEGER :: tstrtlvl

  INTEGER :: mptag1,mptag2,mptag3
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'phycst.inc'
  INCLUDE 'bndry.inc'
  INCLUDE 'mp.inc'            ! Message passing parameters.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!call test_dump (tke,"XXXcftmix_tke",nx,ny,nz,0,0)
!call test_dump (pbldpth,"XXXcftmix_pbldpth",nx,ny,1,0,0)
!call test_dump (defsq,"XXXcftmix_defsq",nx,ny,nz,0,0)
!
!-----------------------------------------------------------------------
!
!  Set the mixing coefficient, km, to a constant value TMIXCST.
!
!-----------------------------------------------------------------------
!
  one3rd= 1.0/3.0
  prinv = 1.0/prantl
  km_nd_max = kmlimit * 0.125/dtbig

  IF(tmixopt == 0) THEN

    DO k=1,nz
      DO i=1,nx
        DO j=1,ny
          kmh(i,j,k)= 0.0
          kmv(i,j,k)= 0.0
          rprntl(i,j,k)=prinv
          lenscl(i,j,k)= dx     ! not used for this option
        END DO
      END DO
    END DO

    RETURN

  ELSE IF(tmixopt == 1) THEN

    DO k=1,nz-1
      DO i=1,nx-1
        DO j=1,ny-1
          kmh(i,j,k)=tmixcst
          kmv(i,j,k)=tmixcst    ! Always assume isotropic
          rprntl(i,j,k)=prinv
          lenscl(i,j,k)= dx     ! not used for this option
        END DO
      END DO
    END DO

    GO TO 3000

  END IF

  deltah = SQRT( dx*dy )
  deltah2= dx*dy

  CALL stgrdscl(nx,ny,nz, zp, grdscl)
!
!-----------------------------------------------------------------------
!
!  Calculate the turbulent mixing coefficient, km, using the
!  modified Smagorinsky formulation.
!
!-----------------------------------------------------------------------
!

  IF( (ABS(curtim-tstart) <= 1.0E-10) .AND. (restrt /= 1) ) THEN
    frstep=1           ! Indicate that this is the initial step of
                       ! model integration.
  ELSE                 ! For non-first step or restart run
    frstep=0
  END IF

  IF((tmixopt == 3).OR.(tmixopt == 2).OR. (frstep == 1 .AND.tmixopt == 4)) THEN

    IF(tmixopt /= 3) tmixcst=0.0

    IF (trbisotp == 1) THEN

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1
!
!  An upper bound is imposed on the KM value for numerical stability:
!
            tema = grdscl(i,j,k)*grdscl(i,j,k)

            kmh(i,j,k)= MIN(km_nd_max*tema, 0.0441*tema*                &
                SQRT(MAX(defsq(i,j,k)-nsqed(i,j,k)*prinv,0.0))          &
                +tmixcst)

            kmv(i,j,k)= kmh(i,j,k)

!
!  Set the initial value of tke (at tpast and tpresent) to be
!  consistent with Smagorinsky value through Kolmogorov-Prandtl relation
!
!  This could be a potential problem if users try to use tke as a
!  unused array when turn off the tke option.
!
            IF(tmixopt == 4) THEN
              tke(i,j,k,tpresent)=(kmh(i,j,k)*10./grdscl(i,j,k))**2
              tke(i,j,k,tpast   )=(kmh(i,j,k)*10./grdscl(i,j,k))**2
            END IF

            rprntl(i,j,k)=prinv
            lenscl(i,j,k)=grdscl(i,j,k) ! not used for this option

          END DO
        END DO
      END DO

    ELSE

      temb = 1.0/deltah2

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1
!
!  An upper bound is imposed on the KM value for numerical stability:
!

            kmh(i,j,k)= MIN(km_nd_max*deltah2, 0.0441*deltah2*          &
                SQRT(MAX(defsq(i,j,k)-nsqed(i,j,k)*prinv,0.0))+tmixcst)

            tema = grdscl(i,j,k)*grdscl(i,j,k)

            kmv(i,j,k)= MIN(km_nd_max*tema, 0.0441*tema*                &
                SQRT(MAX(defsq(i,j,k)-nsqed(i,j,k)*prinv,0.0))          &
                +tmixcst*tema*temb )

            IF(tmixopt == 4) THEN
              tke(i,j,k,tpresent)=(kmv(i,j,k)*10./grdscl(i,j,k))**2
              tke(i,j,k,tpast   )=(kmv(i,j,k)*10./grdscl(i,j,k))**2

              kmh(i,j,k)= 0.1*SQRT(tke(i,j,k,tpresent)*deltah2)
            END IF

            rprntl(i,j,k)=prinv
            lenscl(i,j,k)=grdscl(i,j,k) ! not used for this option

          END DO
        END DO
      END DO

    END IF

  END IF
!
!-----------------------------------------------------------------------
!
!  1.5 order TKE option:
!
!-----------------------------------------------------------------------
!
  IF(sadvopt == 4) THEN ! Forward-based FCT scheme
    tstrtlvl = tpresent
  ELSE
    tstrtlvl = tpast
  END IF

  IF(tmixopt == 4 .AND. curtim > 0.0) THEN

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1

          IF( nsqed(i,j,k) > 0.0 ) THEN
            lenscl(i,j,k)=MIN(0.76*SQRT(tke(i,j,k,tstrtlvl)             &
                          /nsqed(i,j,k)),grdscl(i,j,k))
          ELSE
            lenscl(i,j,k)=grdscl(i,j,k)
          END IF

        END DO
      END DO
    END DO

    IF (tkeopt == 3) THEN
!
!-----------------------------------------------------------------------
!
!  For tkeopt=3, set length scale inside and immediately above the
!  PBL using a profile after Sun and Chang (1986).
!
!-----------------------------------------------------------------------
!
      lpbltf = lsclpbl0 * 1.8*(1.0-EXP(-4.0)-0.0003*EXP(8.0))

      DO j=1,ny-1
        DO i=1,nx-1
!
!-----------------------------------------------------------------------
!
!  When the PBL is convectively stable, the diagnosed PBL depth should
!  have been set to the thickness of the layer below first scalar
!  point. In this case, the profile will not be used.
!
!-----------------------------------------------------------------------
!
          IF( pbldpth(i,j)+zp(i,j,2) > 0.51*(zp(i,j,3)+zp(i,j,2)) ) THEN

            DO k=1,nz-1


              zs = (zp(i,j,k)+zp(i,j,k+1))*0.5
              tema=(zs-zp(i,j,2))/pbldpth(i,j)

              IF (tema <= 1.0)THEN  ! Below PBL top, use exp expression

                lenscl(i,j,k)=lsclpbl0*(1.8*pbldpth(i,j)*               &
                            (1.0-EXP(-4.0*tema)-0.0003*EXP(8.0*tema)))

              ELSE  ! Using linear function
!
!-----------------------------------------------------------------------
!
!  lenscl linearly decrease to zero from 1.0 pbldpth to 1.2 pbldpth.
!
!-----------------------------------------------------------------------
!
                temb=(lpbltf * pbldpth(i,j))                            &
                    *(1.2*pbldpth(i,j)-(zs-zp(i,j,2)))/(0.2*pbldpth(i,j))

                lenscl(i,j,k)= MAX( lenscl(i,j,k), temb )

              END IF
!
!-----------------------------------------------------------------------
!
!  Force lenscl to be smaller than the larger of grid scale and 600m.
!
!-----------------------------------------------------------------------
!
              lenscl(i,j,k)= MIN( lenscl(i,j,k),MAX(grdscl(i,j,k),600.0) )

            END DO
          END IF
        END DO
      END DO

    END IF
!
    km_nd_min=(1.e-6)

    IF (trbisotp == 1) THEN

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1

            tema = grdscl(i,j,k)*grdscl(i,j,k)

            rprntl(i,j,k)=1.+2.*lenscl(i,j,k)/grdscl(i,j,k)

            rprntl(i,j,k)=MIN( rprntl(i,j,k), 3.0 )

            kmh(i,j,k)=0.1*SQRT(tke(i,j,k,tstrtlvl))*lenscl(i,j,k)

            IF( rprntl(i,j,k)*nsqed(i,j,k) < defsq(i,j,k))              &
                kmh(i,j,k)=MAX(km_nd_min*tema,kmh(i,j,k))

            kmh(i,j,k)=MIN(km_nd_max*tema,kmh(i,j,k))

            kmv(i,j,k)=kmh(i,j,k)

          END DO
        END DO
      END DO

    ELSE

      deltah  = SQRT(dx*dy)
      deltah2 = dx*dy

      km_nd_max2 = km_nd_max
      IF (trbvimp == 1) km_nd_max2 = 1000.0

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1

            tema = grdscl(i,j,k)*grdscl(i,j,k)

            rprntl(i,j,k)=1.+2.*lenscl(i,j,k)/grdscl(i,j,k)

            rprntl(i,j,k)=MIN( rprntl(i,j,k), 3.0 )

            kmh(i,j,k)=0.1*SQRT(tke(i,j,k,tstrtlvl))*deltah
            kmv(i,j,k)=0.1*SQRT(tke(i,j,k,tstrtlvl))*lenscl(i,j,k)

            IF( rprntl(i,j,k)*nsqed(i,j,k) < defsq(i,j,k)) THEN
              kmh(i,j,k)=MAX(km_nd_min*deltah2,kmh(i,j,k))
              kmv(i,j,k)=MAX(km_nd_min*tema   ,kmv(i,j,k))
            END IF

            kmh(i,j,k)=MIN(km_nd_max*deltah2, kmh(i,j,k))

            tema=km_nd_max2*tema
            kmv(i,j,k)=MIN(tema   , kmv(i,j,k))

          END DO
        END DO
      END DO

    END IF

  END IF

  3000  CONTINUE
!
!-----------------------------------------------------------------------
!
!  Reset the lateral boundary values of km and rprntl
!
!-----------------------------------------------------------------------
!
!call test_dump (kmh,"XXXtke_kmh",nx,ny,nz,0,0)
!call test_dump (kmv,"XXXtke_kmv",nx,ny,nz,0,0)
!call test_dump (rprntl,"XXXtke_rprntl",nx,ny,nz,0,0)
  IF (mp_opt > 0) THEN
    CALL acct_interrupt(mp_acct)
    CALL mpsend2dew(kmh,nx,ny,nz,ebc,wbc,0,mptag1,tem1)
    CALL mpsend2dew(kmv,nx,ny,nz,ebc,wbc,0,mptag2,tem1)
    CALL mpsend2dew(rprntl,nx,ny,nz,ebc,wbc,0,mptag3,tem1)
    CALL mprecv2dew(kmh,nx,ny,nz,ebc,wbc,0,mptag1,tem1)
    CALL mprecv2dew(kmv,nx,ny,nz,ebc,wbc,0,mptag2,tem1)
    CALL mprecv2dew(rprntl,nx,ny,nz,ebc,wbc,0,mptag3,tem1)
    CALL mpsend2dns(kmh,nx,ny,nz,nbc,sbc,0,mptag1,tem1)
    CALL mpsend2dns(kmv,nx,ny,nz,nbc,sbc,0,mptag2,tem1)
    CALL mpsend2dns(rprntl,nx,ny,nz,nbc,sbc,0,mptag3,tem1)
    CALL mprecv2dns(kmh,nx,ny,nz,nbc,sbc,0,mptag1,tem1)
    CALL mprecv2dns(kmv,nx,ny,nz,nbc,sbc,0,mptag2,tem1)
    CALL mprecv2dns(rprntl,nx,ny,nz,nbc,sbc,0,mptag3,tem1)
  END IF
  CALL acct_interrupt(bc_acct)
  CALL bckmkh(nx,ny,nz,kmh)
  CALL bckmkh(nx,ny,nz,kmv)
  CALL bckmkh(nx,ny,nz,rprntl)
  CALL acct_stop_inter
!call test_dump (kmh,"XXXAtke_kmh",nx,ny,nz,0,1)
!call test_dump (kmv,"XXXAtke_kmv",nx,ny,nz,0,1)
!call test_dump (rprntl,"XXXAtke_rprntl",nx,ny,nz,0,1)

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


SUBROUTINE stgrdscl(nx,ny,nz, zp, grdscl ) 2
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Set the grid scale to be used in turbulence mixing calculations.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  3/11/96
!
!  MODIFICATION HISTORY:
!
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    zp       Vertical coordinate of grid points in physical space (m)
!
!  OUTPUT:
!
!    grdscl   The grid scale using turbulence mixing calculations (m)
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: grdscl(nx,ny,nz)     ! Grid scale (m)
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i, j, k
!
  REAL :: deltah, one3rd, dzp, dxdy3rd
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
!  Set the mixing coefficient, km, to a constant value TMIXCST.
!
!-----------------------------------------------------------------------
!
  one3rd = 1.0/3.0
  deltah = SQRT( dx*dy )
  dxdy3rd =(dx*dy)**one3rd

  IF (trbisotp == 1) THEN  ! isotropic case

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          dzp = zp(i,j,k+1)-zp(i,j,k)
          IF( runmod == 1 ) THEN
            grdscl(i,j,k) = dxdy3rd * dzp**one3rd
          ELSE IF( runmod == 2 ) THEN
            grdscl(i,j,k) = SQRT(dx*dzp)
          ELSE IF( runmod == 3 ) THEN
            grdscl(i,j,k) = SQRT(dy*dzp)
          ELSE IF( runmod == 4 ) THEN
            grdscl(i,j,k) = dzp
          END IF
        END DO
      END DO
    END DO

  ELSE                       ! anisotropic case

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          grdscl(i,j,k) = zp(i,j,k+1)-zp(i,j,k)
        END DO
      END DO
    END DO

  END IF

  RETURN
END SUBROUTINE stgrdscl
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE DEFORM                     ######
!######                                                      ######
!######                     Developed by                     ######
!######  Center for the Analysis and Prediction of Storms    ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!
!


SUBROUTINE deform(nx,ny,nz,u,v,w,mapfct,                                & 1,82
           j1,j2,j3,aj3x,aj3y,aj3z,j3inv,                               &
           d11,d12,d13,d22,d23,d33,d31,d32,defsq,                       &
           tem1,tem2,tem3,tem4,mp_tem)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the deformation tensor components Dij.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  6/25/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  3/21/96 (M. Xue)
!  Moved the calculation of magnitude of deformation (defsq) to
!  from CFTMIX to this routine.
!
!  4/1/96 (Donghai Wang, X. Song and M. Xue)
!  Added a time average weighting coefficient for implicit treatment
!  of vertical mixing.
!
!  6/5/96 (Donghai Wang, M. Xue and X. Song)
!  Fixed a minor bug related to the vertical implicit treatment of
!  turbulence mixing. Should not affect the results much.
!
!  11/06/97 (D. Weber)
!  Added three additional levels to the mapfct array.  The three
!  levels (4,5,6) represent the inverse of the first three in order.
!  The inverse map factors are computed to improve efficiency.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  Added tmixvert option for vertical tmixing only (for large aspect
!  ratio simulations only dx,dy>>dz).
!  -added aj3x,y,z arrays.
!
!  2/15/2002 (Yunheng Wang)
!  Fixed a typo in the first call of mpsend2dew and mprecv2dew 
!  respectively (sbc replaced with wbc).
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    u        x component of velocity at a given time level (m/s)
!    v        y component of velocity at a given time level (m/s)
!    w        Vertical component of velocity in Cartesian
!             coordinates at a given time level (m/s).
!
!    mapfct   Map factors at scalar, u and v points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    aj3z     Avgz of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    d11      Deformation tensor component (1/s)
!    d12      Deformation tensor component (1/s)
!    d13      Deformation tensor component (1/s)
!    d22      Deformation tensor component (1/s)
!    d23      Deformation tensor component (1/s)
!    d31      Deformation tensor component (1/s)
!    d32      Deformation tensor component (1/s)
!    d33      Deformation tensor component (1/s)
!    defsq    Deformation squared (1/s**2)
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  REAL :: u     (nx,ny,nz)     ! Total u-velocity (m/s)
  REAL :: v     (nx,ny,nz)     ! Total v-velocity (m/s)
  REAL :: w     (nx,ny,nz)     ! Total w-velocity (m/s)

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u and v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: aj3z  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Z-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
!
  REAL :: d11   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d12   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d13   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d22   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d23   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d31   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d32   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: d33   (nx,ny,nz)     ! Deformation tensor component (1/s)
  REAL :: defsq (nx,ny,nz)     ! Deformation squared (1/s**2)
!
  REAL :: tem1(nx,ny,nz)       ! Temproary working array
  REAL :: tem2(nx,ny,nz)       ! Temproary working array
  REAL :: tem3(nx,ny,nz)       ! Temproary working array
  REAL :: tem4(nx,ny,nz)       ! Temproary working array
  REAL :: mp_tem(MAX(nx,ny)*nz) ! Message passing work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: tema,temb,temc

  INTEGER :: mptag1,mptag2
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'phycst.inc'
  INCLUDE 'bndry.inc'
  INCLUDE 'mp.inc'            ! Message passing parameters.

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor components Dij, which are stored
!  in arrays dij.
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
!  Calculate the stress tensor component d33
!  d33 = 2./j3 * difz(w)
!
!-----------------------------------------------------------------------
!call test_dump (u,"XXXdeform_u",nx,ny,nz,1,1)
!call test_dump (v,"XXXdeform_v",nx,ny,nz,2,1)
!call test_dump (w,"XXXdeform_w",nx,ny,nz,3,1)

  tema = 2.0*dzinv
  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        d33(i,j,k)=tema*j3inv(i,j,k) * (w(i,j,k+1)-w(i,j,k))
      END DO
    END DO
  END DO

!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor component D11:
!
!   d11 = (2./j3) * m * m * (difx(avgsu(j3) * (u/m)) +
!                           (difz(avgx(j1 * avgsw(u/m)))))
!
!-----------------------------------------------------------------------
!

!-----------------------------------------------------------------------
!
!  Calculate difx(avgsu(j3) * (u/m))
!
!-----------------------------------------------------------------------

  IF(tmixvert == 0)THEN   !  compute the horizontal terms also....

    DO k=1,nz-1     ! difx (avgx(j3)*u*mapfct)
      DO j=1,ny-1
        DO i=1,nx-1
          d11(i,j,k) = dxinv*(aj3x(i+1,j,k)*u(i+1,j,k)*mapfct(i+1,j,5)  &
                            - aj3x(i,j,k)  *u(i,j,k)  *mapfct(i,j,5) )
        END DO
      END DO
    END DO

!
!  At this point, D11 = difx(avgsu(j3) * (u/m))
!

    IF( ternopt /= 0 ) THEN  ! add in the terrain term.......

!-----------------------------------------------------------------------
!
!  Calculate the second term of d11
!  difz(avgx(j1 * avgsw(u/m)))  ! note 1/m comes outside difz...
!  NOTE:avgsw(u) is stored in d32 and will be used in the
!       third term of d12 later...
!
!-----------------------------------------------------------------------

      DO k=2,nz-1    ! average u in z-dir.
        DO j=1,ny-1
          DO i=1,nx
            d32(i,j,k) = 0.5*(u(i,j,k)+u(i,j,k-1))
          END DO
        END DO
      END DO

!call test_dump (d32,"XXXtke_d32a",nx,ny,nz,2,0)
!call test_dump (d32,"XXXtke_d32b",nx,ny,nz,3,0)
      CALL acct_interrupt(bc_acct)
      CALL bcsw(nx,ny,nz,1,nx,1,ny-1,tbc,bbc,d32)
      CALL acct_stop_inter
!call test_dump (d32,"XXXAtke_d32a",nx,ny,nz,2,1)
!call test_dump (d32,"XXXAtke_d32b",nx,ny,nz,3,1)

      DO k=1,nz      ! average j1*d32 in x-dir.
        DO j=1,ny-1
          DO i=1,nx-1
            tem2(i,j,k) = 0.5*(j1(i+1,j,k)*d32(i+1,j,k)                 &
                             + j1(i  ,j,k)*d32(i  ,j,k))
          END DO
        END DO
      END DO

!-----------------------------------------------------------------------
!
!  Combine the terms, ( 2 /j3)* m * (m * d11 + difz(tem2)) to form
!  the final D11 stress tensor
!
!-----------------------------------------------------------------------

      tema = 2.0*dzinv
      DO k=1,nz-1      ! difz(tem2).
        DO j=1,ny-1
          DO i=1,nx-1
            d11(i,j,k) = 2.0*j3inv(i,j,k)*mapfct(i,j,1)*                &
                (mapfct(i,j,1)*d11(i,j,k)+dzinv*(tem2(i,j,k+1)-tem2(i,j,k)))
          END DO
        END DO
      END DO   ! d11 with terrain is complete...

    ELSE

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1
            d11(i,j,k) = 2.0*j3inv(i,j,k)*mapfct(i,j,7)*d11(i,j,k)
          END DO
        END DO
      END DO   ! d11 w/o terrain is complete...


    END IF   ! end of terrain if block for d11.....

!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor component d22:
!
!   d22 = (2./j3) * m * m *(dify(avgsv(j3) * (v/m)) +
!                           difz(avgy(j2) * avgsw(v/m)))
!
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Calculate the first term in D22
!  dify(avgsv(j3) * (v/m))
!  NOTE:avgsv(j3) is stored in d23 and will be used in the second
!       term of d12 later...
!
!-----------------------------------------------------------------------

    DO k=1,nz-1        ! dify(d23*v*mapfct)
      DO j=1,ny-1
        DO i=1,nx-1
          d22(i,j,k) = dyinv*(aj3y(i,j+1,k)*v(i,j+1,k)*mapfct(i,j+1,6)  &
                           -  aj3y(i,j,k)  *v(i,j,k)  *mapfct(i,j,6) )
        END DO
      END DO
    END DO

!
!  At this point, D22 = dify(avgsv(j3) * v/m)
!

    IF( ternopt /= 0 ) THEN

!-----------------------------------------------------------------------
!
!  Calculate the second term of d22
!  difz(avgy(j2 * avgsw(v/m)))  Note: 1/m comes outside difz..
!  NOTE:avgsw(v) is stored in d31 and will be used in the
!       third term of d12 later...
!
!-----------------------------------------------------------------------

      DO k=2,nz-1    ! average v in z-dir.
        DO j=1,ny
          DO i=1,nx-1
            d31(i,j,k) = 0.5*(v(i,j,k)+v(i,j,k-1))
          END DO
        END DO
      END DO

!call test_dump (d31,"XXXtke_d31a",nx,ny,nz,1,0)
!call test_dump (d31,"XXXtke_d31b",nx,ny,nz,3,0)
      CALL acct_interrupt(bc_acct)
      CALL bcsw(nx,ny,nz,1,nx-1,1,ny,tbc,bbc,d31)
      CALL acct_stop_inter
!call test_dump (d31,"XXXAtke_d31a",nx,ny,nz,1,1)
!call test_dump (d31,"XXXAtke_d31b",nx,ny,nz,3,1)

      DO k=1,nz      ! average j2*d31 in y-dir.
        DO j=1,ny-1
          DO i=1,nx-1
            tem2(i,j,k) = 0.5*(j2(i,j+1,k)*d31(i,j+1,k)                 &
                             + j2(i,j,k)  *d31(i,j,k))
          END DO
        END DO
      END DO

!-----------------------------------------------------------------------
!
!  Combine terms 2./j3 * m * (m*D22 + difz(tem2)) to obtain the final
!  D22 deformation tensor
!
!-----------------------------------------------------------------------

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1
            d22(i,j,k)= 2.0*j3inv(i,j,k)*mapfct(i,j,1)*                 &
                          (mapfct(i,j,1)*d22(i,j,k)                     &
                   +dzinv*(tem2(i,j,k+1)-tem2(i,j,k)))
          END DO
        END DO
      END DO    ! d22 with terrain is complete

    ELSE

      DO k=1,nz-1
        DO j=1,ny-1
          DO i=1,nx-1
            d22(i,j,k)= 2.0*j3inv(i,j,k)*mapfct(i,j,7)*d22(i,j,k)
          END DO
        END DO
      END DO    ! d22 w/o terrain is complete

    END IF   ! end of d22 terrain if block.......


!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor d12
!
!  d12 = m*m/(avgsv(avgsu(j3))) *
!         (dify(avgsu(j3) * u/m) + difx(avgsv(j3) * v/m)
!        + difz(avgsu(j2) * avgsv(avgsw(u/m))
!        +      avgsv(j1) * avgsu(avgsw(v/m))))
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Note: In order to reduce memory usage, order dependence has been
!  introduced into the calculation of D12, which reduces the possible
!  term-wise parallellism.  This is due to the constraint of only two
!  temporary arrays being avaliable for passage into this subroutine.
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0 ) THEN

!-----------------------------------------------------------------------
!
!  Calculate the first sub-term of the third term of D12
!  avgsu(j2) * avgsv(avgsw(u/m)), this term is zero when ternopt=0
!  and
!  Calculate the second sub-term in the third term of d12
!  avgsv(j1) * avgsu(avgsw(v/m)), this term is zero when ternopt=0
!  Note: from above avgsw(u) = d32
!  Note: from above avgsw(v) = d31
!  NOTE: ORDER IS VERY IMPORTANT!!
!
!-----------------------------------------------------------------------

      DO k=1,nz      ! average j2 in x-dir.
        DO j=1,ny
          DO i=2,nx-1
            tem1(i,j,k) = 0.5*(j2(i,j,k)+j2(i-1,j,k))
          END DO
        END DO
      END DO

!call test_dump (tem1,"XXXtke_tem1",nx,ny,nz,1,0)
      IF (mp_opt > 0) THEN
        CALL acct_interrupt(mp_acct)
        CALL mpsend2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
        CALL mprecv2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
      END IF
      CALL acct_interrupt(bc_acct)
      CALL bcsu(nx,ny,nz,1,ny,1,nz,ebc,wbc,tem1)
      CALL acct_stop_inter
!call test_dump (tem1,"XXXAtke_tem1",nx,ny,nz,1,1)

      DO k=1,nz    ! average u in y-dir.
        DO j=2,ny-1
          DO i=1,nx
            tem2(i,j,k) = 0.5*(d32(i,j,k)*mapfct(i,j,5)                 &
                              +d32(i,j-1,k)*mapfct(i,j-1,5))
          END DO
        END DO
      END DO   ! d32 is available for use...

!call test_dump (tem2,"XXXtke_tem2",nx,ny,nz,2,0)
      IF (mp_opt > 0) THEN
        CALL acct_interrupt(mp_acct)
        CALL mpsend2dns(tem2,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
        CALL mprecv2dns(tem2,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
      END IF
      CALL acct_interrupt(bc_acct)
      CALL bcsv(nx,ny,nz,1,nx,1,nz,nbc,sbc,tem2)
      CALL acct_stop_inter
!call test_dump (tem2,"XXXAtke_tem2",nx,ny,nz,2,1)

      DO k=1,nz    ! average v in x-dir.
        DO j=1,ny
          DO i=2,nx-1
            tem4(i,j,k) = 0.5*(d31(i,j,k)* mapfct(i,j,6)                &
                              +d31(i-1,j,k)* mapfct(i-1,j,6))
          END DO
        END DO
      END DO   ! d31 is available for use...

!call test_dump (tem4,"XXXtke_tem4",nx,ny,nz,1,0)
      IF (mp_opt > 0) THEN
        CALL acct_interrupt(mp_acct)
        CALL mpsend2dew(tem4,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
        CALL mprecv2dew(tem4,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
      END IF
      CALL acct_interrupt(bc_acct)
      CALL bcsu(nx,ny,nz,1,ny,1,nz,ebc,wbc,tem4)
      CALL acct_stop_inter
!call test_dump (tem4,"XXXAtke_tem4",nx,ny,nz,1,1)

      DO k=1,nz    ! average j1 in y-dir.
        DO j=2,ny-1
          DO i=1,nx
            tem3(i,j,k) = 0.5*(j1(i,j,k)+j1(i,j-1,k))
          END DO
        END DO
      END DO

!call test_dump (tem3,"XXXtke_tem3",nx,ny,nz,2,0)
      IF (mp_opt > 0) THEN
        CALL acct_interrupt(mp_acct)
        CALL mpsend2dns(tem3,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
        CALL mprecv2dns(tem3,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
      END IF
      CALL acct_interrupt(bc_acct)
      CALL bcsv(nx,ny,nz,1,nx,1,nz,nbc,sbc,tem3)
      CALL acct_stop_inter
!call test_dump (tem3,"XXXAtke_tem3",nx,ny,nz,2,1)

      DO k=1,nz-1    ! difz of the third term...
        DO j=1,ny
          DO i=1,nx
            d12(i,j,k) = dzinv*((tem1(i,j,k+1)*tem2(i,j,k+1)            &
                                +tem3(i,j,k+1)*tem4(i,j,k+1))           &
                               -(tem1(i,j,k)*tem2(i,j,k)                &
                                +tem3(i,j,k)*tem4(i,j,k)))
          END DO
        END DO
      END DO

    ELSE

      DO k=1,nz-1
        DO j=1,ny
          DO i=1,nx
            d12(i,j,k)=0.0
          END DO
        END DO
      END DO

    END IF    ! end of the terrain if block for d12....
!
!  At this point, d12 = the third term of d12
!

!-----------------------------------------------------------------------
!
!  Calculate the first and second terms in d12
!    (dify(avgsu(j3) * u/m) + difx(avgsv(j3) * v/m)
!  NOTE: D13 contains avgsu(j3) and
!        D23 contains avgsv(j3)
!
!-----------------------------------------------------------------------

    DO k=1,nz-1    ! dify(avgsu(j3) * u/m)
      DO j=2,ny-1
        DO i=1,nx
          tem2(i,j,k) = dyinv*(aj3x(i,j,k)*u(i,j,k)*mapfct(i,j,5)       &
                         - aj3x(i,j-1,k)*u(i,j-1,k)*mapfct(i,j-1,5))
        END DO
      END DO
    END DO    ! d13 is available for use

!call test_dump (tem2,"XXX1tke_tem2",nx,ny,nz,2,0)
    IF (mp_opt > 0) THEN
      CALL acct_interrupt(mp_acct)
      CALL mpsend2dns(tem2,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
      CALL mprecv2dns(tem2,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
    END IF
    CALL acct_interrupt(bc_acct)
    CALL boundv (tem2,nx,ny,nz, 1,nx, 1,nz-1)
    CALL acct_stop_inter
!call test_dump (tem2,"XXX1Atke_tem2",nx,ny,nz,2,1)

    DO k=1,nz-1    ! difx(avgsv(j3) * v/m)
      DO j=1,ny
        DO i=2,nx-1
          tem1(i,j,k) = dxinv*(aj3y(i,j,k)*v(i,j,k)*mapfct(i,j,6)       &
                         - aj3y(i-1,j,k)*v(i-1,j,k)*mapfct(i-1,j,6))
        END DO
      END DO
    END DO    ! d23 is available for use

!call test_dump (tem1,"XXX1tke_tem1",nx,ny,nz,1,0)
    IF (mp_opt > 0) THEN
      CALL acct_interrupt(mp_acct)
      CALL mpsend2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
      CALL mprecv2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
    END IF
    CALL acct_interrupt(bc_acct)
    CALL boundu (tem1,nx,ny,nz, 1,ny, 1,nz-1)
    CALL acct_stop_inter
!call test_dump (tem1,"XXX1Atke_tem1",nx,ny,nz,1,1)

!-----------------------------------------------------------------------
!
!  Combine the d12 terms
!
!-----------------------------------------------------------------------

    DO k=1,nz-1
      DO j=1,ny
        DO i=1,nx
          d12(i,j,k)= d12(i,j,k)+tem1(i,j,k)+tem2(i,j,k)
        END DO
      END DO
    END DO

!
!  At this point, d12 = first + second + third terms of d12
!

!-------------------------------------------------------------------
!
!  Calculate the coefficient of d12
!  avgsv(avgsu(j3*mapfct**2))
!
!-------------------------------------------------------------------

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tem2(i,j,k) = j3inv(i,j,k) * mapfct(i,j,7)
        END DO
      END DO
    END DO

    CALL avgsu(tem2,nx,ny,nz, 1,ny-1, 1,nz-1, tem1, tem4)

!call test_dump (tem1,"XXXbavgsv_tem1",nx,ny,nz,0,1)
    CALL avgsv(tem1,nx,ny,nz, 1,nx, 1,nz-1, tem3, tem4)

!  Compute the final d12 = d12 * tem2

    DO k=1,nz-1
      DO j=1,ny
        DO i=1,nx
          d12(i,j,k)=d12(i,j,k)*tem3(i,j,k)
        END DO
      END DO
    END DO

  ELSE   ! zero the horizontal mixing terms....
         ! needed for the deformation computation below....

    DO k=1,nz-1
      DO j=1,ny
        DO i=1,nx
          d11(i,j,k)=0.0
          d22(i,j,k)=0.0
          d12(i,j,k)=0.0
        END DO
      END DO
    END DO

  END IF  !  end if tmixvert if block for d12....

!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor d13
!  d13 = m/ avgsw(avgsu(j3)) * (difx(avgsw(j3) * w) +
!        difz(u/m + avgz(j1 * (avgsu(w)))))
!
!-----------------------------------------------------------------------

!-------------------------------------------------------------------
!
!  Compute the first term of d13
!  difx(avgsw(j3) * w)
!
!-------------------------------------------------------------------

  DO k=1,nz   ! difx (avgz(j3)*w)
    DO j=1,ny-1
      DO i=2,nx-1
        d13(i,j,k)=dxinv*(aj3z(i,j,k)*w(i,j,k)-                         &
                          aj3z(i-1,j,k)*w(i-1,j,k))
      END DO
    END DO
  END DO

!call test_dump (d13,"XXXtke_d13",nx,ny,nz,1,0)
  IF (mp_opt > 0) THEN
    CALL acct_interrupt(mp_acct)
    CALL mpsend2dew(d13,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
    CALL mprecv2dew(d13,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
  END IF
  CALL acct_interrupt(bc_acct)
  CALL boundu(d13,nx,ny,nz, 1,ny-1, 1,nz)
  CALL acct_stop_inter
!call test_dump (d13,"XXXAtke_d13",nx,ny,nz,1,1)

!
!  At this point D23 = difx(avgsw(j3) * w)  for term d13
!

!-----------------------------------------------------------------------
!
!  Compute the second term of d13
!  difz(u + avgz(j1 * (avgsu(w))))
!
!-----------------------------------------------------------------------

  IF( ternopt /= 0 ) THEN

    DO k=1,nz    ! average w in x-dir.
      DO j=1,ny-1
        DO i=2,nx-1
          tem1(i,j,k) = 0.5*(w(i,j,k)+w(i-1,j,k))
        END DO
      END DO
    END DO

!call test_dump (tem1,"XXX1tke_tem1",nx,ny,nz,1,0)
    IF (mp_opt > 0) THEN
      CALL acct_interrupt(mp_acct)
      CALL mpsend2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
      CALL mprecv2dew(tem1,nx,ny,nz,ebc,wbc,1,mptag1,mp_tem)
    END IF
    CALL acct_interrupt(bc_acct)
    CALL bcsu(nx,ny,nz,1,ny-1,1,nz,ebc,wbc,tem1)
    CALL acct_stop_inter
!call test_dump (tem1,"XXX1Atke_tem1",nx,ny,nz,1,1)

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx
          tem2(i,j,k) = 0.5*(tem1(i,j,k+1)*j1(i,j,k+1)                  &
                           + tem1(i,j,k)*j1(i,j,k) )
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Compute u + tem2
!
!-----------------------------------------------------------------------

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx
          tema = u(i,j,k)*mapfct(i,j,5)
          tem3(i,j,k)=tema+tem2(i,j,k)
          tem2(i,j,k)=alfcoef*tema+tem2(i,j,k)
        END DO
      END DO
    END DO

  ELSE   ! If ternopt=0, tem2=0

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx
          tem3(i,j,k)=u(i,j,k)*mapfct(i,j,5)
          tem2(i,j,k)=alfcoef* tem3(i,j,k)
        END DO
      END DO
    END DO

  END IF

  DO k=2,nz-1
    DO j=1,ny-1
      DO i=1,nx
        tem1(i,j,k)=dzinv*(tem2(i,j,k)-tem2(i,j,k-1))
        tem4(i,j,k)=dzinv*(tem3(i,j,k)-tem3(i,j,k-1))
      END DO
    END DO
  END DO

!call test_dump (tem1,"XXX2tke_tem1",nx,ny,nz,3,0)
!call test_dump (tem4,"XXX2tke_tem4",nx,ny,nz,3,0)
  CALL acct_interrupt(bc_acct)
  CALL boundw(tem1,nx,ny,nz, 1,nx, 1,ny-1)
  CALL boundw(tem4,nx,ny,nz, 1,nx, 1,ny-1)
  CALL acct_stop_inter
!call test_dump (tem1,"XXX2Atke_tem1",nx,ny,nz,3,1)
!call test_dump (tem4,"XXX2Atke_tem4",nx,ny,nz,3,1)

!-----------------------------------------------------------------------
!
!  Compute d13 + tem1
!
!-----------------------------------------------------------------------

  DO k=1,nz
    DO j=1,ny-1
      DO i=1,nx
        d31(i,j,k)=d13(i,j,k)+tem4(i,j,k)
        d13(i,j,k)=d13(i,j,k)+tem1(i,j,k)
      END DO
    END DO
  END DO

!
!  At this point, D13 = first and second terms of d13
!

!-----------------------------------------------------------------------
!
!  Compute the coefficient of d13
!  avgsw(avgsu(j3))
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=1,ny-1
      DO i=1,nx
        tem2(i,j,k)=0.5*(aj3x(i,j,k)+aj3x(i,j,k-1))
      END DO
    END DO
  END DO

!call test_dump (tem2,"XXX3tke_tem2",nx,ny,nz,3,0)
  CALL acct_interrupt(bc_acct)
  CALL bcsw(nx,ny,nz,1,nx,1,ny,tbc,bbc,tem2)
  CALL acct_stop_inter
!call test_dump (tem2,"XXX3Atke_tem2",nx,ny,nz,3,1)


!-----------------------------------------------------------------------
!
!  Compute the final d13 tensor = d13 / tem2
!  Note: the limits have been changed from 1,nz to 2,nz-1....
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=1,ny-1
      DO i=1,nx
        tema = mapfct(i,j,2)/tem2(i,j,k)
        d13(i,j,k)=d13(i,j,k)*tema
        d31(i,j,k)=d31(i,j,k)*tema
      END DO
    END DO
  END DO

!-----------------------------------------------------------------------
!
!  Calculate the deformation tensor d23
!  d23 = m/ avgsw(avgsv(j3)) * (dify(avgsw(j3) * w) +
!            difz(v/m + avgz(j2 * (avgsv(w)))))
!
!-----------------------------------------------------------------------

!-------------------------------------------------------------------
!
!  Compute the first term of d23
!  dify(avgsw(j3) * w)
!  NOTE: d32 = avgsw(j3)
!
!-------------------------------------------------------------------

  DO k=1,nz   ! dify (avgsw(j3)*w)
    DO j=2,ny-1
      DO i=1,nx-1
        d23(i,j,k)=dyinv*(aj3z(i,j,k)*w(i,j,k)-                         &
                          aj3z(i,j-1,k)*w(i,j-1,k))
      END DO
    END DO
  END DO

!call test_dump (d23,"XXX1tke_d23",nx,ny,nz,2,0)
  IF (mp_opt > 0) THEN
    CALL acct_interrupt(mp_acct)
    CALL mpsend2dns(d23,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
    CALL mprecv2dns(d23,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
  END IF
!call test_dump (d23,"XXXB1d32_d23a",nx,ny,nz,2,0)
  CALL acct_interrupt(bc_acct)
  CALL boundv(d23,nx,ny,nz, 1,nx-1, 1,nz)
  CALL acct_stop_inter
!call test_dump (d23,"XXX1Atke_d23",nx,ny,nz,2,1)
!call test_dump (d23,"XXX1d32_d23a",nx,ny,nz,2,0)

!
!  At this point d23 = dify(avgsw(j3) * w)
!

!-----------------------------------------------------------------------
!
!  Compute the second term of D23
!  difz(v + avgz(j2 * (avgsv(w))))
!
!-----------------------------------------------------------------------

  IF( ternopt /= 0 ) THEN

    DO k=1,nz
      DO j=2,ny-1
        DO i=1,nx-1
          tem1(i,j,k)=0.5*(w(i,j,k)+w(i,j-1,k))
        END DO
      END DO
    END DO

!call test_dump (tem1,"XXX3tke_tem1",nx,ny,nz,2,0)
    IF (mp_opt > 0) THEN
      CALL acct_interrupt(mp_acct)
      CALL mpsend2dns(tem1,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
      CALL mprecv2dns(tem1,nx,ny,nz,nbc,sbc,2,mptag1,mp_tem)
    END IF
    CALL acct_interrupt(bc_acct)
    CALL bcsv(nx,ny,nz,1,nx-1,1,nz,nbc,sbc,tem1)
    CALL acct_stop_inter
!call test_dump (tem1,"XXX3Atke_tem1",nx,ny,nz,2,1)

    DO k=1,nz-1   ! avgz (j2*avgsv(w))
      DO j=1,ny
        DO i=1,nx-1
          tem2(i,j,k)=0.5*(j2(i,j,k)  *tem1(i,j,k)                      &
                         + j2(i,j,k+1)*tem1(i,j,k+1))
        END DO
      END DO
    END DO

    DO k=1,nz-1
      DO j=1,ny
        DO i=1,nx-1
          tema = v(i,j,k)*mapfct(i,j,6)
          tem3(i,j,k)=tema +tem2(i,j,k)
          tem2(i,j,k)=alfcoef * tema +tem2(i,j,k)
        END DO
      END DO
    END DO


  ELSE   ! When ternopt.eq.0, tem2=0

    DO k=1,nz-1
      DO j=1,ny
        DO i=1,nx-1
          tem3(i,j,k)=v(i,j,k)*mapfct(i,j,6)
          tem2(i,j,k)=alfcoef * tem3(i,j,k)
        END DO
      END DO
    END DO

  END IF

  DO k=2,nz-1
    DO j=1,ny
      DO i=1,nx-1
        tem1(i,j,k)=dzinv*(tem2(i,j,k)-tem2(i,j,k-1))
        tem4(i,j,k)=dzinv*(tem3(i,j,k)-tem3(i,j,k-1))
      END DO
    END DO
  END DO

  CALL acct_interrupt(bc_acct)
  CALL boundw(tem1,nx,ny,nz, 1,nx-1, 1,ny)
  CALL boundw(tem4,nx,ny,nz, 1,nx-1, 1,ny)
  CALL acct_stop_inter
!call test_dump (tem1,"XXX4Atke_tem1",nx,ny,nz,3,1)
!call test_dump (tem4,"XXX4Atke_tem4",nx,ny,nz,3,1)

!-----------------------------------------------------------------------
!
!    Compute d23 + tem1
!
!-----------------------------------------------------------------------

  DO k=1,nz
    DO j=1,ny
      DO i=1,nx-1
        d32(i,j,k)=d23(i,j,k)+tem4(i,j,k)
        d23(i,j,k)=d23(i,j,k)+tem1(i,j,k)
      END DO
    END DO
  END DO
!call test_dump (tem4,"XXXd32_tem4a",nx,ny,nz,2,0)
!call test_dump (tem4,"XXXd32_tem4b",nx,ny,nz,3,0)
!call test_dump (d23,"XXXd32_d23a",nx,ny,nz,2,0)
!call test_dump (d23,"XXXd32_d23b",nx,ny,nz,3,0)

!
!  At this point, d23 = first + second terms of d23
!

!-----------------------------------------------------------------------
!
!  Compute the coefficient of d23
!  avgsw(avgsv(j3))
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=1,ny
      DO i=1,nx-1
        tem2(i,j,k)= 0.5*(aj3y(i,j,k)+aj3y(i,j,k-1))
      END DO
    END DO
  END DO

!call test_dump (tem2,"XXX5tke_tem2",nx,ny,nz,3,0)
  CALL acct_interrupt(bc_acct)
  CALL bcsw(nx,ny,nz,1,nx-1,1,ny,tbc,bbc,tem2)
  CALL acct_stop_inter
!call test_dump (tem2,"XXX5Atke_tem2",nx,ny,nz,3,1)

!-----------------------------------------------------------------------
!
!  Compute the final d23 deformation tensor d23 = d23 / tem2
!
!-----------------------------------------------------------------------

  DO k=1,nz
    DO j=1,ny
      DO i=1,nx-1
        tema = mapfct(i,j,3)/tem2(i,j,k)
        d23(i,j,k)=d23(i,j,k)*tema
        d32(i,j,k)=d32(i,j,k)*tema
      END DO
    END DO
  END DO

!-----------------------------------------------------------------------
!
!  Calculate the magnitude of deformation squared, Def**2.
!
!-----------------------------------------------------------------------

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        tema = (d12(i,j,k)+d12(i,j+1,k))                                &
              +(d12(i+1,j,k)+d12(i+1,j+1,k))
        temb = (d31(i,j,k)+d31(i,j,k+1))                                &
              +(d31(i+1,j,k)+d31(i+1,j,k+1))
        temc = (d32(i,j,k)+d32(i,j+1,k))                                &
              +(d32(i,j,k+1)+d32(i,j+1,k+1))

        defsq(i,j,k) =(d11(i,j,k)*d11(i,j,k)                            &
                      +d22(i,j,k)*d22(i,j,k)                            &
                      +d33(i,j,k)*d33(i,j,k))*0.5                       &
                      +(tema*tema+temb*temb+temc*temc)*0.0625
      END DO
    END DO
  END DO
!call test_dump (defsq,"XXXdeform_defsq",nx,ny,nz,0,0)
!call test_dump (d11,"XXXdeform_d11",nx,ny,nz,0,0)
!call test_dump (d12,"XXXdeform_d12a",nx,ny,nz,1,0)
!call test_dump (d12,"XXXdeform_d12b",nx,ny,nz,2,0)
!call test_dump (d22,"XXXdeform_d22",nx,ny,nz,0,0)
!call test_dump (d31,"XXXdeform_d31a",nx,ny,nz,1,0)
!call test_dump (d31,"XXXdeform_d31b",nx,ny,nz,3,0)
!call test_dump (d32,"XXXdeform_d32a",nx,ny,nz,2,0)
!call test_dump (d32,"XXXdeform_d32b",nx,ny,nz,3,0)
!call test_dump (d33,"XXXdeform_d33",nx,ny,nz,0,0)


  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        d33(i,j,k)=alfcoef * d33(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE deform


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


SUBROUTINE stress(nx,ny,nz,j3,j3inv,                                    & 1,6
           kmh,kmv,rhostr,tau11,tau12,tau13,tau22,tau23,tau33,          &
           tau31,tau32,                                                 &
           tem1, tem2, tem3, rjkmh, rjkmv)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the stress tensor tauij from deformation tensor
!  Dij (input as tauij).
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  6/26/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  3/21/96 (Ming Xue)
!  Added work arrays rjkmh and rjkmv. Simplified the code.
!
!  6/5/96 (Donghai Wang, M. Xue and X. Song)
!  Fixed a minor bug related to the vertical implicit treatment of
!  turbulence mixing. Should not affect the results much.
!
!  8/27/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tem3
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    j3       Coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!    km       Turbulent mixing coefficient for momentum ( m**2/s ).
!    rhostr   Base state air density times j3 (kg/m**3).
!
!    tau11    Deformation tensor component (1/s)
!    tau12    Deformation tensor component (1/s)
!    tau13    Deformation tensor component (1/s)
!    tau22    Deformation tensor component (1/s)
!    tau23    Deformation tensor component (1/s)
!    tau33    Deformation tensor component (1/s)
!
!
!  OUTPUT:
!
!    tau11    Stress tensor component (kg/(m*s**2))
!    tau12    Stress tensor component (kg/(m*s**2))
!    tau13    Stress tensor component (kg/(m*s**2))
!    tau22    Stress tensor component (kg/(m*s**2))
!    tau23    Stress tensor component (kg/(m*s**2))
!    tau33    Stress tensor component (kg/(m*s**2))
!
!  WORKING ARRAYS:
!
!    tem1     Temporary working array
!    tem2     Temporary working array
!    tem3     Temporary working array
!    rjkmh    rhostr/j3*kmh
!    rjkmv    rhostr/j3*kmv
!
!  (These arrays are defined and used locally (i.e. inside this
!   subroutine), they may also be passed into routines called by
!   this one. Exiting the call to this subroutine, these temporary
!   working arrays may be used for other purposes therefore their
!   contents overwritten. Please examine the usage of working arrays
!   before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )

  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3(kg/m**3)
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
!
  REAL :: tau11 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau12 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau13 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau22 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau23 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau33 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau31 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))
  REAL :: tau32 (nx,ny,nz)     ! Deformation and stress tensor
                               ! component (kg/(m*s**2))

  REAL :: tem1  (nx,ny,nz)     ! Temporary working array
  REAL :: tem2  (nx,ny,nz)     ! Temporary working array
  REAL :: tem3  (nx,ny,nz)     ! Temporary working array
  REAL :: rjkmh (nx,ny,nz)     ! rhostr/j3*kmh
  REAL :: rjkmv (nx,ny,nz)     ! rhostr/j3*kmv
!
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'phycst.inc'
  INCLUDE 'bndry.inc'
  INCLUDE 'mp.inc'            ! Message passing parameters.

!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau11, Tau22 and Tau33.
!
!  tau11 = rhostr/j3*kmh*d11
!  tau22 = rhostr/j3*kmh*d22
!  tau33 = rhostr/j3*kmv*d33
!
!-----------------------------------------------------------------------

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        rjkmv(i,j,k)=rhostr(i,j,k)*j3inv(i,j,k)*kmv(i,j,k)
        tau33(i,j,k)=tau33(i,j,k)*rjkmv(i,j,k)
      END DO
    END DO
  END DO

  IF( tmixvert == 0)THEN   ! compute the horizontal terms...

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          rjkmh(i,j,k)=rhostr(i,j,k)*j3inv(i,j,k)*kmh(i,j,k)
          tau11(i,j,k)=tau11(i,j,k)*rjkmh(i,j,k)
          tau22(i,j,k)=tau22(i,j,k)*rjkmh(i,j,k)
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau12.
!  tau12 = avgsv(avgsu(rhostr/j3*kmh)) * d12
!
!-----------------------------------------------------------------------

    DO k=1,nz-1   ! note: do not overwrite tem3...
      DO j=1,ny-1
        DO i=2,nx-1
          tem3(i,j,k)=0.5*(rjkmh(i,j,k)+rjkmh(i-1,j,k))
        END DO
      END DO
    END DO        ! tem3 is used below...

    DO k=1,nz-1
      DO j=2,ny-1
        DO i=2,nx-1
          tem2(i,j,k)=0.5*(tem3(i,j,k)+tem3(i,j-1,k))
        END DO
      END DO
    END DO

    DO k=1,nz-1
      DO j=2,ny-1
        DO i=2,nx-1
          tau12(i,j,k)=tem2(i,j,k)*tau12(i,j,k)
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau31.
!  tau31 = avgsw(avgsu(rhostr/j3*kmh)) * d31
!
!  Note:  avgsu(rhostr/j3*kmh) is stored in tem3 from above...
!
!-----------------------------------------------------------------------

    DO k=2,nz-1
      DO j=2,ny-2
        DO i=2,nx-1
          tem2(i,j,k)=0.5*(tem3(i,j,k)+tem3(i,j,k-1))
        END DO
      END DO
    END DO   ! tem3 is used below... -- ??? can't find it [GMB]

    CALL acct_interrupt(bc_acct)
    CALL bcsw(nx,ny,nz,2,nx-1,2,ny-2,tbc,bbc,tem2)
    CALL acct_stop_inter
!call test_dump (tem2,"XXX6Atke_tem2",nx,ny,nz,3,0)

    DO k=1,nz
      DO j=2,ny-2
        DO i=2,nx-1
          tau31(i,j,k)=tem2(i,j,k)*tau31(i,j,k)
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau32.
!  tau32 = avgsw(avgsv(rhostr/j3*kmh)) * d32
!
!-----------------------------------------------------------------------

    DO k=2,nz-1
      DO j=2,ny-1
        DO i=2,nx-2
          tem1(i,j,k)=0.25*((rjkmh(i,j,k)  +rjkmh(i,j-1,k))             &
                           +(rjkmh(i,j,k-1)+rjkmh(i,j-1,k-1)))
        END DO
      END DO
    END DO

    CALL acct_interrupt(bc_acct)
    CALL bcsw(nx,ny,nz,2,nx-2,2,ny-1,tbc,bbc,tem1)
    CALL acct_stop_inter
!call test_dump (tem1,"XXX7Atke_tem1",nx,ny,nz,3,0)

    DO k=1,nz
      DO j=2,ny-1
        DO i=2,nx-2
          tau32(i,j,k)=tau32(i,j,k)*tem1(i,j,k)
        END DO
      END DO
    END DO

  END IF     ! end of tmixvert if block...

!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau13.
!  tau13 = avgsw(avgsu(rhostr/j3*kmv)) * d13
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=2,ny-2
      DO i=2,nx-1
        tem2(i,j,k)=0.25*((rjkmv(i,j,k)+rjkmv(i-1,j,k))+                &
                          (rjkmv(i,j,k-1)+rjkmv(i-1,j,k-1)))
      END DO
    END DO
  END DO

  DO k=2,nz-1
    DO j=2,ny-2
      DO i=2,nx-1
        tau13(i,j,k)=tau13(i,j,k)*tem2(i,j,k)
      END DO
    END DO
  END DO

!-----------------------------------------------------------------------
!
!  Calculate the stress tensor Tau23.
!  tau23 = avgsw(avgsv(rhostr/j3*kmv)) * d23
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=2,ny-1
      DO i=2,nx-2
        tem1(i,j,k)=0.25*((rjkmv(i,j,k)+rjkmv(i,j-1,k))+                &
                          (rjkmv(i,j,k-1)+rjkmv(i,j-1,k-1)))
      END DO
    END DO
  END DO

  DO k=2,nz-1
    DO j=2,ny-1
      DO i=2,nx-2
        tau23(i,j,k)=tau23(i,j,k)*tem1(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE stress


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


SUBROUTINE tmixpt (nx,ny,nz,ptprt,ptbar,rhostr,kmh,kmv,rprntl,          & 1,2
           usflx,vsflx,ptsflx,pbldpth,                                  &
           x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,j3inv,ptsfc,            &
           ptmix,                                                       &
           h1,h2,h3, tem1,tem2,tem3)
!
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term for the potential
!  temperature equation. The term is expressed in terms of turbulent
!  heat fluxes.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/20/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  6/16/93 (MX)
!  Break down into subroutine calls.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  3/16/96 (Ming Xue)
!  The model can now include the surface fluxes with the turbulent
!  mxing option off (tmixopt=0).
!
!  3/27/1998 (M. Xue)
!  Added option tqflxdis for quadratic distribution of heat
!  and moisture fluxes in depth dtqflxdis, which is typically
!  set to 200 m.
!
!  9/18/98 (D. Weber)
!  Added arrays aj3x,y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    ptprt    Perturbation potential temperature at a given time level (K)
!    ptbar    Base state potential temperature (K)
!    rhostr   Base state air density times j3 (kg/m**3)
!
!    usflx    Surface flux of u-momentum
!    vsflx    Surface flux of v-momentum
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    ptsflx   Surface flux of heat (K*kg/(m**2*s))
!    pbldpth  Planetary boundary layer depth (m)
!
!  OUTPUT:
!
!    ptmix    Total mixing in potential temperature
!             equation (K*kg/(m**3*s)).
!
!  WORK ARRAYS:
!
!    h1       Turbulent heat flux, a local array.
!    h2       Turbulent heat flux, a local array.
!    h3       Turbulent heat flux, a local array.
!    tem1     Temporary work array
!    tem2     Temporary work array
!    tem3     Temporary work array
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes, and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature (K)
  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3 (kg/m**3)
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: usflx(nx,ny)         ! Surface flux of u momentum
  REAL :: vsflx(nx,ny)         ! surface flux of v momentum
  REAL :: ptsflx(nx,ny)        ! surface flux of heat (K*kg/(m**2*s))
  REAL :: pbldpth(nx,ny)       ! Planetary boundary layer depth (m)

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
  REAL :: ptsfc  (nx,ny)       ! Ground surface potential temperature (K)
!
  REAL :: ptmix (nx,ny,nz)     ! Turbulent mixing on potential
                               ! temperature (K*kg/(m**3 *s))
!
  REAL :: h1    (nx,ny,nz)     ! Turbulent heat flux
  REAL :: h2    (nx,ny,nz)     ! Turbulent heat flux
  REAL :: h3    (nx,ny,nz)     ! Turbulent heat flux
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k,kt
  REAL :: mdpth                ! Match layer depth (m)
  REAL :: tem,temb,dtqflxdis1
  INTEGER :: cdiszero
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'phycst.inc'
  INCLUDE 'bndry.inc'
!
!-----------------------------------------------------------------------


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


  IF(tmixopt == 0) THEN

    DO k=1,nz
      DO j=1,ny
        DO i=1,nx
          h3(i,j,k)=0.0
        END DO
      END DO
    END DO

  ELSE

!-----------------------------------------------------------------------
!
!  Compute turbulent heat fluxes H1, H2 and H3.
!
!-----------------------------------------------------------------------

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tem1(i,j,k)=ptbar(i,j,k)+ptprt(i,j,k)
        END DO
      END DO
    END DO

    CALL trbflxs(nx,ny,nz,tem1,rhostr,kmh,kmv,rprntl,                   &
                 x,y,z,zp, j1,j2,j3,j3inv,mapfct,                       &
                 h1,h2,h3, tem2,tem3)

  END IF

!-----------------------------------------------------------------------
!
!  The surface heat flux depends on the option chosen:
!
!  When sfcphy = 0, the internally calculated (from SGS turbulence
!  parameterization) surface fluxes are used.
!  Otherwise, pre-calculated fluxes ptsflx is used.
!
!-----------------------------------------------------------------------
!
  IF( (landwtr == 0.AND.cdhlnd == 0.0).OR.                              &
        (landwtr == 1.AND.cdhlnd == 0.0.AND.cdhwtr == 0.0) ) THEN
    cdiszero = 1
  ELSE
    cdiszero = 0
  END IF

  IF( (sfcphy == 1.OR.sfcphy == 3) .AND. cdiszero == 1) GO TO 111

  IF( sfcphy /= 0 ) THEN
!
    IF ( (sflxdis == 0) .OR. (sflxdis == 1 .AND.                        &
           (sfcphy == 1.OR.sfcphy == 3).AND.cdiszero == 1) ) THEN
!
!-----------------------------------------------------------------------
!
!  Heat flux h3 at the surface = ptsflx.
!
!-----------------------------------------------------------------------
!
      DO j=2,ny-2
        DO i=2,nx-2
          h3(i,j,2) = ptsflx(i,j)
        END DO
      END DO

    ELSE IF (sflxdis == 1 .OR. sflxdis == 2)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          tem=0.833*pbldpth(i,j)
          temb = ptsflx(i,j)/tem
          h3(i,j,2) = ptsflx(i,j)
          IF(ptsfc(i,j) > ptprt(i,j,2)+ptbar(i,j,2))THEN
            DO k=3,nz-1
              IF ((zp(i,j,k)-zp(i,j,2)) <= tem)                         &
                  h3(i,j,k)=ptsflx(i,j)-(zp(i,j,k)-zp(i,j,2))*temb
            END DO
          END IF
        END DO
      END DO

    END IF

    IF (tqflxdis == 1)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          IF(pbldpth(i,j)+zp(i,j,2) > 0.51*(zp(i,j,3)+zp(i,j,2)))THEN
            dtqflxdis1 = MIN(dtqflxdis,pbldpth(i,j))
          ELSE
            dtqflxdis1 = dtqflxdis
          END IF
          tem = 1.0/dtqflxdis1

          temb = ptsflx(i,j)*tem
          h3(i,j,2) = ptsflx(i,j)
          DO k=3,nz-1
            IF ((zp(i,j,k)-zp(i,j,2)) <= dtqflxdis1)                    &
                h3(i,j,k)= h3(i,j,k) + ptsflx(i,j) *                    &
                       ( 1. - (zp(i,j,k)-zp(i,j,2)) *tem ) ** 2
          END DO
        END DO
      END DO

    ELSE IF (tqflxdis == 2)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          tem = usflx(i,j)*usflx(i,j)+vsflx(i,j)*vsflx(i,j)
          tem = (SQRT(tem))**3
          temb = ABS(ptsflx(i,j))
          mdpth = 0.254842*tem*(ptprt(i,j,2)                            &
                         +ptbar(i,j,2))/(temb+1.e-20)
          mdpth = mdpth*2.5
          tem = MAX (pbldpth(i,j), 100.)
          mdpth = MIN(mdpth,tem)
          mdpth = MAX(mdpth,(zp(i,j,3)-zp(i,j,2)))
          kt=1
          temb =1./(0.833*tem)
          IF(ptsfc(i,j) <= ptprt(i,j,2)+ptbar(i,j,2)) THEN
            kt = 2
            temb = 1./mdpth
          END IF
          h3(i,j,2) = ptsflx(i,j)
          DO k=3,nz-1
            IF ((zp(i,j,k)-zp(i,j,2)) <= mdpth)                         &
                h3(i,j,k)=ptsflx(i,j)*(1.-(zp(i,j,k)-zp(i,j,2))*temb)   &
                      **kt+h3(i,j,k)
          END DO
        END DO
      END DO

    END IF

  END IF

  111   CONTINUE
!
!-----------------------------------------------------------------------
!
!  Calculate the turbulent mixing term for the potential temperature
!
!  ptmix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2) + difz(h3 +
!          avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))
!
!-----------------------------------------------------------------------

  IF( tmixopt == 0 ) THEN

    DO k=2,nz-2
      DO j=2,ny-2
        DO i=2,nx-2
          ptmix(i,j,k)=(h3(i,j,k+1)-h3(i,j,k))*dzinv
        END DO
      END DO
    END DO

  ELSE

    CALL smixtrm(nx,ny,nz,h1,h2,h3,rhostr,x,y,z,zp,mapfct,              &
                 j1,j2,j3,aj3x,aj3y,                                    &
                 ptmix,                                                 &
                 tem1,tem2,tem3)

  END IF
!
!-----------------------------------------------------------------------
!
!  Set the boundary conditions for the mixing term
!
!-----------------------------------------------------------------------
!
  DO k=1,nz-1
    DO i=1,nx-1
      ptmix(i,   1,k)=ptmix(i,2,k)
      ptmix(i,ny-1,k)=ptmix(i,ny-2,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      ptmix(   1,j,k)=ptmix(2,j,k)
      ptmix(nx-1,j,k)=ptmix(nx-2,j,k)
    END DO
  END DO

  RETURN
END SUBROUTINE tmixpt

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


SUBROUTINE tmixqv(nx,ny,nz,qv,rhostr,kmh,kmv,rprntl,                    & 1,2
           qvsflx,pbldpth,                                              &
           x,y,z,zp,mapfct, j1,j2,j3,aj3x,aj3y,j3inv,                   &
           usflx,vsflx,ptsflx,ptsfc,qvsfc,ptbar,ptprt,                  &
           qvmix,                                                       &
           h1,h2,h3, tem1,tem2,tem3)

!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term for the water vapor specific
!  humidity equation. This term is expressed in the form of a turbulent
!  flux of the quantity in question.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/20/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  6/16/93 (MX)
!  Break down into subroutine calls.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  3/16/96 (Ming Xue)
!  The model can now include the surface fluxes with the turbulent
!  mxing option off (tmixopt=0).
!
!  3/27/1998 (M. Xue)
!  Added option tqflxdis for quadratic distribution of heat
!  and moisture fluxes in depth dtqflxdis, which is typically
!  set to 200 m.
!
!  9/18/1998 (D. Weber)
!  Added arrays aj3x,y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    qv       Water vapor specific humidity at a given time level (kg/kg)
!    pbldpth  Planetary boundary layer depth (m)
!    rhostr   Base state air density times j3 (kg/m**3)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    qvsflx  Surface flux of moisture (K*kg/(m**2*s))
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    qvmix    Total mixing in water vapor equation (kg/(m**3 * s))
!
!  WORK ARRAYS:
!
!    h1       Turbulent flux of moisture. A local array.
!    h2       Turbulent flux of moisture. A local array.
!    h3       Turbulent flux of moisture. A local array.
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes, and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: qv    (nx,ny,nz)     ! Water vapor specific humidity (kg/kg)
  REAL :: pbldpth(nx,ny)        ! Planetary boundary layer depth (m)
  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3 (kg/m**3)
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: qvsflx(nx,ny)        ! surface flux of moisture (kg/(m**2*s))

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: ptbar (nx,ny,nz)     ! Base state potential temperature (K)
  REAL :: ptprt (nx,ny,nz)     ! Perturbation potential temperature
  REAL :: ptsfc(nx,ny)         ! Temperature at ground (K) (in top 1 cm layer)
  REAL :: qvsfc(nx,ny)         ! Effective qv at the surface (kg/kg)

  REAL :: usflx(nx,ny)         ! Surface flux of u momentum
  REAL :: vsflx(nx,ny)         ! surface flux of v momentum
  REAL :: ptsflx(nx,ny)        ! Surface heat flux (K*kg/(m**2*s))

  REAL :: qvmix (nx,ny,nz)     ! Turbulent mixing on water substance
                               ! kg/(m**3 *s)
!
  REAL :: h1    (nx,ny,nz)     ! Turbulent moisture flux.
  REAL :: h2    (nx,ny,nz)     ! Turbulent moisture flux.
  REAL :: h3    (nx,ny,nz)     ! Turbulent moisture flux.
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array


!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k,kt
  REAL :: mdpth                ! Match layer depth (m)
  REAL :: tem,temb,dtqflxdis1
  INTEGER :: cdiszero
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!-----------------------------------------------------------------------
!
!  Compute turbulent moisture fluxes H1, H2 and H3.
!
!-----------------------------------------------------------------------

  IF(tmixopt == 0) THEN

    DO k=1,nz
      DO j=1,ny
        DO i=1,nx
          h3(i,j,k)=0.0
        END DO
      END DO
    END DO

  ELSE

    CALL trbflxs(nx,ny,nz,qv,rhostr,kmh,kmv,rprntl,                     &
                 x,y,z,zp, j1,j2,j3,j3inv,mapfct,                       &
                 h1,h2,h3, tem1,tem2)

  END IF

!-----------------------------------------------------------------------
!
!  Set the surface moisture fluxes:
!
!  When sfcphy = 0, the internally calculated (from SGS turbulence
!  parameterization) surface fluxes are used.
!  Otherwise, pre-calculated fluxes qvsflx is used.
!
!-----------------------------------------------------------------------
!
  IF( (landwtr == 0.AND.cdqlnd == 0.0).OR.                              &
        (landwtr == 1.AND.cdqlnd == 0.0.AND.cdqwtr == 0.0) ) THEN
    cdiszero = 1
  ELSE
    cdiszero = 0
  END IF

  IF( (sfcphy == 1.OR.sfcphy == 3) .AND. cdiszero == 1) GO TO 111

  IF( sfcphy /= 0 ) THEN
!
    IF ( (sflxdis == 0) .OR. (sflxdis == 1 .AND.                        &
           (sfcphy == 1.OR.sfcphy == 3).AND.cdiszero == 1) ) THEN
!
!-----------------------------------------------------------------------
!
!  Moisture flux h3 at the surface = qvsflx.
!
!-----------------------------------------------------------------------
!
      DO j=2,ny-2
        DO i=2,nx-2
          h3(i,j,2) = qvsflx(i,j)
        END DO
      END DO

    ELSE IF (sflxdis == 1 .OR. sflxdis == 2)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          tem=0.833*pbldpth(i,j)
          temb = qvsflx(i,j)/tem
          h3(i,j,2) = qvsflx(i,j)
          IF(ptsfc(i,j) > ptprt(i,j,2)+ptbar(i,j,2))THEN
            DO k=2,nz-1
              IF ((zp(i,j,k)-zp(i,j,2)) <= tem)                         &
                  h3(i,j,k)=qvsflx(i,j)-(zp(i,j,k)-zp(i,j,2))*temb
            END DO
          END IF
        END DO
      END DO

    END IF

    IF (tqflxdis == 1)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          IF(pbldpth(i,j)+zp(i,j,2) > 0.51*(zp(i,j,3)+zp(i,j,2)))THEN
            dtqflxdis1 = MIN(dtqflxdis,pbldpth(i,j))
          ELSE
            dtqflxdis1 = dtqflxdis
          END IF
          tem = 1.0/dtqflxdis1

          temb = qvsflx(i,j)*tem
          h3(i,j,2) = qvsflx(i,j)
          DO k=3,nz-1
            IF((zp(i,j,k)-zp(i,j,2)) <= dtqflxdis1)                     &
                h3(i,j,k)= h3(i,j,k) + qvsflx(i,j) *                    &
                       ( 1. - (zp(i,j,k)-zp(i,j,2)) * tem ) ** 2
          END DO
        END DO
      END DO

    ELSE IF (tqflxdis == 2)  THEN

      DO j=2,ny-2
        DO i=2,nx-2
          tem = usflx(i,j)*usflx(i,j)+vsflx(i,j)*vsflx(i,j)
          tem = (SQRT(tem))**3
          temb = ABS(ptsflx(i,j))
          mdpth = 0.254842*tem*(ptprt(i,j,2)                            &
                         +ptbar(i,j,2))/(temb+1.e-20)

          mdpth = mdpth*2.5
          tem = MAX (pbldpth(i,j), 100.)
          mdpth = MIN(mdpth,tem)

          mdpth = MAX(mdpth,(zp(i,j,3)-zp(i,j,2)))
          kt=1
          temb =1./tem
          IF(ptsfc(i,j) <= ptprt(i,j,2)+ptbar(i,j,2)) THEN
            kt = 2
            temb = 1./mdpth
          END IF
          h3(i,j,2) = qvsflx(i,j)
          DO k=3,nz-1
            IF ((zp(i,j,k)-zp(i,j,2)) <= mdpth)                         &
                h3(i,j,k)=qvsflx(i,j)*(1.-(zp(i,j,k)-zp(i,j,2))*temb)   &
                      **kt+h3(i,j,k)
          END DO
        END DO
      END DO

    END IF

  END IF

  111   CONTINUE
!
!-----------------------------------------------------------------------
!
!  Calculate the mixing term for the water vapor mixing ratio (qv)
!
!  qvmix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2) + difz(h3 +
!          avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))
!
!-----------------------------------------------------------------------

  IF( tmixopt == 0 ) THEN

    DO k=2,nz-2
      DO j=2,ny-2
        DO i=2,nx-2
          qvmix(i,j,k)=(h3(i,j,k+1)-h3(i,j,k))*dzinv
        END DO
      END DO
    END DO

  ELSE

    CALL smixtrm(nx,ny,nz,h1,h2,h3,rhostr,x,y,z,zp,mapfct,              &
                 j1,j2,j3,aj3x,aj3y,                                    &
                 qvmix,                                                 &
                 tem1,tem2,tem3)

  END IF
!
!-----------------------------------------------------------------------
!
!  Set the qvmix boundary values to the inside points.
!
!-----------------------------------------------------------------------
!

  DO k=1,nz-1
    DO i=1,nx-1
      qvmix(i,   1,k)=qvmix(i,2,k)
      qvmix(i,ny-1,k)=qvmix(i,ny-2,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      qvmix(   1,j,k)=qvmix(2,j,k)
      qvmix(nx-1,j,k)=qvmix(nx-2,j,k)
    END DO
  END DO

  RETURN
END SUBROUTINE tmixqv

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


SUBROUTINE tmixq(nx,ny,nz, q,rhostr,kmh,kmv,rprntl,                     & 2,2
           x,y,z,zp,mapfct, j1,j2,j3,aj3x,aj3y,j3inv,                   &
           qmix,                                                        &
           h1,h2,h3, tem1,tem2,tem3)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term for a water substance equation.
!  This term is expressed in the form of a turbulent flux of the water
!  quantity in question.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  10/10/91
!
!  MODIFICATION HISTORY:
!
!  5/05/92 (M. Xue)
!  Added full documentation.
!
!  6/1/92 (M. Xue and H. Jin)
!  Further facelift.
!
!  7/20/92 (M. Xue and D. Weber)
!  Terrain included.
!
!  6/16/93 (MX)
!  Break down into subroutine calls.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  11/06/97 (D. Weber)
!  Added three additional levels to the mapfct array.  The three
!  levels (4,5,6) represent the inverse of the first three in order.
!  The inverse map factors are computed to improve efficiency.
!
!  9/18/98 (D. Weber)
!  Added arrays aj3x,y.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    q        mixing ratio of one of the water/ice quantities at
!             a given time level (kg/kg)
!
!    rhostr   Base state air density times j3 (kg/m**3)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar, u, and v points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!  OUTPUT:
!
!    qmix     Total mixing in water/ice substance
!             equation (kg/(m**3 * s))
!
!  WORK ARRAYS:
!
!    h1       Turbulent flux a water quantity, a local array.
!    h2       Turbulent flux a water quantity, a local array.
!    h3       Turbulent flux a water quantity, a local array.
!    tem1     Temporary work array.
!    tem2     Temporary work array.
!    tem3     Temporary work array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes, and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: q     (nx,ny,nz)     ! Water/ice mixing ratio (kg/kg)
  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3 (kg/m**3)
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.
  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u, and v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3
!
  REAL :: qmix  (nx,ny,nz)     ! Turbulent mixing on water/ice
                               ! substance (kg/(m**2 *s))
!
  REAL :: h1    (nx,ny,nz)     ! Turbulent flux of a water quantity
  REAL :: h2    (nx,ny,nz)     ! Turbulent flux of a water quantity
  REAL :: h3    (nx,ny,nz)     ! Turbulent flux of a water quantity
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


!-----------------------------------------------------------------------
!
!  Compute turbulent water fluxes H1, H2 and H3.
!
!-----------------------------------------------------------------------

  CALL trbflxs(nx,ny,nz,q,rhostr,kmh,kmv,rprntl,                        &
               x,y,z,zp, j1,j2,j3,j3inv,mapfct,                         &
               h1,h2,h3, tem1,tem2)

!-----------------------------------------------------------------------
!
!  Calculate the mixing term for the water mixing ratio (q)
!
!  qmix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2) + difz(h3 +
!         avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))
!
!-----------------------------------------------------------------------


  CALL smixtrm(nx,ny,nz,h1,h2,h3,rhostr,x,y,z,zp,mapfct,                &
               j1,j2,j3,aj3x,aj3y,                                      &
               qmix,                                                    &
               tem1,tem2,tem3)

  DO k=1,nz-1
    DO i=1,nx-1
      qmix(i,   1,k)=qmix(i,2,k)
      qmix(i,ny-1,k)=qmix(i,ny-2,k)
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      qmix(   1,j,k)=qmix(2,j,k)
      qmix(nx-1,j,k)=qmix(nx-2,j,k)
    END DO
  END DO

  RETURN
END SUBROUTINE tmixq
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE TRBFLXS                    ######
!######                                                      ######
!######                     Developed by                     ######
!######  Center for the Analysis and Prediction of Storms    ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE trbflxs(nx,ny,nz,s,rhostr,kmh,kmv,rprntl,x,y,z,zp,           & 3,6
           j1,j2,j3,j3inv,mapfct,                                       &
           h1,h2,h3, tem1,tem2)
!
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent fluxes in x, y and z direction for a
!  scalar quantity 's'
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue
!  6/16/1993
!
!  MODIFICATION HISTORY:
!
!  4/1/96 (Donghai Wang, X. Song and M. Xue)
!  Added a time average weighting coefficient for implicit treatment
!  of vertical mixing.
!
!  8/27/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO-ENDDO structure for f90 conversion
!  -added mapfct to h1,h2 computation (previously performed in
!   smixtrm)
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    s        A scalar variable.
!    rhostr   Base state air density times j3 (kg/m**3)
!
!    kmh      Horizontal turb. mixing coef. for momentum ( m**2/s )
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    rprntl   Reciprocal of Prandtl number
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    j3inv    Inverse of j3
!
!    mapfct   Map factors at scalar, u, and v points
!
!  OUTPUT:
!
!    h1       Turbulent flux in x direction.
!    h2       Turbulent flux in y direction.
!    h3       Turbulent flux in z direction.
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array
!    tem2     Temporary work array
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    work arrays may be used for other purposes, and therefore their
!    contents may be overwritten. Please examine the usage of work
!    arrays before you alter the code.)
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: s     (nx,ny,nz)     ! A scalar variable.
  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3 (kg/m**3)
  REAL :: kmh   (nx,ny,nz)     ! Horizontal turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: rprntl(nx,ny,nz)     ! Reciprocal of Prandtl number

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: j3inv (nx,ny,nz)     ! Inverse of j3

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u, and v points

!
  REAL :: h1    (nx,ny,nz)     ! Turbulent flux in x direction
  REAL :: h2    (nx,ny,nz)     ! Turbulent flux in y direction
  REAL :: h3    (nx,ny,nz)     ! Turbulent flux in z direction

  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: del2inv
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'bndry.inc'
  INCLUDE 'mp.inc'            ! Message passing parameters.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  del2inv = 1./(dx*dy)

!-----------------------------------------------------------------------
!
!  Compute turbulent flux in x direction (H1)
!
!  H1 = avgx(rhobar * Km / j3) * (difx(j3 * s ) +
!       difz(j1 * avgsw(avgx( s ))))
!
!-----------------------------------------------------------------------


!-----------------------------------------------------------------------
!
!  Calculate the first term in the turbulent flux (H1)
!  difx(j3 * s)
!
!-----------------------------------------------------------------------

  IF( tmixvert == 0)THEN  ! compute the horizontal terms...

    DO k=1,nz-1    ! difx(j3 * s)
      DO j=2,ny-2
        DO i=2,nx-1
          h1(i,j,k) = dxinv*(j3(i,j,k)*s(i,j,k)                         &
                           - j3(i-1,j,k)*s(i-1,j,k))
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the second term in the turbulent flux (H1)
!  difz(j1 * avgsw(avgx(s))). When ternopt=0, this term is zero.
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0 ) THEN

      DO k=2,nz-1    ! avgsw(avgx(s))
        DO j=2,ny-2
          DO i=2,nx-1
            tem1(i,j,k) = 0.25*(s(i,j,k-1)+s(i-1,j,k-1)                 &
                               +s(i,j,k)  +s(i-1,j,k))
          END DO
        END DO
      END DO

      CALL acct_interrupt(bc_acct)
      CALL bcsw(nx,ny,nz,2,nx-1,2,ny-2,tbc,bbc,tem1)
      CALL acct_stop_inter
!call test_dump (tem1,"XXX8Atke_tem1",nx,ny,nz,0,0)

      DO k=1,nz-1
        DO j=2,ny-2
          DO i=2,nx-1
            h1(i,j,k) = h1(i,j,k) + dzinv*(j1(i,j,k+1)*tem1(i,j,k+1)    &
                                       -   j1(i,j,k)  *tem1(i,j,k))
          END DO
        END DO
      END DO

    END IF        ! end of terrain if block for H1....

!-----------------------------------------------------------------------
!
!  Calculate turbulent flux in Y direction (H2)
!
!  H2= avgy(rhobar*kh/j3)*(dify(j3 * s) + difz(j2 * avgsw(avgy(s))))
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Calculate the first term in the turbulent flux (H2)
!  dify(j3 * s)
!
!-----------------------------------------------------------------------

    DO k=1,nz-1    ! dify(j3 * s)
      DO j=2,ny-1
        DO i=1,nx-1
          h2(i,j,k) = dyinv*(j3(i,j,k)*s(i,j,k)                         &
                           - j3(i,j-1,k)*s(i,j-1,k))
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the second term in the turbulent flux (H2)
!  difz(j2 * avgsw(avgy(s))). When ternopt=0, this term is zero.
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0 ) THEN

      DO k=2,nz-1    ! avgsw(avgy(s))
        DO j=2,ny-1
          DO i=2,nx-2
            tem1(i,j,k) = 0.25*(s(i,j,k-1)+s(i,j-1,k-1)                 &
                               +s(i,j,k)  +s(i,j-1,k))
          END DO
        END DO
      END DO

      CALL acct_interrupt(bc_acct)
      CALL bcsw(nx,ny,nz,2,nx-2,2,ny-1,tbc,bbc,tem1)
      CALL acct_stop_inter
!call test_dump (tem1,"XXX9Atke_tem1",nx,ny,nz,3,0)

      DO k=1,nz-1
        DO j=2,ny-1
          DO i=2,nx-2
            h2(i,j,k) = h2(i,j,k) + dzinv*(j2(i,j,k+1)*tem1(i,j,k+1)    &
                                       -   j2(i,j,k)  *tem1(i,j,k))
          END DO
        END DO
      END DO

    END IF     ! end of terrain if block for H2....


!-----------------------------------------------------------------------
!
!  Calculate the coefficient for H1 and H2...
!  for H1  avgx(rhobar*kh/j3) = avgx(rhostr*kh/(j3*j3))
!  for H2  avgy(rhobar*kh/j3) = avgy(rhostr*kh/(j3*j3))
!
!-----------------------------------------------------------------------

    DO k=1,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          tem1(i,j,k) = rhostr(i,j,k)*kmh(i,j,k)*rprntl(i,j,k)          &
                      * (j3inv(i,j,k)*j3inv(i,j,k))
        END DO
      END DO
    END DO

    DO k=1,nz-1
      DO j=2,ny-2
        DO i=2,nx-1
          h1(i,j,k)  = 0.5*(tem1(i,j,k)+tem1(i-1,j,k))                  &
                             *h1(i,j,k)*mapfct(i,j,2)
        END DO
      END DO
    END DO     ! H1 is complete....

    DO k=1,nz-1
      DO j=2,ny-1
        DO i=2,nx-2
          h2(i,j,k) = 0.5*(tem1(i,j,k)+tem1(i,j-1,k))                   &
                          *h2(i,j,k)*mapfct(i,j,3)
        END DO
      END DO
    END DO     ! H2 is complete....

  END IF       !  end of tmixvert if block....

!-----------------------------------------------------------------------
!
!  Compute turbulent flux in z direction (H3).
!  H3= avgz (rhobar*kh/j3) * difz(s)
!
!  First calculate H3 = difz(s)
!
!-----------------------------------------------------------------------

  DO k=2,nz-1
    DO j=2,ny-2
      DO i=2,nx-2
        h3(i,j,k) = dzinv*(s(i,j,k)-s(i,j,k-1))
      END DO
    END DO
  END DO

!-----------------------------------------------------------------------
!
!  Calculate the coefficient for H3
!
!  avgz(rhobar*kh/j3)
!
!-----------------------------------------------------------------------

  DO k=1,nz-1
    DO j=2,ny-2
      DO i=2,nx-2
        tem1(i,j,k) = alfcoef * rhostr(i,j,k)*kmv(i,j,k)*rprntl(i,j,k)  &
                    * (j3inv(i,j,k)*j3inv(i,j,k))
      END DO
    END DO
  END DO

  DO k=2,nz-1
    DO j=2,ny-2
      DO i=2,nx-2
        h3(i,j,k) = 0.5*(tem1(i,j,k)+tem1(i,j,k-1))*h3(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE trbflxs
!
!##################################################################
!##################################################################
!######                                                      ######
!######                SUBROUTINE SMIXTRM                    ######
!######                                                      ######
!######                     Developed by                     ######
!######  Center for the Analysis and Prediction of Storms    ######
!######                University of Oklahoma                ######
!######                                                      ######
!##################################################################
!##################################################################
!


SUBROUTINE smixtrm(nx,ny,nz,h1,h2,h3,rhostr,                            & 3
           x,y,z,zp, mapfct, j1,j2,j3,aj3x,aj3y,                        &
           smix,                                                        &
           tem1,tem2,tem3)
!
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term for a scalar from the
!  turbulent fluxes h1, h2 and h3.
!
!  smix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2) +
!         difz(h3 + avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Ming Xue & Dan Weber
!  6/16/93
!
!  MODIFICATION HISTORY:
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  11/06/97 (D. Weber)
!  Added three additional levels to the mapfct array.  The three
!  levels (4,5,6) represent the inverse of the first three in order.
!  The inverse map factors are computed to improve efficiency.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tmixvert option for computing the vertical turbulent
!   mixing terms only.
!  -added arrays aj3x,y.
!
!  2/24/1999 (M.Xue)
!  Set contributions of H1 and H2 to fluxes through lower boundary
!  to zero. They are zero anyway in the absence of terrain.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    h1       Turbulent heat flux, a local array.
!    h2       Turbulent heat flux, a local array.
!    h3       Turbulent heat flux, a local array.
!
!    rhostr   Base state air density times j3 (kg/m**3)
!
!    x        x coordinate of grid points in physical/comp. space (m)
!    y        y coordinate of grid points in physical/comp. space (m)
!    z        z coordinate of grid points in computational space (m)
!    zp       Vertical coordinate of grid points in physical space (m)
!
!    mapfct   Map factors at scalar, u, and v points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!
!  OUTPUT:
!
!    smix     The mixing term for a scalar calc. from its turbulent fluxes
!
!  WORK ARRAYS:
!
!    tem1     Temporary work array
!    tem2     Temporary work array
!    tem3     Temporary work array
!
!-----------------------------------------------------------------------
!
!  Variable Declarations.
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions
!
  REAL :: h1    (nx,ny,nz)     ! Turbulent flux in x direction
  REAL :: h2    (nx,ny,nz)     ! Turbulent flux in y direction
  REAL :: h3    (nx,ny,nz)     ! Turbulent flux in z direction

  REAL :: rhostr(nx,ny,nz)     ! Base state air density times j3 (kg/m**3)
                               ! momentum. ( m**2/s )

  REAL :: x     (nx)           ! The x-coord. of the physical and
                               ! computational grid. Defined at u-point.
  REAL :: y     (ny)           ! The y-coord. of the physical and
                               ! computational grid. Defined at v-point.
  REAL :: z     (nz)           ! The z-coord. of the computational grid.
                               ! Defined at w-point on the staggered grid.
  REAL :: zp    (nx,ny,nz)     ! The physical height coordinate defined at
                               ! w-point of the staggered grid.

  REAL :: mapfct(nx,ny,8)      ! Map factors at scalar, u, and v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( x ).
  REAL :: j2    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! - d( zp )/d( y ).
  REAL :: j3    (nx,ny,nz)     ! Coordinate transform Jacobian defined as
                               ! d( zp )/d( z ).
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
!
  REAL :: smix  (nx,ny,nz)     ! Turbulent mixing for a scalar
!
  REAL :: tem1  (nx,ny,nz)     ! Temporary work array
  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
  REAL :: tem3  (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------

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


!-----------------------------------------------------------------------
!
!  Calculate the turbulent mixing term for a scalar as the divergence
!  of its turbluent fluxes:
!
!  smix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2) + difz(h3 +
!         avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Computing the vertical term first - difz(h3).
!
!-----------------------------------------------------------------------

  DO k=2,nz-2   ! add in the vertical h3 term.....
    DO j=2,ny-2
      DO i=2,nx-2
        smix(i,j,k) = dzinv*(h3(i,j,k+1)-h3(i,j,k))
      END DO
    END DO
  END DO

  IF( tmixvert == 0)THEN    ! compute the horizontal terms.

!-----------------------------------------------------------------------
!
!  Calculate term difx(avgx(j3) * h1) and dify(avgy(j3) * h2)
!  and difz(h3)  (non-terrain terms)
!
!-----------------------------------------------------------------------

    DO k=2,nz-2   ! add the two terms to smix...
      DO j=2,ny-2
        DO i=2,nx-2
          smix(i,j,k) =smix(i,j,k) + mapfct(i,j,1)*                     &
                        (dxinv*( h1(i+1,j,k)*aj3x(i+1,j,k)-             &
                                 h1(i,j,k)*aj3x(i,j,k))                 &
                        +dyinv*( h2(i,j+1,k)*aj3y(i,j+1,k)              &
                                -h2(i,j,k)*aj3y(i,j,k)))
        END DO
      END DO
    END DO     ! smix w/o terrain is complete.

!
!  At this point, smix = difx(avgx(j3) * h1) + dify(avgy(j3) * h2)
!

!-----------------------------------------------------------------------
!
!  Calculate the third term in the smix relation.
!  difz(h3 + avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2)) ! old
!  difz( avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2))   ! new
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0 ) THEN

!-----------------------------------------------------------------------
!
!  Calculate the second and third parts of the third term.
!  mapfct( avgx(avgz(h1) * j1) + avgy(avgz(h2) * j2)) )
!
!-----------------------------------------------------------------------

      DO k=3,nz-1   ! avgz(h1) * j1 and avgz(h2) * j2
        DO j=2,ny-1
          DO i=2,nx-1
            tem1(i,j,k) = 0.5*j1(i,j,k)*(h1(i,j,k)+h1(i,j,k-1))
            tem2(i,j,k) = 0.5*j2(i,j,k)*(h2(i,j,k)+h2(i,j,k-1))
          END DO
        END DO
      END DO

      DO k=3,nz-1
        DO j=2,ny-2
          DO i=2,nx-2
            tem3(i,j,k) =   mapfct(i,j,1)*0.5*                          &
                               ((tem1(i+1,j,k)+tem1(i,j,k))             &
                               +(tem2(i,j+1,k)+tem2(i,j,k)))
          END DO
        END DO
      END DO

      DO j=2,ny-2
        DO i=2,nx-2
          tem3(i,j,2) = 0.0  ! This term should not contribute more to the
                             ! flux through the lower boundary, which is
                             ! stored in H3.
        END DO
      END DO

      DO k=2,nz-2    ! add the terrain terms to smix...
        DO j=2,ny-2
          DO i=2,nx-2
            smix(i,j,k) =smix(i,j,k)+dzinv*(tem3(i,j,k+1)-tem3(i,j,k))
          END DO
        END DO
      END DO         ! smix is complete.....


    END IF        ! end of terrain if block....

  END IF      ! end of tmixvert if block....

  RETURN
END SUBROUTINE smixtrm

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


SUBROUTINE umixtrm(nx,ny,nz,mapfct,j1,j2,j3,aj3y,                       & 1
           tau11,tau12,tau13,                                           &
           umix,tem1,tem2)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term in u equation as the divergence
!  of the turbulent momentum fluxes.
!
!  j3 * DIV U = difx (j3 * tau11) + dify (avgx (avgsv(j3)) * tau12)
!               + difz (tau13 + (j1 * avgz (avgx (tau11))) + (avgy
!               ((avgx (j2)) * (avgz (tau12))))
!
!-----------------------------------------------------------------------
!
!  AUTHOR: D. Weber & M. Xue
!  6/29/92.
!
!  MODIFICATION HISTORY:
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  8/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tmixvert option to compute only vertical t-mixing terms.
!  -added array aj3y.
!
!  2/24/1999 (M.Xue)
!  Set contributions of tau11 and tau12 to momentum flux through
!  lower boundary to zero. They are zero anyway in the absence of terrain.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    mapfct   Map factors at u points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!
!    tau11    Deformation tensor component (1/s)
!    tau12    Deformation tensor component (1/s)
!    tau13    Deformation tensor component (1/s)
!
!
!  OUTPUT:
!
!    umix     The divergence of u mixing term
!
!  WORKING ARRAYS:
!
!    tem1     Temporary working array.
!    tem2     Temporary working array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    working arrays may be used for other purposes therefore their
!    contents overwritten. Please examine the usage of working arrays
!    before you alter the code.)
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
!  Variable Declarations
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  REAL :: mapfct(nx,ny)        ! Map factors at u points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dx
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dy
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               !   d(zp)/dz
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
!
  REAL :: tau11 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau12 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau13 (nx,ny,nz)     ! Deformation stress component.
!
  REAL :: umix  (nx,ny,nz)     ! Divergence of u mixing term
!
  REAL :: tem1  (nx,ny,nz)     ! Temporary working array.
  REAL :: tem2  (nx,ny,nz)     ! Temporary working array.

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'     ! Global constants that control model
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'bndry.inc'
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!-----------------------------------------------------------------------
!
!  NOTE: In order to reduce memory usage, order dependance has been
!        introduced in the calculation of the third term in the
!        U mixing divergence term, which reduces the possible term-
!        wise parallelism.  This is due to the constraint that only two
!        temporary arrays being avaliable for passage into this subroutine.
!
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Calculate the vertical term first of the u mixing divergence term.
!  difz(Tau13)
!  Note:  tau13 will be used as a temporary array later...
!
!-----------------------------------------------------------------------

  DO k=2,nz-2
    DO j=2,ny-2
      DO i=2,nx-1
        umix(i,j,k) = dzinv*(tau13(i,j,k+1)-tau13(i,j,k))
      END DO
    END DO
  END DO   ! note tau13 is available for use as a temporary array..
!call test_dump (umix,"XXXumixtrm_umix",nx,ny,nz,1,0)
!call test_dump (tau13,"XXXumixtrm_tau13",nx,ny,nz,1,0)

!-----------------------------------------------------------------------
!
!  Calculate the first term of the u mixing divergence term.
!  difx(j3 * Tau11)
!
!-----------------------------------------------------------------------

  IF( tmixvert == 0)THEN   ! compute the horizontal terms.....

    DO k=2,nz-2    !  difx(j3 * Tau11)
      DO j=2,ny-2
        DO i=2,nx-1
          tau13(i,j,k) = dxinv*(j3(i,j,k)*tau11(i,j,k)-                 &
                                j3(i-1,j,k)*tau11(i-1,j,k))
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the second term of the u mixing divergence term.
!  dify(avgx(avgsv(j3)) * Tau12)
!
!-----------------------------------------------------------------------

    DO k=2,nz-2    !  avgx(aj3y) * Tau12
      DO j=2,ny-1
        DO i=2,nx-1
          tem2(i,j,k) = 0.5*(aj3y(i,j,k)+aj3y(i-1,j,k))*tau12(i,j,k)
        END DO
      END DO
    END DO

    DO k=2,nz-2    !  mapfct*(dify(tem2) + umix)
      DO j=2,ny-2    !  tau13 is the difx term...
        DO i=2,nx-1
          umix(i,j,k) = umix(i,j,k) + mapfct(i,j) *                     &
                   (tau13(i,j,k) + dyinv*(tem2(i,j+1,k)-tem2(i,j,k)))
        END DO
      END DO
    END DO
!call test_dump (umix,"XXX1umixtrm_umix",nx,ny,nz,1,0)
!call test_dump (mapfct,"XXX1umixtrm_mapfct",nx,ny,1,1,0)
!call test_dump (tem2,"XXXumixtrm_tem2",nx,ny,nz,1,0)
!call test_dump (tau12,"XXXumixtrm_tau12",nx,ny,nz,1,0)

!-----------------------------------------------------------------------
!
!  Calculate the third part of the third term first.
!  avgy (avgx (j2) * avgz (tau12)). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0) THEN

      DO k=3,nz-1    !  avgx (j2) * avgz (tau12)....
        DO j=2,ny-1
          DO i=2,nx-1
            tem1(i,j,k) = 0.25*(j2(i,j,k)+j2(i-1,j,k))*                 &
                          (tau12(i,j,k)+tau12(i,j,k-1))
          END DO
        END DO
      END DO

!
!  At this point, tem1 =  avgx (j2) * avgz (tau12).
!

!-----------------------------------------------------------------------
!
!  Calculate the second part of the third term.
!  j1 * (avgz (avgx (tau11))). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

      DO k=3,nz-1    !  j1 * (avgz (avgx (tau11)))....
        DO j=2,ny-2
          DO i=2,nx-1
            tem2(i,j,k)=j1(i,j,k)*0.25*((tau11(i-1,j,k)+tau11(i,j,k))   &
                                     +(tau11(i-1,j,k-1)+tau11(i,j,k-1)))
          END DO
        END DO
      END DO

      DO k=3,nz-1    !  mapfct*(avgy(tem1)+tem2)....
        DO j=2,ny-2
          DO i=2,nx-1
            tem2(i,j,k)=mapfct(i,j)*(tem2(i,j,k)+                       &
                                0.5*(tem1(i,j+1,k)+tem1(i,j,k)))
          END DO
        END DO
      END DO

      DO j=2,ny-2
        DO i=2,nx-1
          tem2(i,j,2)=0.0
        END DO
      END DO

      DO k=2,nz-2    !  add in terrain term.
        DO j=2,ny-2
          DO i=2,nx-1
            umix(i,j,k)=umix(i,j,k)+dzinv*(tem2(i,j,k+1)-tem2(i,j,k))
          END DO
        END DO
      END DO         ! umix is complete.......
!call test_dump (umix,"XXX2umixtrm_umix",nx,ny,nz,1,0)

    END IF       ! end of terrain if block.........

  END IF  !  end of tmixvert if block....

  RETURN
END SUBROUTINE umixtrm


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


SUBROUTINE vmixtrm(nx,ny,nz,mapfct,j1,j2,j3,aj3x,                       & 1
           tau12,tau22,tau23,                                           &
           vmix,tem1,tem2)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term in v equation as the
!  divergence of the turbulent momentum fluxes.
!
!  j3 * DIV V = difx (avgy(avgsu(j3)) * tau12) + dify (j3 * tau22)
!               + difz (tau23 + avgx(avgy(j1) * avgz (tau12)) +
!               (j2 * (avgz (avgy(tau22)))))
!
!-----------------------------------------------------------------------
!
!  AUTHOR: D. Weber & M. Xue
!  6/29/92.
!
!  MODIFICATION HISTORY:
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  9/18/98 (D. Weber)
!  Modified do loop structure to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tmixvert option for computing only the vertical
!   turbulent mixing terms.
!  -added array aj3x.
!
!  2/24/1999 (M.Xue)
!  Set contributions of tau21 and tau22 to momentum flux through
!  lower boundary to zero. They are zero anyway in absence of terrain.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    mapfct   Map factors at v points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!
!    tau12    Deformation tensor component (1/s)
!    tau22    Deformation tensor component (1/s)
!    tau23    Deformation tensor component (1/s)
!
!
!  OUTPUT:
!
!    vmix     The divergence of v mixing term
!
!  WORKING ARRAYS:
!
!    tem1     Temporary working array.
!    tem2     Temporary working array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    working arrays may be used for other purposes therefore their
!    contents overwritten. Please examine the usage of working arrays
!    before you alter the code.)
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  REAL :: mapfct(nx,ny)        ! Map factors at v points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dx
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dy
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               !   d(zp)/dz
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
!
  REAL :: tau12 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau22 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau23 (nx,ny,nz)     ! Deformation stress component.
!
  REAL :: vmix  (nx,ny,nz)     ! Divergence of v mixing term
!
  REAL :: tem1  (nx,ny,nz)     ! Temporary working array.
  REAL :: tem2  (nx,ny,nz)     ! Temporary working array.

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'     ! Global constants that control model
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'bndry.inc'
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!

!-----------------------------------------------------------------------
!
!  Calculate the third term of the V mixing divergence term first.
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  NOTE: In order to reduce memory usage, order dependance has been
!        introduced in the calculation of the third term in the
!        v mixing divergence term, which reduces the possible term-
!        wise parallelism.  This is due to the constraint that only two
!        temporary arrays being avaliable for passage into this subroutine.
!
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Calculate the vetical mixing term of the V mixing divergence term.
!  difz(Tau23)
!
!-----------------------------------------------------------------------

  DO k=2,nz-2    !  difz(Tau23)
    DO j=2,ny-1
      DO i=2,nx-2
        vmix(i,j,k) = dzinv*(tau23(i,j,k+1)-tau23(i,j,k))
      END DO
    END DO         ! if needed tau23 can be used as a temp array.
  END DO         ! vmix for tmixvert=1 is complete.


  IF( tmixvert == 0)THEN   ! compute the horizontal mixing terms.

!-----------------------------------------------------------------------
!
!  Calculate the second term of the V mixing divergence term.
!  dify(j3 * Tau22)
!
!-----------------------------------------------------------------------

    DO k=2,nz-2    !  dify(j3 * Tau22)
      DO j=2,ny-1
        DO i=2,nx-2
          tau23(i,j,k) = dyinv*(j3(i,j,k)*tau22(i,j,k)-                 &
                                j3(i,j-1,k)*tau22(i,j-1,k))
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the first term of the V mixing divergence term.
!  difx (avgy(avgsu(j3)) * Tau12)
!
!-----------------------------------------------------------------------

    DO k=2,nz-2    !  avgy(aj3x) * Tau12
      DO j=2,ny-1
        DO i=2,nx-1
          tem2(i,j,k) = 0.5*(aj3x(i,j,k)+aj3x(i,j-1,k))*tau12(i,j,k)
        END DO
      END DO
    END DO

    DO k=2,nz-2    !  vmix+ mapfct*(difx(tem2) + tau23)
      DO j=2,ny-1    !                             temp. array
        DO i=2,nx-2
          vmix(i,j,k) = vmix(i,j,k)+mapfct(i,j)*                        &
                      (tau23(i,j,k)+dxinv*(tem2(i+1,j,k)-tem2(i,j,k)))
        END DO
      END DO
    END DO         ! non-terrain portion of vmix is complete.

!-----------------------------------------------------------------------
!
!  Now add in the terrain term......
!  Calculate the second part of the third term (the x-terrain term).
!  avgx(avgy(j1) * avgz(Tau12)). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

    IF( ternopt /= 0) THEN

      DO k=3,nz-1    !  avgy (j1) * avgz (tau12)....
        DO j=2,ny-1
          DO i=2,nx-1
            tem1(i,j,k) = 0.25*(j1(i,j,k)+j1(i,j-1,k))*                 &
                            (tau12(i,j,k)+tau12(i,j,k-1))
          END DO
        END DO
      END DO

!-----------------------------------------------------------------------
!
!  Calculate the third part of the third term (the y-terrain term).
!  j2 * avgz(avgy(tau22)). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

      DO k=3,nz-1    !  j2 * (avgz (avgy (tau22)))....
        DO j=2,ny-1
          DO i=2,nx-2
            tem2(i,j,k)=j2(i,j,k)*0.25*((tau22(i,j-1,k)+tau22(i,j,k))+  &
                                      (tau22(i,j-1,k-1)+tau22(i,j,k-1)))
          END DO
        END DO
      END DO

      DO k=3,nz-1    !  mapfct*(avgx(tem1)+tem2)....
        DO j=2,ny-1
          DO i=2,nx-2
            tem2(i,j,k)=mapfct(i,j)*(tem2(i,j,k)+                       &
                                0.5*(tem1(i+1,j,k)+tem1(i,j,k)))
          END DO
        END DO
      END DO

      DO j=2,ny-1
        DO i=2,nx-2
          tem2(i,j,2)= 0.0
        END DO
      END DO

      DO k=2,nz-2    !  add in terrain term.
        DO j=2,ny-1
          DO i=2,nx-2
            vmix(i,j,k)=vmix(i,j,k)+dzinv*(tem2(i,j,k+1)-tem2(i,j,k))
          END DO
        END DO
      END DO         ! vmix is complete.......

    END IF           ! end of terrain if block.....

  END IF             ! end of tmixvert if block....

  RETURN
END SUBROUTINE vmixtrm


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


SUBROUTINE wmixtrm(nx,ny,nz,mapfct,j1,j2,j3,aj3x,aj3y,                  & 1
           tau13,tau23,tau33,                                           &
           wmix,tem1,tem2)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the turbulent mixing term in w equation as the
!  divergence of the turbulent momentum fluxes.
!
!  j3 * DIV W = difx (avgz(avgsu(j3)) * tau13) + dify(avgz(avgsv(j3))
!               * tau23) + difz (tau33 + avgx(avgz(j1) * avgz(tau13))
!               + (avgy(avgz(j2) * avgz(tau23))))
!
!-----------------------------------------------------------------------
!
!  AUTHOR: D. Weber & M. Xue
!  6/29/92.
!
!  10/17/93  (D. Weber)
!  Vertical loop bounds in loop 300 and 305 corrected.
!
!  1/23/96 (Donghai Wang & Yuhe Liu)
!  Added the map projection factor.
!
!  8/27/98 (D. Weber)
!  Modified code to improve code efficiency via:
!  -merging existing loops together
!  -removing and merging operators
!  -switched to DO  ENDDO structure for f90 conversion
!  -added tmixvert option for computing only the horizontal
!   turbulent mixing terms.
!  -added aj3x,y arrays.
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    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
!
!    mapfct   Map factors at scalar points
!
!    j1       Coordinate transform Jacobian -d(zp)/dx
!    j2       Coordinate transform Jacobian -d(zp)/dy
!    j3       Coordinate transform Jacobian  d(zp)/dz
!    aj3x     Avgx of the coordinate transformation Jacobian  d(zp)/dz
!    aj3y     Avgy of the coordinate transformation Jacobian  d(zp)/dz
!
!    tau13    Deformation tensor component (1/s)
!    tau23    Deformation tensor component (1/s)
!    tau33    Deformation tensor component (1/s)
!
!
!  OUTPUT:
!
!    wmix     The divergence of w mixing term
!
!  WORKING ARRAYS:
!
!    tem1     Temporary working array.
!    tem2     Temporary working array.
!
!   (These arrays are defined and used locally (i.e. inside this
!    subroutine), they may also be passed into routines called by
!    this one. Exiting the call to this subroutine, these temporary
!    working arrays may be used for other purposes therefore their
!    contents overwritten. Please examine the usage of working arrays
!    before you alter the code.)
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE
!
  INTEGER :: nx,ny,nz          ! Number of grid points in 3 directions

  REAL :: mapfct(nx,ny)        ! Map factors at scalar points

  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dx
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               ! - d(zp)/dy
  REAL :: j3    (nx,ny,nz)     ! Coordinate transformation Jacobian
                               !   d(zp)/dz
  REAL :: aj3x  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE X-DIR.
  REAL :: aj3y  (nx,ny,nz)     ! Coordinate transformation Jacobian defined
                               ! as d( zp )/d( z ) AVERAGED IN THE Y-DIR.
!
  REAL :: tau13 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau23 (nx,ny,nz)     ! Deformation stress component.
  REAL :: tau33 (nx,ny,nz)     ! Deformation stress component.
!
  REAL :: wmix  (nx,ny,nz)     ! Divergence of w mixing term
!
  REAL :: tem1  (nx,ny,nz)     ! Temporary working array.
  REAL :: tem2  (nx,ny,nz)     ! Temporary working array.

!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'globcst.inc'     ! Global constants that control model
  INCLUDE 'grid.inc'          ! Grid & map parameters.
  INCLUDE 'bndry.inc'       ! Boundry constants
!
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

!-----------------------------------------------------------------------
!
!  NOTE: In order to reduce memory usage, order dependance has been
!        introduced in the calculation of the third term in the
!        w mixing divergence term, which reduces the possible term-
!        wise parallelism.  This is due to the constraint that only
!        two temporary arrays being avaliable for passage into this
!        subroutine.
!
!
!-----------------------------------------------------------------------

!-----------------------------------------------------------------------
!
!  Calculate the first term of the third W mixing divergence term.
!  difz(Tau33).
!
!-----------------------------------------------------------------------

  DO k=2,nz-1    ! difz(tau33)
    DO j=2,ny-2    ! note tau33 is used as a tem array after this
      DO i=2,nx-2    ! loop.........
        wmix(i,j,k) = dzinv*(tau33(i,j,k)-tau33(i,j,k-1))
      END DO
    END DO
  END DO         ! vertical mixing for wmix is complete.

!-----------------------------------------------------------------------
!
!  NOTE: tau33 is no longer needed and will be used as a temporary
!        array...
!
!-----------------------------------------------------------------------

  IF( tmixvert == 0)THEN   ! compute the horizontal terms.

!-----------------------------------------------------------------------
!
!  Calculate the first term of the W mixing divergence term.
!  difx (avgz(avgsu(j3)) * Tau13)
!
!-----------------------------------------------------------------------

    DO k=2,nz-1    !  avgz(avgsu(j3)) * Tau13
      DO j=2,ny-2
        DO i=2,nx-1
          tem1(i,j,k) = 0.5*(aj3x(i,j,k)+aj3x(i,j,k-1))*tau13(i,j,k)
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Calculate the second term of the W mixing divergence term.
!  dify(avgz(avgsv(j3)) * Tau23)
!
!-----------------------------------------------------------------------

    DO k=2,nz-1    !  avgz(aj3y) * Tau23
      DO j=2,ny-1
        DO i=2,nx-2
          tem2(i,j,k) = 0.5*(aj3y(i,j,k)+aj3y(i,j,k-1))*tau23(i,j,k)
        END DO
      END DO
    END DO

!-----------------------------------------------------------------------
!
!  Combine the non terrain terms with the vertical term...
!
!-----------------------------------------------------------------------

    DO k=2,nz-1    !  wmix + mapfct*(difx(tem1)+dify(tem2))
      DO j=2,ny-2
        DO i=2,nx-2
          wmix(i,j,k) = wmix(i,j,k)+                                    &
                        mapfct(i,j)*(dxinv*(tem1(i+1,j,k)-tem1(i,j,k))+ &
                                     dyinv*(tem2(i,j+1,k)-tem2(i,j,k)))
        END DO
      END DO
    END DO         ! wmix without terrain is complete.


    IF( ternopt /= 0 ) THEN

!-----------------------------------------------------------------------
!
!  Calculate the second part of the third term.
!  avgx(avgz(j1) * avgz(tau13)). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

      DO k=1,nz-1    !  avgz(j1) * avgz(tau13)....
        DO j=2,ny-2
          DO i=2,nx-1
            tem1(i,j,k)=0.25*(j1(i,j,k+1)+   j1(i,j,k))*                &
                          (tau13(i,j,k+1)+tau13(i,j,k))
          END DO
        END DO
      END DO

!-----------------------------------------------------------------------
!
!  Calculate the third part of the third term.
!  avgy(avgz(j2) * avgz(tau23)). This term is zero when ternopt=0.
!
!-----------------------------------------------------------------------

      DO k=1,nz-1    !  avgz(j2) * avgz(tau23)....
        DO j=2,ny-1
          DO i=2,nx-2
            tem2(i,j,k)=0.25*(j2(i,j,k+1)+   j2(i,j,k))*                &
                          (tau23(i,j,k+1)+tau23(i,j,k))
          END DO
        END DO
      END DO


      DO k=1,nz-1    !  mapfct*(avgx(tem1)+avgy(tem2))....
        DO j=2,ny-2
          DO i=2,nx-2
            tau33(i,j,k)=mapfct(i,j)*0.5*((tem1(i+1,j,k)+tem1(i,j,k))+  &
                                          (tem2(i,j+1,k)+tem2(i,j,k)))
          END DO
        END DO
      END DO

      DO k=2,nz-1    !  wmix+difz(tau33)...
        DO j=2,ny-2
          DO i=2,nx-2
            wmix(i,j,k)=wmix(i,j,k)+dzinv*(tau33(i,j,k)-tau33(i,j,k-1))
          END DO
        END DO
      END DO         !  wmix is complete with terrain terms...

    END IF           !  end of terrain if block...

  END IF             !  end of tmixvert if block...

  RETURN
END SUBROUTINE wmixtrm

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


SUBROUTINE vmiximpuvw(nx,ny,nz,dtbig1,u,v,w,                            & 1,4
           rhostr,kmv,j1,j2,j3inv,                                      &
           uforce,vforce,wforce,                                        &
           rkj3inv2,u_temp,v_temp,w_temp,                               &
           rhostru,rhostrv,rhostrw,a,b,c,d)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Coordinate the vertical mixing terms by using implicit scheme
!  in the u,v,and w momentum equations.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Donghai Wang, M. Xue and X. Song
!  4/19/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx       Number of grid points in the x-direction
!    ny       Number of grid points in the y-direction
!    nz       Number of grid points in the vertical
!
!    dtbig1   The big time step size
!    u        x component of velocity at a given time level (m/s)
!    v        y component of velocity at a given time level (m/s)
!    w        Vertical component of velocity in Cartesian
!             coordinates at a given time level (m/s)
!    rhostr    Base state density rhobar times j3 (kg/m**3)
!    kmv      Vertical turb. mixing coef. for momentum ( m**2/s )
!    j1       Coordinate transformation Jacobian -d(zp)/dx
!    j2       Coordinate transformation Jacobian -d(zp)/dy
!    j3inv    Inverse of J3
!    uforce   Acoustically inactive forcing terms in u-momentum
!             equation (kg/(m*s)**2). uforce= -uadv + umix + ucorio
!    vforce   Acoustically inactive forcing terms in v-momentum
!             equation (kg/(m*s)**2). vforce= -vadv + vmix + vcorio
!    wforce   Acoustically inactive forcing terms in w-momentum
!             equation (kg/(m*s)**2).
!
!  OUTPUT:
!
!    uforce    Updated uforce.
!    vforce    Updated vforce.
!    wforce    Updated wforce.
!
!  WORK ARRAYS:
!
!    rkj3inv2  Array for calculating a, b, c
!              defined as rhostr*kmv*j3inv*j3inv
!    u_temp    Updated total u-velocity (m/s)
!    v_temp    Updated total v-velocity (m/s)
!    w_temp    Intermediate value of w (m/s)
!    rhostru  Average rhostr at u points (kg/m**3).
!    rhostrv  Average rhostr at v points (kg/m**3).
!    rhostrw  Average rhostr at w points (kg/m**3).
!    a         lhs coefficient of tridigonal eqations
!    b         lhs coefficient of tridigonal eqations
!    c         lhs coefficient of tridigonal eqations
!    d         rhs coefficient of tridigonal eqations
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions
  REAL :: dtbig1            ! the big time step size
  REAL :: u     (nx,ny,nz)     ! Total u-velocity (m/s)
  REAL :: v     (nx,ny,nz)     ! Total v-velocity (m/s)
  REAL :: w     (nx,ny,nz)     ! Total w-velocity (m/s)
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.
  REAL :: kmv   (nx,ny,nz)     ! Vertical turb. mixing coef. for
                               ! momentum. ( m**2/s )
  REAL :: j1    (nx,ny,nz)     ! Coordinate transformation Jacobian
  REAL :: j2    (nx,ny,nz)     ! Coordinate transformation Jacobian
  REAL :: j3inv (nx,ny,nz)     ! Inverse of J3

  REAL :: uforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in u-momentum equation (kg/(m*s)**2)
  REAL :: vforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in v-momentum equation (kg/(m*s)**2)
  REAL :: wforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in w-momentum equation (kg/(m*s)**2)

  REAL :: rkj3inv2(nx,ny,nz)   ! Array for calculating a, b, c
                               ! defined as rhostr*kmv*j3inv*j3inv
  REAL :: u_temp(nx,ny,nz)     ! Updated total u-velocity (m/s)
  REAL :: v_temp(nx,ny,nz)     ! Updated total v-velocity (m/s)
  REAL :: w_temp(nx,ny,nz)     ! Intermediate value of w
  REAL :: rhostru(nx,ny,nz)    ! Average rhostr at u points (kg/m**3)
  REAL :: rhostrv(nx,ny,nz)    ! Average rhostr at v points (kg/m**3)
  REAL :: rhostrw(nx,ny,nz)    ! Average rhostr at w points (kg/m**3)
  REAL :: a     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: b     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: c     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: d     (nx,ny,nz)     ! rhs coefficient of tridigonal eqations
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'phycst.inc'      ! Physical constants
  INCLUDE 'globcst.inc'     ! Global constants that control model
                            ! execution
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        rkj3inv2(i,j,k)=rhostr(i,j,k)*kmv(i,j,k)                        &
                        *j3inv(i,j,k)*j3inv(i,j,k)
      END DO
    END DO
  END DO
!call test_dump (kmv,"XXXvmiximpuvw_kmv",nx,ny,nz,0,1)
!call test_dump (rhostr,"XXXvmiximpuvw_rhostr",nx,ny,nz,0,1)
!call test_dump (j3inv,"XXXvmiximpuvw_j3inv",nx,ny,nz,0,1)

  CALL rhouvw(nx,ny,nz,rhostr,rhostru,rhostrv,rhostrw)

  CALL vmiximpu(nx,ny,nz,dtbig1,u,rhostru,rkj3inv2,                     &
                uforce,u_temp,                                          &
                a,b,c,d,w_temp)
!call test_dump (uforce,"XXXAvmiximpu_uforce",nx,ny,nz,1,0)

  CALL vmiximpv(nx,ny,nz,dtbig1,v,rhostrv,rkj3inv2,                     &
                vforce,v_temp,                                          &
                a,b,c,d,w_temp)

  IF( ternopt == 0 ) THEN

    DO k=2,nz-1
      DO j=1,ny-1
        DO i=1,nx-1
          w_temp(i,j,k)=0.0
        END DO
      END DO
    END DO

  ELSE


    DO j=1,ny-1
      DO i=1,nx-1
        w_temp(i,j,nz-1)=0.0
        w_temp(i,j,2) =-((u_temp(i  ,j,2)+u_temp(i  ,j,1))*j1(i,j,2)    &
                        +(u_temp(i+1,j,2)+u_temp(i+1,j,1))*j1(i+1,j,2)  &
                        +(v_temp(i,j  ,2)+v_temp(i,j  ,1))*j2(i,j,2)    &
                        +(v_temp(i,j+1,2)+v_temp(i,j+1,1))*j2(i,j+1,2)  &
                         )*0.25
      END DO
    END DO

  END IF

  CALL vmiximpw(nx,ny,nz,dtbig1,w,rhostrw,w_temp,rkj3inv2,              &
                wforce,                                                 &
                a,b,c,d)


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


SUBROUTINE vmiximpu(nx,ny,nz,dtbig1,u,rhostru,rkj3inv2,                 & 1,2
           uforce,u_temp,                                               &
           a,b,c,d,tem2)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the vertical mixing term using implicit scheme in the u
!  momentum equation.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Donghai Wang, X. Song and M. Xue
!  4/2/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx        Number of grid points in the x-direction
!    ny        Number of grid points in the y-direction
!    nz        Number of grid points in the vertical
!
!    dtbig1    The big time step size
!    u         Total u-velocity (m/s)
!    rhostru  Average rhostr at u points (kg/m**3).
!    rkj3inv2  Array for calculating a, b, c
!              defined as rhostr*kmv*j3inv*j3inv
!    uforce    Acoustically inactive forcing terms in u-eq.
!              (kg/(m*s)**2)
!
!  OUTPUT:
!
!    uforce    Updated uforce.
!    u_temp    Updated total u-velocity (m/s)
!
!  WORK ARRAYS:
!
!    a         lhs coefficient of tridigonal eqations
!    b         lhs coefficient of tridigonal eqations
!    c         lhs coefficient of tridigonal eqations
!    d         rhs coefficient of tridigonal eqations
!    tem2      Work array
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions
  REAL :: dtbig1            !the big time step size
  REAL :: u     (nx,ny,nz)     ! Total u-velocity (m/s)
  REAL :: rhostru(nx,ny,nz)    ! Average rhostr at u points (kg/m**3)
  REAL :: rkj3inv2(nx,ny,nz)   ! Array for calculating a, b, c
                               ! defined as rhostr*kmv*j3inv*j3inv
  REAL :: uforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in u-eq.(kg/(m*s)**2)
  REAL :: u_temp(nx,ny,nz)     ! Updated total u-velocity (m/s)
  REAL :: dt2inv         !Defined as 1/(2*dtbig1),
  REAL :: a     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: b     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: c     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: d     (nx,ny,nz)     ! rhs coefficient of tridigonal eqations
                               ! The contains solution u_temp on exit.

  REAL :: tem2  (nx,ny,nz)     ! Temporary work array

!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'phycst.inc'      ! Physical constants
  INCLUDE 'globcst.inc'     ! Global constants that control model
                            ! execution
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: tema,accoef
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  CALL avgsu(rkj3inv2, nx,ny,nz, 1,ny-1, 1,nz,  tem2, a) ! a used as temp
!
!-----------------------------------------------------------------------
!
!  Calculate coefficients of the tridigonal eqation.
!
!-----------------------------------------------------------------------
!

  accoef=0.5*(1.-alfcoef)*dzinv*dzinv
  dt2inv = 0.5/dtbig1

  DO k=2,nz-2
    DO j=1,ny-1
      DO i=1,nx-1
        a(i,j,k)=-accoef*(tem2(i,j,k-1)+tem2(i,j,k  ))
        c(i,j,k)=-accoef*(tem2(i,j,k  )+tem2(i,j,k+1))
        tema    =rhostru(i,j,k)*dt2inv
        b(i,j,k)=-(a(i,j,k)+c(i,j,k))+tema
        d(i,j,k)=uforce(i,j,k)+tema*u(i,j,k)
      END DO
    END DO
  END DO

  DO j=1,ny-1
    DO i=1,nx-1
      b(i,j,2)   =b(i,j,2)   +a(i,j,2)
      b(i,j,nz-2)=b(i,j,nz-2)+c(i,j,nz-2)
    END DO
  END DO
!
!-----------------------------------------------------------------------
!
!  Call the tridiagonal solver.
!
!-----------------------------------------------------------------------
!

  CALL tridiag2(nx,ny,nz,2,nx-1,1,ny-1,2,nz-2,a,b,c,d)

!
!-----------------------------------------------------------------------
!
!  Set d(=u_temp) on the boundaries using zero gradient boundary
!  condition.
!
!-----------------------------------------------------------------------
!

  DO j=1,ny-1
    DO i=2,nx-1
      d(i,j,1   )=d(i,j,2   )
      d(i,j,nz-1)=d(i,j,nz-2)
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Updated uforce and u(=u_temp).
!
!-----------------------------------------------------------------------
!

  DO k=2,nz-2
    DO j=1,ny-1
      DO i=2,nx-1
        uforce(i,j,k)=rhostru(i,j,k)*(d(i,j,k)-u(i,j,k))*dt2inv
      END DO
    END DO
  END DO

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=2,nx-1
        u_temp(i,j,k)=d(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE vmiximpu

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


SUBROUTINE vmiximpv(nx,ny,nz,dtbig1,v,rhostrv,rkj3inv2,                 & 1,2
           vforce,v_temp,                                               &
           a,b,c,d,tem2)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the vertical mixing term using implicit scheme in the v
!  momentum equation.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Donghai Wang, X. Song and M. Xue
!  4/2/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx        Number of grid points in the x-direction
!    ny        Number of grid points in the y-direction
!    nz        Number of grid points in the vertical
!
!    dtbig1    the big time step size
!    v         Total v-velocity (m/s)
!    rhostrv  Average rhostr at v points (kg/m**3).
!    rkj3inv2  Array for calculating a, b, c
!              defined as rhostr*kmv*j3inv*j3inv
!    vforce    Acoustically inactive forcing terms in v-eq.
!              (kg/(m*s)**2)
!
!  OUTPUT:
!
!    vforce    Updated vforce.
!    v_temp    Updated total v-velocity (m/s)
!
!  WORK ARRAYS:
!
!    a         lhs coefficient of tridigonal eqations
!    b         lhs coefficient of tridigonal eqations
!    c         lhs coefficient of tridigonal eqations
!    d         rhs coefficient of tridigonal eqations
!    rhostrv   Work array
!    tem2      Work array
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions
  REAL :: dtbig1            !the big time step size
  REAL :: v     (nx,ny,nz)     ! Total v-velocity (m/s)
  REAL :: rhostrv(nx,ny,nz)    ! Average rhostr at v points (kg/m**3)
  REAL :: rkj3inv2(nx,ny,nz)   ! Array for calculating a, b, c
                               ! defined as rhostr*kmv*j3inv*j3inv

  REAL :: vforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in v-eq.(kg/(m*s)**2)
  REAL :: v_temp(nx,ny,nz)     ! Updated total v-velocity (m/s)

  REAL :: dt2inv            !Defined as 1/(2*dtbig1),
  REAL :: a     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: b     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: c     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: d     (nx,ny,nz)     ! rhs coefficient of tridigonal eqations
                               ! The contains solution v_temp on exit.

  REAL :: tem2  (nx,ny,nz)     ! Temporary work array
!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'phycst.inc'      ! Physical constants
  INCLUDE 'globcst.inc'     ! Global constants that control model
                            ! execution
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: tema,accoef
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!call test_dump (rkj3inv2,"XXXbavgsv_rkj3inv2",nx,ny,nz,0,1)
  CALL avgsv(rkj3inv2, nx,ny,nz, 1,nx-1, 1,nz, tem2, a) ! a used as temp
!
!-----------------------------------------------------------------------
!
!  Calculate coefficients of the tridigonal eqation.
!
!-----------------------------------------------------------------------
!

  accoef=0.5*(1.-alfcoef)*dzinv*dzinv
  dt2inv = 0.5/dtbig1

  DO k=2,nz-2
    DO j=1,ny-1
      DO i=1,nx-1
        a(i,j,k)=-accoef*(tem2(i,j,k-1)+tem2(i,j,k  ))
        c(i,j,k)=-accoef*(tem2(i,j,k  )+tem2(i,j,k+1))
        tema    =rhostrv(i,j,k)*dt2inv
        b(i,j,k)=-(a(i,j,k)+c(i,j,k))+tema
        d(i,j,k)=vforce(i,j,k)+tema*v(i,j,k)
      END DO
    END DO
  END DO

  DO j=1,ny-1
    DO i=1,nx-1
      b(i,j,2)   =b(i,j,2)   +a(i,j,2)
      b(i,j,nz-2)=b(i,j,nz-2)+c(i,j,nz-2)
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Call the tridiagonal solver.
!
!-----------------------------------------------------------------------
!

  CALL tridiag2(nx,ny,nz,1,nx-1,2,ny-1,2,nz-2,a,b,c,d)

!
!-----------------------------------------------------------------------
!
!  Set d(=v_temp) on the boundaries using zero gradient boundary
!  condition.
!
!-----------------------------------------------------------------------
!

  DO j=2,ny-1
    DO i=1,nx-1
      d(i,j,1   )=d(i,j,2   )
      d(i,j,nz-1)=d(i,j,nz-2)
    END DO
  END DO
!
!-----------------------------------------------------------------------
!
!  Updated vforce and v(=v_temp).
!
!-----------------------------------------------------------------------
!

  DO k=2,nz-2
    DO j=2,ny-1
      DO i=1,nx-1
        vforce(i,j,k)=rhostrv(i,j,k)*(d(i,j,k)-v(i,j,k))*dt2inv
      END DO
    END DO
  END DO

  DO k=1,nz-1
    DO j=2,ny-1
      DO i=1,nx-1
        v_temp(i,j,k)=d(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE vmiximpv


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


SUBROUTINE vmiximpw(nx,ny,nz,dtbig1,w,rhostrw,w_temp,rkj3inv2,          & 1,1
           wforce,                                                      &
           a,b,c,d)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the vertical mixing term using implicit scheme in the w
!  momentum equation.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Donghai Wang, X. Song and M. Xue
!  4/2/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx       Number of grid points in the x-direction
!    ny       Number of grid points in the y-direction
!    nz       Number of grid points in the vertical
!
!    dtbig1   The big time step size
!    w        Total w-velocity (m/s)
!    rhostrw  Average rhostr at w points (kg/m**3).
!    w_temp   Intermediate value of w
!    rkj3inv2 Array for calculating a, b, c
!             defined as rhostr*kmv*j3inv*j3inv
!    wforce   Acoustically inactive forcing terms in w-eq.
!             (kg/(m*s)**2)
!
!  OUTPUT:
!
!    wforce   Updated wforce.
!
!  WORK ARRAYS:
!
!    dt2inv   Defined as 1/(2*dtbig1)
!    a        lhs coefficient of tridigonal eqations
!    b        lhs coefficient of tridigonal eqations
!    c        lhs coefficient of tridigonal eqations
!    d        rhs coefficient of tridigonal eqations
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions
  REAL :: dtbig1            ! the big time step size
  REAL :: w     (nx,ny,nz)     ! Total w-velocity (m/s)
  REAL :: rhostrw(nx,ny,nz)    ! Average rhostr at w points (kg/m**3)
  REAL :: w_temp(nx,ny,nz)     ! Intermediate value of w
  REAL :: rkj3inv2(nx,ny,nz)   ! Array for calculating a, b, c
                               ! defined as rhostr*kmv*j3inv*j3inv

  REAL :: wforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in w-eq.(kg/(m*s)**2)

  REAL :: dt2inv            ! Defined as 1/(2*dtbig1),
  REAL :: a     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: b     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: c     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: d     (nx,ny,nz)     ! rhs coefficient of tridigonal eqations
                               ! The contains solution updated-w on exit

!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'phycst.inc'      ! Physical constants
  INCLUDE 'globcst.inc'     ! Global constants that control model
                            ! execution
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: tema,accoef
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
!  Calculate coefficients of the tridigonal eqation.
!
!-----------------------------------------------------------------------
!

  accoef=2.0*(1.-alfcoef)*dzinv*dzinv
  dt2inv = 0.5/dtbig1

  DO k=2,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        a(i,j,k)=-accoef*rkj3inv2(i,j,k  )
        c(i,j,k)=-accoef*rkj3inv2(i,j,k+1)
        tema    =rhostrw(i,j,k)*dt2inv
        b(i,j,k)=-(a(i,j,k)+c(i,j,k))+tema
        d(i,j,k)=wforce(i,j,k)+tema*w(i,j,k)
      END DO
    END DO
  END DO

  DO j=1,ny-1
    DO i=1,nx-1
      d(i,j,3)   =d(i,j,3)   - w_temp(i,j,2)*a(i,j,3)
      d(i,j,nz-2)=d(i,j,nz-2)
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Call the tridiagonal solver.
!
!-----------------------------------------------------------------------
!

  CALL tridiag2(nx,ny,nz,1,nx-1,1,ny-1,3,nz-2,a,b,c,d)

!
!-----------------------------------------------------------------------
!
!  Set d on the boundaries using zero gradient boundary
!  condition.
!
!-----------------------------------------------------------------------
!

  DO j=1,ny-1
    DO i=1,nx-1
      d(i,j,2 )= w_temp(i,j,2)
      d(i,j,nz-1)=0.0
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Updated wforce.
!
!-----------------------------------------------------------------------
!
  DO k=2,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        wforce(i,j,k)=rhostrw(i,j,k)*(d(i,j,k)-w(i,j,k))*dt2inv
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE vmiximpw

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


SUBROUTINE vmiximps(nx,ny,nz,dtbig1,s,rhostr,rkj3inv2,                  & 4,1
           sforce,a,b,c,d)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the vertical mixing term using implicit scheme in the
!  scalar equations, including potential temperature, presure, water
!  substances and TKE.
!
!-----------------------------------------------------------------------
!
!  AUTHOR: Donghai Wang, X. Song and M. Xue
!  4/2/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx  Number of grid points in the x-direction
!    ny  Number of grid points in the y-direction
!    nz  Number of grid points in the vertical
!
!    dtbig1    the big time step size
!    s        A scalar varable
!    rhostr   Base state density rhobar times j3 (kg/m**3)
!    rkj3inv2 Array for calculating a, b, c
!             defined as rhostr*kmv*j3inv*j3inv
!    sforce   Acoustically inactive forcing terms in a scalar-eq.
!
!  OUTPUT:
!
!    sforce   Updated sforce.
!
!  WORK ARRAYS:
!
!    a        lhs coefficient of tridigonal eqations
!    b        lhs coefficient of tridigonal eqations
!    c        lhs coefficient of tridigonal eqations
!    d        rhs coefficient of tridigonal eqations
!
!-----------------------------------------------------------------------
!

!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions
  REAL :: dtbig1            ! the big time step size
  REAL :: s     (nx,ny,nz)     ! A total scalar varable
  REAL :: rhostr(nx,ny,nz)     ! Base state density rhobar times j3.
  REAL :: rkj3inv2(nx,ny,nz)   ! Array for calculating a, b, c
                               ! defined as rhostr*kmv*j3inv*j3inv

  REAL :: sforce(nx,ny,nz)     ! Acoustically inactive forcing terms
                               ! in a scalar-eq

  REAL :: dt2inv            ! Defined as 1/(2*dtbig1),
  REAL :: a     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: b     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: c     (nx,ny,nz)     ! lhs coefficient of tridigonal eqations
  REAL :: d     (nx,ny,nz)     ! rhs coefficient of tridigonal eqations
                               ! The contains solution ustar on exit.

!
!-----------------------------------------------------------------------
!
!  Include files:
!
!-----------------------------------------------------------------------
!
  INCLUDE 'phycst.inc'      ! Physical constants
  INCLUDE 'globcst.inc'     ! Global constants that control model
                            ! execution
  INCLUDE 'grid.inc'          ! Grid & map parameters.
!
!-----------------------------------------------------------------------
!
!  Misc. local variables:
!
!-----------------------------------------------------------------------
!
  INTEGER :: i,j,k
  REAL :: tema,accoef
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!

!
!-----------------------------------------------------------------------
!
!  Calculate coefficients of the tridigonal eqation.
!
!-----------------------------------------------------------------------
!

  accoef=0.5*(1.-alfcoef)*dzinv*dzinv
  dt2inv = 0.5/dtbig1

  DO k=2,nz-2
    DO j=1,ny-1
      DO i=1,nx-1
        a(i,j,k)=-accoef*(rkj3inv2(i,j,k-1)+rkj3inv2(i,j,k  ))
        c(i,j,k)=-accoef*(rkj3inv2(i,j,k  )+rkj3inv2(i,j,k+1))
        tema    =rhostr(i,j,k)*dt2inv
        b(i,j,k)=-(a(i,j,k)+c(i,j,k))+tema
        d(i,j,k)=sforce(i,j,k)+tema*s(i,j,k)
      END DO
    END DO
  END DO

  DO j=1,ny-1
    DO i=1,nx-1
      b(i,j,2)   =b(i,j,2)   +a(i,j,2)
      b(i,j,nz-2)=b(i,j,nz-2)+c(i,j,nz-2)
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Call the tridiagonal solver.
!
!-----------------------------------------------------------------------
!

  CALL tridiag2(nx,ny,nz,1,nx-1,1,ny-1,2,nz-2,a,b,c,d)

!
!-----------------------------------------------------------------------
!
!  Set d on the boundaries using zero gradient boundary
!  condition.
!
!-----------------------------------------------------------------------
!

  DO j=1,ny-1
    DO i=1,nx-1
      d(i,j,1   )=d(i,j,2   )
      d(i,j,nz-1)=d(i,j,nz-2)
    END DO
  END DO

!
!-----------------------------------------------------------------------
!
!  Updated sforce.
!
!-----------------------------------------------------------------------
!

  DO k=1,nz-1
    DO j=1,ny-1
      DO i=1,nx-1
        sforce(i,j,k)=rhostr(i,j,k)*(d(i,j,k)-s(i,j,k))*dt2inv
      END DO
    END DO
  END DO

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


SUBROUTINE tridiag2(nx,ny,nz,ibgn,iend,jbgn,jend,                       & 4
           kbgn,kend,a,b,c,d)
!
!-----------------------------------------------------------------------
!
!  PURPOSE:
!
!  Calculate the solution for a tridiagonal equations.
!  Note:
!       a: left of main diagonal, useful range [kbgn+1,kend];
!       b: main diagonal, useful range [kbgn,kend];
!       c: right of main diagonal, useful range [kbgn,kend-1];
!       d: right hand side of equations.
!
!-----------------------------------------------------------------------
!
!
!  AUTHOR: X. Song, Donghai Wang and M. Xue
!  4/2/96
!
!  MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
!-----------------------------------------------------------------------
!
!  INPUT :
!
!    nx       Number of grid points in the x-direction
!    ny       Number of grid points in the y-direction
!    nz       Number of grid points in the vertical
!
!    ibgn     i-index where operation begins.
!    iend     i-index where operation ends.
!    jbgn     j-index where operation begins.
!    jend     j-index where operation ends.
!    kbgn     k-index where operation begins.
!    kend     k-index where operation ends.
!
!    a        left of main diagonal, useful range [kbgn+1,kend]
!    b        main diagonal, useful range [kbgn,kend]
!    c        right of main diagonal, useful range [kbgn,kend-1]
!    d        right hand side of equations
!
!  OUTPUT:
!
!    d        The solution
!
!-----------------------------------------------------------------------
!
!  Variable Declarations:
!
!-----------------------------------------------------------------------
!
  IMPLICIT NONE             ! Force explicit declarations

  INTEGER :: nx, ny, nz        ! Number of grid points in 3 directions

  REAL :: c(nx,ny,nz)       ! Right of main diagonal
  REAL :: a(nx,ny,nz)       ! Left of main diagonal
  REAL :: d(nx,ny,nz)       ! Right hand side of equations
  REAL :: b(nx,ny,nz)       ! Main diagonal

  INTEGER :: ibgn,iend,jbgn,jend,kbgn,kend
  INTEGER :: i,j,k
  REAL :: r
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!  Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
  DO k=kbgn+1,kend
    DO j=jbgn,jend
      DO i=ibgn,iend
        r=a(i,j,k)/b(i,j,k-1)
        b(i,j,k)=b(i,j,k)-r*c(i,j,k-1)
        d(i,j,k)=d(i,j,k)-r*d(i,j,k-1)
      END DO
    END DO
  END DO

  DO j=jbgn,jend
    DO i=ibgn,iend
      d(i,j,kend)=d(i,j,kend)/b(i,j,kend)
    END DO
  END DO

  DO k=kend-1,kbgn,-1
    DO j=jbgn,jend
      DO i=ibgn,iend
        d(i,j,k)=(d(i,j,k)-c(i,j,k)*d(i,j,k+1))/b(i,j,k)
      END DO
    END DO
  END DO

  RETURN
END SUBROUTINE tridiag2