!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer, 
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms 
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer 
!version 3 or (at your option) any later version that should be found at: 
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html 
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software; 
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec), 
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
***s/r p_apply_ad - adjoint of apply consistency with related dynamical variables
*
#include "model_macros_f.h"
*

      subroutine p_apply_ad ( F_tdu,F_tdv,F_tdt,F_trm,F_tp,F_qp, 1,14
     $                        F_tpm,F_trpm,F_qpm,
     $                        DIST_DIM, Nk)
*
      implicit none
*
      integer DIST_DIM,Nk
      real 
     $     F_tdu   (DIST_SHAPE,Nk), F_tdv   (DIST_SHAPE,Nk),
     $     F_tdt   (DIST_SHAPE,Nk), F_trm   (DIST_SHAPE,Nk,*),
     $     F_tp    (DIST_SHAPE,Nk), F_qp    (DIST_SHAPE,Nk),
     $     F_tpm   (DIST_SHAPE,Nk), F_trpm  (DIST_SHAPE,Nk),
     $     F_qpm   (DIST_SHAPE,Nk)
*
*author 
*     Stephane Laroche        Janvier 2002
*
*revision
* v3_00 - Laroche S.        - initial MPI version
* v3_03 - Tanguay M.        - use v4d_zerohalo 
* v3_20 - Laroche S.        - slight modification to rpn_comm_xch_halo call
* v3_21 - Tanguay M.        - Revision Openmp 
* v3_30 - Tanguay M.        - adapt TL/AD to itf/new tendencies
*                           - Validation for LAM version  
*
*object
*       TLM of apply consistency of the tendencies on physics variables
*       with related dynamical variables. Interpolate wind
*       tendancies toward theirs respective grids.
*
*arguments
*arguments
*  Name        I/O                 Description
*----------------------------------------------------------------
* F_tcond       I    -
*	
*implicits
#include "glb_ld.cdk"
#include "cstv.cdk"
#include "lun.cdk"
#include "hblen.cdk"
#include "dcst.cdk"
#include "schm.cdk"
#include "geomg.cdk"
#include "p_cond.cdk"
#include "intuv.cdk"
#include "inuvl.cdk"
#include "vt0.cdk"
#include "vt1.cdk"
#include "itf_phy_busind.cdk"
#include "v4dg.cdk"
*
*modules
      integer  vmmlod,vmmget,vmmuld
      external vmmlod,vmmget,vmmuld
*
      integer*8 pnt_trp(phyt_ntr),pnt_trm(phyt_ntr)
      integer i, j, k, n, i0, in, j0, jn, err, key1(10), ng,
     $     keyp(phyt_ntr), keym(h2o_ntr), keyp_, keym_
      real trajexp
      real*8, parameter :: ZERO_8 = 0.0
      real  wk3(LDIST_SHAPE,Nk) ,    
     $      wk5(LDIST_SHAPE,Nk) ,   wk6(LDIST_SHAPE,Nk), trp, trm,
     $      wk2(LDIST_SHAPE,Nk) ,   wk1(LDIST_SHAPE,Nk),   
     $   F_tdum(LDIST_SHAPE,Nk), F_tdvm(LDIST_SHAPE,Nk),
     $   F_tdtm(LDIST_SHAPE,Nk), F_trmm(LDIST_SHAPE,Nk),
     $   F_st1m(LDIST_SHAPE)
      pointer (patrp, trp(LDIST_SHAPE,*)),(patrm, trm(LDIST_SHAPE,*))
*     __________________________________________________________________
*
      keyp_ = VMM_KEY (trt1)
      if (phyt_ntr.gt.0) then
         do n=1,phyt_ntr
            keyp(n) = keyp_ + n
         end do
         err = vmmlod(keyp,phyt_ntr)
         do n=1,phyt_ntr
            err = vmmget(keyp(n),patrp,trp)
            pnt_trp(n) = patrp
         end do
      endif
