subroutine turbl_ad(pges,tges,oges,u,v,prs,t,termu,termv,termt,jstart,jstop)
!$$$  subprogram documentation block
!                .      .    .
! subprogram:    turbl_ad
!
!   prgrmmr:
!
! abstract:      Adjoint of turbl_tl
!
! program history log:
!   2008-04-02  safford -- add subprogram doc block, rm unused vars and uses
!
!   input argument list:
!     pges     -
!     tges     -
!     oges     -
!     prs      -
!     t        -
!     u        -
!     v        -
!     termu    -
!     termv    -
!     termt    -
!
!   output argument list:
!     prs      -
!     t        -
!     u        -
!     v        -
!     termu    -
!     termv    -
!     termt    -
!
! attributes:
!   language:  f90
!   machine:
!
!$$$

  use constants, only: rd_over_cp,two,rd_over_g,half,zero,one,three,grav
  use kinds, only: r_kind,i_kind 
  use gridmod, only: lat2,lon2,nsig,nsig_hlf
  use turblmod, only: use_pbl
  use turblmod, only: dudz,dvdz,dodz,ri,rf,kar0my20,zi,km,kh,sm,sh
  use turblmod, only: lmix,dudtm,dvdtm,dtdtm,rdzi,rdzl
  use turblmod, only: a0my20,c0my20,d0my20, &
                      f7my20,f8my20,karmy20
  use turblmod, only: eps_m
  use turblmod, only: fsm_my20,fsh_my20
  use turblmod, only: ri_int
  implicit none


! Declare passed variables
  real(r_kind),dimension(lat2,lon2,nsig+1),intent(in   ) :: pges
  real(r_kind),dimension(lat2,lon2,nsig)  ,intent(in   ) :: tges,oges
  real(r_kind),dimension(lat2,lon2,nsig+1),intent(inout) :: prs
  real(r_kind),dimension(lat2,lon2,nsig)  ,intent(inout) :: t,u,v
  real(r_kind),dimension(lat2,lon2,nsig)  ,intent(inout) :: termu,termv,termt
  integer(i_kind)                         ,intent(in   ) :: jstart,jstop

! Declare local variables
  real(r_kind),dimension(nsig_hlf):: t_bck,o_bck
  real(r_kind),dimension(nsig_hlf):: dudz_bck,dvdz_bck,dodz_bck,ri_bck,rf_bck
  real(r_kind),dimension(nsig_hlf):: rdudz_bck,rdvdz_bck,sm_bck,sh_bck
  real(r_kind),dimension(nsig_hlf):: rdzl_bck,rdzi_bck,t_tl,u_tl,v_tl,o_tl,dzi_tl,zl_tl
  real(r_kind),dimension(nsig_hlf):: rssq,rofbck,rshbck
  real(r_kind),dimension(nsig_hlf+1):: km_bck,kh_bck,p_bck,zi_bck
  real(r_kind),dimension(nsig_hlf+1):: km_tl,kh_tl,p_tl,zi_tl
  real(r_kind),dimension(2:nsig_hlf):: dzl_tl,dodz_tl,dudz_tl,dvdz_tl,ri_tl
  real(r_kind),dimension(2:nsig_hlf):: rf_tl,sh_tl,sm_tl,lmix_tl
  integer(i_kind),dimension(nsig_hlf):: lssq
  real(r_kind):: px,rpx,a1,a2,ax,bx,ssq,rtbck
  real(r_kind):: alph,beta,gamm,gam1,gam2,alph1,alph2,delt,bet
  real(r_kind):: rdzibk,rdzlbk,kmbk,khbk,rpbck,hrdzbk,ardzbk
  real(r_kind):: kmaz_bck,khaz_bck,kmaz_tl,khaz_tl
  integer(i_kind) i,j,k

  if(.not. use_pbl)return

  do i=1,lat2
     do j=jstart,jstop

! background fields
        do k=1,nsig_hlf
           t_bck(k)=tges(i,j,k)
           p_bck(k)=pges(i,j,k)
           o_bck(k)=oges(i,j,k)
           rdzi_bck(k)=rdzi(i,j,k)
           rdzl_bck(k)=rdzl(i,j,k)
           zi_bck(k)=zi(i,j,k)
        end do
        p_bck(nsig_hlf+1) =pges(i,j,nsig_hlf+1)
        zi_bck(nsig_hlf+1)=zi  (i,j,nsig_hlf+1)

        do k=1,nsig_hlf
           dodz_bck(k)=dodz(i,j,k)
           dudz_bck(k)=dudz(i,j,k)
           dvdz_bck(k)=dvdz(i,j,k)
           ri_bck(k)=ri(i,j,k)
           rf_bck(k)=rf(i,j,k)
           sm_bck(k)=sm(i,j,k)
           sh_bck(k)=sh(i,j,k)
           km_bck(k)=km(i,j,k)
           kh_bck(k)=kh(i,j,k)
        end do
        km_bck(nsig_hlf+1)=zero
        kh_bck(nsig_hlf+1)=zero

        do k=2,nsig_hlf
           ssq=dudz_bck(k)**2+dvdz_bck(k)**2
           lssq(k)=1
           if(ssq < eps_m) then
              lssq(k)=0
              ssq = eps_m
           end if
           rssq(k)=one/ssq
           rdudz_bck(k)=dudz_bck(k)*rssq(k)
           rdvdz_bck(k)=dvdz_bck(k)*rssq(k)
           rofbck(k)=one/(one-rf_bck(k))
           rshbck(k)=one/sh_bck(k)
        end do 

