!--------------------------------------------------------------------------------------------------
!  DOXYGEN
!> @brief HORIZONTAL ADVECTION OF HEIGHT
!> @details CALCULATES DIAGNOSTICALLY THE CONTRIBUTION OF THE HORIZONTAL ADVECTION OF HEIGHT.
!> @author ORIGINATOR - JANJIC 
!> @date 96-05-?? \n
!> @author LUCCI 
!> @date 18-03-20 \n
!> @version V1.1.0
!> @details MODERNIZATION OF THE CODE, INCLUDING:
!!                      * F77 TO F90/F95
!!                      * INDENTATION & UNIFORMIZATION CODE
!!                      * REPLACEMENT OF COMMONS BLOCK FOR MODULES
!!                      * DOCUMENTATION WITH DOXYGEN
!!                      * OPENMP FUNCTIONALITY 
!<
!> @details <b>Use Module:</b>
!! @arg @c CONTIN
!! @arg @c CTLBLK
!! @arg @c DYNAM
!! @arg @c F77KINDS
!! @arg @c LOOPS
!! @arg @c MASKS
!! @arg @c METRCS
!! @arg @c MPPSTAFF
!! @arg @c NHYDRO
!! @arg @c PARMETA
!! @arg @c VRBLS
!> @details <b>Driver:</b> 
!<
!> @details <b>Calls:</b>
!! @arg @c AVRH
!! @arg @c BOCOHMPI
!! @arg @c CORNERHM2
!--------------------------------------------------------------------------------------------------
    SUBROUTINE HADZ_GEF
!--------------------------------------------------------------------------------------------------
! SUBROUTINE HADZ_GEF
! 
! SUBPROGRAM: HADZ_GEF - HORIZONTAL ADVECTION OF HEIGHT
! PROGRAMMER: JANJIC 
! ORG: W/NP22
! DATE: 96-05-??
!
! ABSTRACT:  
! HADZ CALCULATES DIAGNOSTICALLY THE CONTRIBUTION OF THE HORIZONTAL ADVECTION OF HEIGHT
!
! PROGRAM HISTORY LOG:
! 96-05-??  JANJIC  - ORIGINATOR
! 18-03-20  LUCCI   - MODERNIZATION OF THE CODE, INCLUDING:
!                     * F77 TO F90/F95
!                     * INDENTATION & UNIFORMIZATION CODE
!                     * REPLACEMENT OF COMMONS BLOCK FOR MODULES
!                     * DOCUMENTATION WITH DOXYGEN
!                     * OPENMP FUNCTIONALITY 
!
!
! INPUT ARGUMENT LIST:
! NONE 
!
! OUTPUT ARGUMENT LIST:
! NONE
!
! INPUT/OUTPUT ARGUMENT LIST:
! NONE 
!
! INPUT FILES:
! NONE
!
! OUTPUT FILES:
! NONE
!
! USE MODULES: CONTIN
!              CTLBLK
!              DYNAM
!              F77KINDS
!              LOOPS
!              MASKS
!              METRCS
!              MPPSTAFF
!              NHYDRO
!              PARMETA
!              VRBLS
!
! DRIVER     : -----        
!
! CALLS      : AVRH
!              BOCOHMPI
!              CORNERHM2         
!-------------------------------------------------------------------------------------------------
    USE CONTIN
    USE CTLBLK
    USE DYNAM
    USE F77KINDS
    USE LOOPS
    USE MASKS
    USE METRCS
    USE MPPSTAFF
    USE NHYDRO
    USE PARMETA
    USE VRBLS
!
    IMPLICIT NONE
!
    INCLUDE "mpif.h" 
!
    INTEGER(KIND=I4)                                                                            ::&
    & I       , J       , L       , IT
!
    REAL   (KIND=R4)    , PARAMETER :: G = 9.8
!
    INTEGER(KIND=I4)    , PARAMETER :: NTSHY = 3
!
    REAL   (KIND=R4)    , DIMENSION(0:IM+1, 0:JM+1)                                             ::&
    & HM      , DPDE    , GDPD    , RGDP    , AGDP    ,                                           &
    & UT      , VT      , ZT      , UTLD    , VTLD    ,                                           & 
    & FXE     , FYE     , FXB     , FYB     ,                                                     &
    & ZXE     , ZYE     , ZXB     , ZYB     , ADZ 
!                             
    REAL   (KIND=R4)                                                                            ::&
    & FAC     , ZADXE   , ZADYE   , ZADXB   , ZADYB   ,                                           &
    & A       , B       , C