*
      key1(1) = VMM_KEY(fipt1)
      key1(2) = VMM_KEY(fit1 )
      key1(3) = VMM_KEY(tplt1)
      key1(4) = VMM_KEY(tpt1 )
      key1(5) = VMM_KEY(tdt1 )
      key1(6) = VMM_KEY(psdt1)
      key1(7) = VMM_KEY(ut1)
      key1(8) = VMM_KEY(vt1)
      key1(9) = VMM_KEY(tt1)
      key1(10)= VMM_KEY(st1)
      err = vmmlod(key1,10)
      err = VMM_GET_VAR(fipt1)
      err = VMM_GET_VAR(fit1 )
      err = VMM_GET_VAR(tplt1)
      err = VMM_GET_VAR(tpt1 )
      err = VMM_GET_VAR(tdt1 )
      err = VMM_GET_VAR(psdt1)
      err = VMM_GET_VAR(ut1)
      err = VMM_GET_VAR(vt1)
      err = VMM_GET_VAR(tt1)
      err = VMM_GET_VAR(st1)
*
!$omp parallel
* 
******START TRAJECTORY **********************************************
*     Zero adjoint WORK variables
*     ---------------------------
!$omp do 
      do k=1,l_nk
       wk1(:,:,k)  = ZERO_8
       wk2(:,:,k)  = ZERO_8
       wk3(:,:,k)  = ZERO_8
       wk5(:,:,k)  = ZERO_8
       wk6(:,:,k)  = ZERO_8
      end do
!$omp end do 
*
******START TRAJECTORY **********************************************
*
*     Read TRAJ for the simplified physics
*     -------------------------------------
!$omp single 
      call v4d_rwtraj_apply(F_tdum,F_tdvm,F_tdtm,F_trmm,F_st1m,LDIST_DIM,Nk)
!$omp end single 
*
*     Compute VIRTUAL temperature tendency from:  temperature tendency,
*     specific humidity, virtual temperature & specific humidity tendency
*     -------------------------------------------------------------------
*
!$omp do 
      do k=1,l_nk
      do j= 1+pil_s, l_nj-pil_n 
      do i= 1+pil_w, l_ni-pil_e 
        F_tdtm(i,j,k) = F_tdtm(i,j,k)*( 1. + Dcst_delta_8*F_trpm(i,j,k) )
     $                + Dcst_delta_8*F_tpm(i,j,k)*F_trmm(i,j,k)
      end do
      end do
      end do
!$omp end do 
*
******END TRAJECTORY ************************************************
*
*   3. apply tendencies to associated variables
*      ----------------------------------------
*
!$omp do 
      do k=1,l_nk
      do j= 1+pil_s, l_nj-pil_n 
      do i= 1+pil_w, l_ni-pil_e 
         wk6  (i,j,k) = wk6  (i,j,k) + Cstv_dt_8*fit1 (i,j,k)
         wk6  (i,j,k) = wk6  (i,j,k) + Cstv_dt_8*fipt1(i,j,k)
C        F_tdt(i,j,k) = F_tdt(i,j,k) + Cstv_dt_8*tpt1 (i,j,k)
         wk1  (i,j,k) = wk1  (i,j,k) + Cstv_dt_8*tpt1 (i,j,k)
         F_tp (i,j,k) = F_tp (i,j,k) + Cstv_dt_8*tplt1(i,j,k)
         F_qp (i,j,k) = F_qp (i,j,k) + Cstv_dt_8*tdt1 (i,j,k)
         wk3  (i,j,k) = wk3  (i,j,k) + Cstv_dt_8*psdt1(i,j,k)
      end do
      end do
      end do
!$omp end do 
*
*   2. apply tendencies to primary variables
*      -------------------------------------
!$omp do 
      do k=1,l_nk
         do j= 1+pil_s, l_nj-pil_n 
         do i= 1+pil_w, l_ni-pil_e 
C           F_tdt(i,j,k) = F_tdt(i,j,k) + Cstv_dt_8*tt1(i,j,k)
            wk1  (i,j,k) = wk1  (i,j,k) + Cstv_dt_8*tt1(i,j,k)
         end do
         end do
         do j= 1+pil_s, l_nj-pil_n 
         do i= 1+pil_w, l_niu-pil_e 
            F_tdu(i,j,k) = F_tdu(i,j,k) + Cstv_dt_8*ut1(i,j,k)
         end do
         end do
         do j= 1+pil_s, l_njv-pil_n 
         do i= 1+pil_w, l_ni-pil_e 
            F_tdv(i,j,k) = F_tdv(i,j,k) + Cstv_dt_8*vt1(i,j,k)
         end do
         end do
      end do