! initialize perturbations

        do k=nsig_hlf,2,-1
           dzl_tl(k)=zero
           lmix_tl(k)=zero
           sm_tl(k)=zero; sh_tl(k)=zero
           ri_tl(k)=zero; rf_tl(k)=zero
           dudz_tl(k)=zero; dvdz_tl(k)=zero; dodz_tl(k)=zero
        enddo
        do k=nsig_hlf,1,-1
           dzi_tl(k)=zero
           zi_tl(k)=zero;   zl_tl(k)=zero
           km_tl(k)=zero; kh_tl(k)=zero
           t_tl(k)=zero
           o_tl(k)=zero; u_tl(k)=zero; v_tl(k)=zero; p_tl(k)=zero
        end do
        p_tl(nsig_hlf+1)=zero; zi_tl(nsig_hlf+1)=zero
        km_tl(nsig_hlf+1)=zero; kh_tl(nsig_hlf+1)=zero

        
! adjoint of update of perturbation tendencies

        do k=nsig_hlf,1,-1
           kmaz_tl=zero
           khaz_tl=zero
           rdzibk=rdzi_bck(k)
           ax=t_bck(k)/o_bck(k)
           hrdzbk=half*rdzibk
           ardzbk=ax*hrdzbk
           kmaz_bck=(km_bck(k)+km_bck(k+1))*hrdzbk
           khaz_bck=(kh_bck(k)+kh_bck(k+1))*ardzbk
           if(k>1) then
              kmaz_tl=-dudz_bck(k)*termu(i,j,k)-dvdz_bck(k)*termv(i,j,k)
              khaz_tl=-dodz_bck(k)*termt(i,j,k)
              dudz_tl(k)=-kmaz_bck*termu(i,j,k)
              dvdz_tl(k)=-kmaz_bck*termv(i,j,k)
              dodz_tl(k)=-khaz_bck*termt(i,j,k)
           end if
           if(k<nsig_hlf) then
              kmaz_tl= dudz_bck(k+1)*termu(i,j,k)+dvdz_bck(k+1)*termv(i,j,k)+kmaz_tl
              khaz_tl= dodz_bck(k+1)*termt(i,j,k)+khaz_tl
              dudz_tl(k+1)= kmaz_bck*termu(i,j,k)+dudz_tl(k+1)
              dvdz_tl(k+1)= kmaz_bck*termv(i,j,k)+dvdz_tl(k+1)
              dodz_tl(k+1)= khaz_bck*termt(i,j,k)+dodz_tl(k+1)
           end if
           dzi_tl(k)= -rdzibk*(dudtm(i,j,k)*termu(i,j,k)+&
                               dvdtm(i,j,k)*termv(i,j,k)+&
                               dtdtm(i,j,k)*termt(i,j,k) )
           if(k>1) then
              km_tl(k)  =hrdzbk*kmaz_tl
              kh_tl(k)  =ardzbk*khaz_tl
           end if
           if(k<nsig_hlf) then
              km_tl(k+1)=hrdzbk*kmaz_tl+km_tl(k+1)
              kh_tl(k+1)=ardzbk*khaz_tl+kh_tl(k+1)
           end if
        end do


! adjoint of perturbation of km and kh

        do k=nsig_hlf,2,-1
           kmbk=km_bck(k)
           khbk=kh_bck(k)
           if(ri_int(i,j,k)==1) then
              km_tl(k)=zero
              kh_tl(k)=zero
           end if
           bx=half/sm_bck(k)
           bet=-half*rofbck(k)
           ax=two/lmix(i,j,k)
           delt= kmbk*ax
           gam1= kmbk*rdudz_bck(k)
           gam2= kmbk*rdvdz_bck(k)
           beta= kmbk*bet
           alph= kmbk*three*bx
           sm_tl(k)  =km_tl(k)*alph  
           rf_tl(k)  =km_tl(k)*beta  
           dudz_tl(k)=km_tl(k)*gam1+dudz_tl(k)
           dvdz_tl(k)=km_tl(k)*gam2+dvdz_tl(k)
           lmix_tl(k)=km_tl(k)*delt          
 
           delt= khbk*ax
           gam1= khbk*rdudz_bck(k)
           gam2= khbk*rdvdz_bck(k)
           beta= khbk*bet
           alph2=khbk*rshbck(k)
           alph= khbk *bx
           sh_tl(k)  =kh_tl(k)*alph2  
           sm_tl(k)  =kh_tl(k)*alph+sm_tl(k)
           rf_tl(k)  =kh_tl(k)*beta+rf_tl(k)
           dudz_tl(k)=kh_tl(k)*gam1+dudz_tl(k)
           dvdz_tl(k)=kh_tl(k)*gam2+dvdz_tl(k)
           lmix_tl(k)=kh_tl(k)*delt+lmix_tl(k)      
        end do