!
    IF (NTSD <= NTSHY) THEN
!
!$omp parallel do
!
    DO L=1,LM
        DO J=0,JM+1
            DO I=0,IM+1
                W(I,J,L) = 0.
            END DO
        END DO
    END DO
!
    RETURN
!
    END IF
!---------------------
! MAIN_LOOP: DO L=1,LM
!--------------------- 
    DO L=1,LM
          HM(:,:) =  HTM(0:IM+1, 0:JM+1, L)
        DPDE(:,:) = PDSL(0:IM+1, 0:JM+1)    * DETA(L)
        GDPD(:,:) = DPDE(:,:) * SQH(:,:)
!
        DO J=1,JM
            DO I=1,IM
                RGDP(I,J) = 1. / GDPD(I,J)
            END DO
        END DO
!      
        CALL BOCOHMPI(RGDP,1)
!    
        UT(:,:) = U(0:IM+1, 0:JM+1, L)
        VT(:,:) = V(0:IM+1, 0:JM+1, L)
        ZT(:,:) = Z(0:IM+1, 0:JM+1, L) 
!
        CALL AVRH(GDPD, AGDP, IM, JM)
!
        CALL CORNERHM2(AGDP, GDPD)
!
        DO IT=1,2 
!-------
! FLUXES
!-------
            DO J=0,JM
                DO I=0,IM
                     UTLD(I,J) =  Q11(I,J) *   UT(I,J) + Q12(I,J) * VT(I,J)
                     VTLD(I,J) =  Q12(I,J) *   UT(I,J) + Q22(I,J) * VT(I,J)
                      FXE(I,J) = AGDP(I,J) * UTLD(I,J)  
                      FYE(I,J) = AGDP(I,J) * VTLD(I,J)  
                END DO
            END DO
!   
            DO J=1,JM
                DO I=0,IM
                    FXB(I,J) = FXE(I,J) + FYE(I,J) + FXE(I,J-1) + FYE(I,J-1)
                END DO
            END DO
!
            DO J=0,JM
                DO I=1,IM
                    FYB(I,J) =-FXE(I,J) + FYE(I,J) - FXE(I-1,J) + FYE(I-1,J)
                END DO
            END DO
!-------
! HEIGHT
!-------
            DO J=0,JM
                DO I=0,IM
	            ZXE(I,J) = FXE(I,J) * (ZT (I+1,J  ) - ZT (I,J+1)) 
                    ZYE(I,J) = FYE(I,J) * (ZT (I+1,J+1) - ZT (I,J  )) 
                END DO
            END DO
!      
            DO J=1,JM
                DO I=0,IM
                    ZXB(I,J) = FXB(I,J) * (ZT(I+1,J) - ZT(I,J)) 
                END DO
            END DO
!      
            DO J=0,JM
                DO I=1,IM  
                    ZYB(I,J) = FYB(I,J) * (ZT(I,J+1) - ZT(I,J)) 
                END DO
            END DO
!      
            DO J=1,JM
                DO I=1,IM
                    FAC   = FADT * RGDP(I,J)
!
                    ZADXE = ZXE(I, J-1) + ZXE(I-1, J  )
                    ZADYE = ZYE(I, J  ) + ZYE(I-1, J-1)
                    ZADXB = ZXB(I, J  ) + ZXB(I-1, J  )
                    ZADYB = ZYB(I, J  ) + ZYB(I  , J-1)
!
                    ADZ(I,J) = FAC * HM(I,J) * (ZADXE + ZADYE + ZADXB + ZADYB)
                END DO 
            END DO
!-------------
! FIRST UPDATE 
!-------------
            IF (IT == 1) THEN
! 	  
                DO J=1,JM
                    DO I=1,IM
                        ZT (I,J) = ZT (I,J) + ADZ  (I,J) * 0.707 
	            END DO
                END DO
!
	        CALL BOCOHMPI(ZT,1) 
!
            END IF
!
        END DO               
!	   
	DO J=1,JM
            DO I=1,IM
                Z(I,J,L) = Z(I,J,L) + ADZ(I,J)  
            END DO
        END DO
!------------------ 
! END THE MAIN_LOOP 
! DO L=1,LM
!------------------ 
    END DO 
!
    CALL BOCOHMPI(Z,LM+1)
!
    RETURN
!
    END SUBROUTINE HADZ_GEF