!$omp end do 
*
      if (phyt_ntr.gt.0) then
         do n=1,phyt_ntr
            patrp = pnt_trp(n) 
!$omp do 
            do k=1,l_nk
            do j= 1+pil_s, l_nj-pil_n 
            do i= 1+pil_w, l_ni-pil_e
               F_trm(i,j,k,n) = F_trm(i,j,k,n) + Cstv_dt_8*trp(i,j,k)
            end do
            end do
            end do
!$omp end do 
!$omp single
         if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) ) then
            call nesajr_ad (F_trm(minx,miny,1,n), wk2, LDIST_DIM,G_nk,
     $                                          0,0,Hblen_tx,Hblen_ty)
         endif
!$omp end single
         end do
      endif
*
!$omp end parallel 
*
      if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) ) then
         call nesajr_ad (F_tdu, wk2, LDIST_DIM,G_nk,1,0,Hblen_tx,Hblen_ty)
         call nesajr_ad (F_tdv, wk2, LDIST_DIM,G_nk,0,1,Hblen_tx,Hblen_ty)
      endif
*
*  5. Compute total divergence and vertical motion associated tendencies
*     d/dt ( total D ) in xrpqt1,  d/dt ( pi*-dot ) in wk3
*     -------------------------------------------------------------------
*
*     TRAJECTORY
*     ----------
      call rpn_comm_xch_halo( F_tdum, LDIST_DIM, l_niu, l_nj,G_nk,
     $                G_halox,G_haloy,G_periodx,G_periody,l_ni,0 )
      call rpn_comm_xch_halo( F_tdvm, LDIST_DIM, l_ni, l_njv,G_nk,
     $                G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) 
*
         if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) ) then
            call nesajr_ad (wk3 ,wk2,LDIST_DIM,G_nk,0,0,Hblen_tx,Hblen_ty)
            call nesajr_ad (F_tp,wk2,LDIST_DIM,G_nk,0,0,Hblen_tx,Hblen_ty)
            call nesajr_ad (F_qp,wk2,LDIST_DIM,G_nk,0,0,Hblen_tx,Hblen_ty)
         endif
*
*     ADJ 
*     ---
      call uv2tdpsd_ad( F_qp, wk3, F_tdu, F_tdv,  st1,
     $                            F_tdum, F_tdvm, F_st1m,
     $                  LDIST_DIM, G_nk )
*
!$omp parallel
*
*     Zero adjoint WORK variables
*     ---------------------------
!$omp do 
      do k=1,l_nk
      do j=l_miny,l_maxy
      do i=l_minx,l_maxx
       wk3(i,j,k)  = ZERO_8
      end do
      end do
      end do
!$omp end do 
*
!$omp single 
      call rpn_comm_adj_halo( F_tdu, LDIST_DIM, l_niu, l_nj,G_nk,
     $                G_halox,G_haloy,G_periodx,G_periody,l_ni,0 )
      call rpn_comm_adj_halo( F_tdv, LDIST_DIM, l_ni, l_njv,G_nk,
     $                G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) 
*
*     Zeroing halo
*     ------------
      call v4d_zerohalo ( F_tdu,l_niu,l_nj,LDIST_DIM, l_nk)
      call v4d_zerohalo ( F_tdv,l_ni,l_njv,LDIST_DIM, l_nk)
!$omp end single 
*
*  3. Compute d/dt ( T'lin ) = pi* d/dt ( T ) exp(s-q) ; put in xrptt1
*     Note:   d/dt ( T' ) = d/dt ( T )  i.e. not computed
*     ----------------------------------------------------------------
*
!$omp do 
      do k=1,l_nk
      do j= 1+pil_s, l_nj-pil_n 
      do i= 1+pil_w, l_ni-pil_e 
         F_qp(i,j,k) = F_qp(i,j,k) + geomg_z_8(k)*F_tp(i,j,k)
         F_tp(i,j,k) = ZERO_8
      end do
      end do
      end do
!$omp end do 
*
!$omp single
         if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) )
     $     call nesajr_ad (wk6,wk2,LDIST_DIM,G_nk,0,0,Hblen_tx,Hblen_ty)