! adjoint of perturbation of flux Richardson number, sh, sm and lmix

        do k=nsig_hlf,2,-1
           zi_tl(k)=karmy20/(one+kar0my20(i,j)*(zi_bck(k)-zi_bck(1)))**2 *lmix_tl(k)  
           if(ri_int(i,j,k)==1) then
              sh_tl(k)=zero
              rf_tl(k)=zero
              sm_tl(k)=zero
           end if 
           sh_tl(k)=sh_tl(k)+sm_bck(k)*rshbck(k)           *sm_tl(k) 
           rf_tl(k)=rf_tl(k)+fsm_my20*sh_bck(k)   &     
                            /(f7my20-f8my20*rf_bck(k))**2  *sm_tl(k) &
                            +fsh_my20*rofbck(k)**2         *sh_tl(k)
           ri_tl(k)=        a0my20*(one-(two*ri_bck(k)-c0my20)/ &
                   (two*sqrt(ri_bck(k)*(ri_bck(k)-c0my20)+d0my20))) *rf_tl(k)
        end do


! adjoint of perturbation of Richardson number

        do k=nsig_hlf,2,-1
           if(ri_int(i,j,k)==1) ri_tl(k) = zero
           rtbck=one/(t_bck(k)+t_bck(k-1))
           alph=-ri_bck(k)*two*lssq(k)
           alph1=alph*rdudz_bck(k)
           alph2=alph*rdvdz_bck(k)
           beta= grav*rssq(k)*rtbck*two
           gamm=-ri_bck(k)*rtbck
           dudz_tl(k)=ri_tl(k)*alph1 + dudz_tl(k)
           dvdz_tl(k)=ri_tl(k)*alph2 + dvdz_tl(k)
           dodz_tl(k)=ri_tl(k)*beta  + dodz_tl(k)
           t_tl(k)   =ri_tl(k)*gamm  + t_tl(k)
           t_tl(k-1) =ri_tl(k)*gamm 
        end do


! adjoint of perturbation of vertical derivatives


        do k=nsig_hlf,2,-1
           rdzlbk=rdzl_bck(k)
           o_tl(k  )=o_tl(k  )+rdzlbk*dodz_tl(k)
           o_tl(k-1)=         -rdzlbk*dodz_tl(k)
           v_tl(k  )=v_tl(k  )+rdzlbk*dvdz_tl(k)
           v_tl(k-1)=         -rdzlbk*dvdz_tl(k)
           u_tl(k  )=u_tl(k  )+rdzlbk*dudz_tl(k)
           u_tl(k-1)=         -rdzlbk*dudz_tl(k)
           dzl_tl(k)=         -rdzlbk*dvdz_bck(k)*dvdz_tl(k) &
                              -rdzlbk*dodz_bck(k)*dodz_tl(k) &
                              -rdzlbk*dudz_bck(k)*dudz_tl(k)
        end do


! adjoint of perturbation of heights

        do k=nsig_hlf,2,-1
           zl_tl(k  )=+dzl_tl(k)+zl_tl(k  )
           zl_tl(k-1)=-dzl_tl(k) !+zl_tl(k-1)
        end do

        do k=nsig_hlf,1,-1
           zi_tl(k+1)=zl_tl(k)*half  + zi_tl(k+1)
           zi_tl(k     )=zl_tl(k)*half  + zi_tl(k  )
        end do

        do k=nsig_hlf,1,-1
           zi_tl(k) =zi_tl(k+1)+zi_tl(k)
           dzi_tl(k)=zi_tl(k+1)+dzi_tl(k)
        end do
        zi_tl(1)=zero    


! adjoint of perturbation fields

        do k=nsig_hlf,1,-1
           rpbck=one/(p_bck(k)+p_bck(k+1))
           rpx = two*rpbck
           a1 = rd_over_g*rpx
           a2 = a1*t_bck(k)*rpx
           gamm=-a1*(p_bck(k+1)-p_bck(k))
           beta=-a2*p_bck(k)
           alph= a2*p_bck(k+1)
           px=rd_over_cp*rpbck
           alph1=o_bck(k)/t_bck(k)
           alph2=-o_bck(k)*px
           t_tl(k  )= gamm*dzi_tl(k)+o_tl(k)*alph1 + t_tl(k  )
           p_tl(k+1)= beta*dzi_tl(k)+o_tl(k)*alph2 + p_tl(k+1)
           p_tl(k     )= alph*dzi_tl(k)+o_tl(k)*alph2 
        end do


        do k=nsig_hlf,1,-1
           t(i,j,k)=t_tl(k)+t(i,j,k)
           u(i,j,k)=u_tl(k)+u(i,j,k)
           v(i,j,k)=v_tl(k)+v(i,j,k)
           prs(i,j,k)=p_tl(k)+prs(i,j,k)
        end do
        prs(i,j,nsig_hlf+1)=p_tl(nsig_hlf+1)+prs(i,j,nsig_hlf+1)

     end do 
  end do 

  return
end subroutine turbl_ad