!$omp end single
*
!$omp end parallel 
*
      ng = (l_maxx-l_minx+1)*(l_maxy-l_miny+1)
      call hatoprg0_ad ( wk6,wk5,1.0,geomg_hz_8,ng,G_nk )
*
*  2. Compute d/dt ( phi ) from d/dt ( T )
*     Note:   d/dt ( phi' ) = d/dt ( phi ) i.e. not computed
*     ------------------------------------------------------
*
!$omp parallel private( trajexp )
*
*     ADJ
*     ---
!$omp do 
      do j= 1+pil_s, l_nj-pil_n 
      do k=1,l_nk
      do i= 1+pil_w, l_ni-pil_e 

      F_qp(i,j,k) = F_qp(i,j,k) + wk5(i,j,k)*Dcst_rgasd_8
      wk5(i,j,k)  = ZERO_8

      trajexp      = exp(F_st1m(i,j) - F_qpm(i,j,k))
      F_tdt(i,j,k) = F_tdt(i,j,k) + F_qp(i,j,k)              *trajexp
      st1(i,j)     = st1(i,j)     + F_qp(i,j,k)*F_tdtm(i,j,k)*trajexp
      F_qp(i,j,k)  =              - F_qp(i,j,k)*F_tdtm(i,j,k)*trajexp
      end do
      end do
      end do
!$omp end do 
*
!$omp single
      if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) )
     $     call nesajr_ad (wk1,wk2,LDIST_DIM,G_nk,0,0,Hblen_tx,Hblen_ty)
!$omp end single
*
*   1.1  Compute VIRTUAL temperature tendency from:  temperature tendency,
*        specific humidity, virtual temperature & specific humidity tendency
*        -------------------------------------------------------------------
*
      patrp = pnt_trp(hucond)
*
!$omp do  
      do k=1,l_nk
      do j= 1+pil_s, l_nj-pil_n 
      do i= 1+pil_w, l_ni-pil_e 
*
*       TRAJECTORY
*       ----------
        F_tdtm(i,j,k) = (F_tdtm(i,j,k)
     $                -  Dcst_delta_8*F_tpm(i,j,k)*F_trmm(i,j,k))
     $                /  (1. + Dcst_delta_8*F_trpm(i,j,k))
*
*       ADJ
*       ---
        F_tdt(i,j,k) = wk1(i,j,k) + F_tdt(i,j,k)
          wk1(i,j,k) = ZERO_8
*
        trp(i,j,k)          = trp(i,j,k)          
     $                      + F_tdt(i,j,k) * Dcst_delta_8 * F_tdtm(i,j,k)
        F_tp(i,j,k)         = F_tp(i,j,k)         
     $                      + F_tdt(i,j,k) * Dcst_delta_8 * F_trmm(i,j,k)
        F_trm(i,j,k,hucond) = F_trm(i,j,k,hucond) 
     $                      + F_tdt(i,j,k) * Dcst_delta_8 * F_tpm(i,j,k)
        F_tdt(i,j,k)        = F_tdt(i,j,k) * (1. + Dcst_delta_8*F_trpm(i,j,k))

      end do
      end do
      end do
!$omp end do  
*
!$omp do 
      do k=1,l_nk
         if ( G_lam .and. ((Hblen_tx.gt.0).or.(Hblen_ty.gt.0)) )
     $      wk2(:,:,k) = 0.
         wk3(:,:,k) = 0.
      end do
!$omp end do 
*
!$omp end parallel 
*
*  4. Interpolation of the wind associated tendencies
*     -----------------------------------------------
*
      call itf_phy_uvgridscal0_ad ( F_tdu, F_tdv, LDIST_DIM, G_nk, .false. )
*
      return
      end