SUBROUTINE LW &
 & ( KIDIA, KFDIA , KLON  , KLEV  , KMODE, KTOPC, KTRAER,&
 & PCCO2, PCLFR , PCLDLD, PCLDLU,&
 & PDP  , PDT0  , PEMIS , PEMIW,&
 & PPMB , PQOF  , PTL,&
 & PAER , PTAVE , PVIEW , PWV,&
 & PEMIT, PFLUX , PFLUC &
 & )  

!**** *LW*   - ORGANIZES THE LONGWAVE CALCULATIONS

!     PURPOSE.
!     --------
!           COMPUTES LONGWAVE FLUXES 

!**   INTERFACE.
!     ----------

!        *LW* IS CALLED FROM *RADLSW*

!        EXPLICIT ARGUMENTS :
!        --------------------
! PAER   : (KLON,6,KLEV)     ; OPTICAL THICKNESS OF THE AEROSOLS
! PCCO2  :                   ; CONCENTRATION IN CO2 (PA/PA)
! PCLFR  : (KLON,KLEV)       ; CLOUD FRACTIONAL COVER
! PCLDLD : (KLON,KLEV)       ; DOWNWARD EFFECTIVE CLOUD FRACTION
! PCLDLU : (KLON,KLEV)       ; UPWARD EFFECTIVE CLOUD FRACTION
! PDP    : (KLON,KLEV)       ; LAYER PRESSURE THICKNESS
! PDT0   : (KLON)            ; SURFACE TEMPERATURE DISCONTINUITY  
! PEMIS  : (KLON)            ; SURFACE LW EMISSIVITY
! PEMIW  : (KLON)            ; SURFACE LW WINDOW EMISSIVITY
! PPMB   : (KLON,KLEV+1)     ; HALF LEVEL PRESSURE
! PQOF   : (KLON,KLEV)       ; CONCENTRATION IN OZONE (PA/PA)
! PTAVE  : (KLON,KLEV)       ; TEMPERATURE
! PTL    : (KLON,KLEV+1)     ; HALF LEVEL TEMPERATURE
! PVIEW  : (KLON)            ; COSECANT OF VIEWING ANGLE
! PWV    : (KLON,KLEV)       ; SPECIFIC HUMIDITY  (PA/PA)
!     ==== OUTPUTS ===
! PEMIT(KLON)                ; SURFACE TOTAL LW EMISSIVITY
! PFLUX(KLON,2,KLEV)         ; RADIATIVE FLUXES :
!                     1  ==>  UPWARD   FLUX TOTAL
!                     2  ==>  DOWNWARD FLUX TOTAL
! PFLUC(KLON,2,KLEV)         ; RADIATIVE FLUXES CLEAR SKY:
!                     1  ==>  UPWARD   FLUX TOTAL
!                     2  ==>  DOWNWARD FLUX TOTAL

!        IMPLICIT ARGUMENTS :   NONE
!        --------------------

!     METHOD.
!     -------

!          1. COMPUTES THE PRESSURE AND TEMPERATURE WEIGHTED AMOUNTS OF
!     ABSORBERS.
!          2. COMPUTES THE PLANCK FUNCTIONS ON THE INTERFACES AND THE
!     GRADIENT OF PLANCK FUNCTIONS IN THE LAYERS.
!          3. PERFORMS THE VERTICAL INTEGRATION DISTINGUISHING THE CON-
!     TRIBUTIONS OF THE ADJACENT AND DISTANT LAYERS AND THOSE FROM THE
!     BOUNDARIES.
!          4. COMPUTES THE CLEAR-SKY DOWNWARD AND UPWARD EMISSIVITIES.
!          5. INTRODUCES THE EFFECTS OF THE CLOUDS ON THE FLUXES.

!     EXTERNALS.
!     ----------

!          *LWU*, *LWBV*, *LWC*

!     REFERENCE.
!     ----------

!        SEE RADIATION'S PART OF THE MODEL'S DOCUMENTATION AND
!        ECMWF RESEARCH DEPARTMENT DOCUMENTATION OF THE IFS

!     AUTHOR.
!     -------
!        JEAN-JACQUES MORCRETTE  *ECMWF*

!     MODIFICATIONS.
!     --------------
!        ORIGINAL : 89-07-14
!        99-05-25   JJMorcrette    Revised aerosols
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        M. Janiskova  22-Nov-2006 Added KTOPC and PCLFR

!-----------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOELW    , ONLY : NUA, NSIL
USE YOEPHLI   ,ONLY : LPHYLIN
USE YOPHNC    ,ONLY : LH2OCO2, LWLOPT

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KLON 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KIDIA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFDIA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KMODE 
INTEGER(KIND=JPIM),INTENT(IN)    :: KTOPC
INTEGER(KIND=JPIM),INTENT(IN)    :: KTRAER
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCCO2 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLFR(KLON,KLEV)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLDLD(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCLDLU(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDP(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDT0(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PEMIS(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PEMIW(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PPMB(KLON,KLEV+1) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PQOF(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PTL(KLON,KLEV+1) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAER(KLON,6,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PTAVE(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVIEW(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PWV(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PEMIT(KLON) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PFLUX(KLON,2,KLEV+1) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PFLUC(KLON,2,KLEV+1) 
!-----------------------------------------------------------------------

!*       0.1   ARGUMENTS
!              ---------

!-------------------------------------------------------------------------

!              ------------
REAL(KIND=JPRB) :: ZABCU(KLON,NUA,3*KLEV+1)&
 & ,  ZBINT(KLON,KLEV+1)        , ZBSUI(KLON)&
 & ,  ZCNTRB(KLON,KLEV+1,KLEV+1)  

!for adjoint computation

REAL(KIND=JPRB) :: ZGA(KLON,8,2,KLEV)  , ZGB(KLON,8,2,KLEV)
REAL(KIND=JPRB) :: ZGASUR(KLON,8,2)    , ZGBSUR(KLON,8,2)
REAL(KIND=JPRB) :: ZGATOP(KLON,8,2)    , ZGBTOP(KLON,8,2)
REAL(KIND=JPRB) :: ZB(KLON,6,KLEV+1), ZBSUR(KLON,6), ZBTOP(KLON,6)
REAL(KIND=JPRB) :: ZDBSL(KLON,6,KLEV*2)

REAL(KIND=JPRB) :: ZADJD(KLON,KLEV+1), ZADJU(KLON,KLEV+1)
REAL(KIND=JPRB) :: ZDBDT(KLON,NSIL,KLEV), ZDWFSU(KLON,NSIL)
REAL(KIND=JPRB) :: ZDISD(KLON,KLEV+1), ZDISU(KLON,KLEV+1)

REAL(KIND=JPRB),ALLOCATABLE :: ZCOND(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZTTPA(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZTTPB(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZTTA(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZTTB(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZZZA(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZZZB(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXNA(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXNB(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXDIVA(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXDIVB(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZZZA1(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZZZB1(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXNA1(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXNB1(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXDIVA1(:,:,:)
REAL(KIND=JPRB),ALLOCATABLE :: ZXDIVB1(:,:,:)
REAL(KIND=JPRB) :: ZTTPA1(KLON,KLEV+1)
REAL(KIND=JPRB) :: ZTTPB1(KLON,KLEV+1)

REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "lwbv.intfb.h"
#include "lwc.intfb.h"
#include "lwu.intfb.h"

!     ------------------------------------------------------------------

IF (LHOOK) CALL DR_HOOK('LW',0,ZHOOK_HANDLE)

!*         1.    INITIALIZATION
!                --------------

!100  CONTINUE

IF (LPHYLIN .AND. LH2OCO2) THEN
  ALLOCATE(ZCOND(KLON,KLEV+1,KLEV+1))
  ALLOCATE(ZTTPA(KLON,KLEV+1,KLEV+1))
  ALLOCATE(ZTTPB(KLON,KLEV+1,KLEV+1))
  ALLOCATE(ZTTA(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZTTB(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZZZA(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZZZB(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZXNA(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZXNB(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZXDIVA(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZXDIVB(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZZZA1(KLON,KTRAER,KLEV+1))
  ALLOCATE(ZZZB1(KLON,KTRAER,KLEV+1))
  ALLOCATE(ZXNA1(KLON,KTRAER,KLEV+1))
  ALLOCATE(ZXNB1(KLON,KTRAER,KLEV+1))
  ALLOCATE(ZXDIVA1(KLON,KTRAER,KLEV+1))
  ALLOCATE(ZXDIVB1(KLON,KTRAER,KLEV+1))
ELSEIF (LPHYLIN .AND. LWLOPT) THEN
  ALLOCATE(ZTTA(KLON,KTRAER*KLEV,KLEV+1))
  ALLOCATE(ZTTB(KLON,KTRAER*KLEV,KLEV+1))
ENDIF

!     ------------------------------------------------------------------

!*         1.1   COMPUTES ABSORBER AMOUNTS
!                -------------------------

CALL LWU &
 & (  KIDIA, KFDIA, KLON, KLEV,&
 & PAER , PCCO2, PDP , PPMB, PQOF , PTAVE, PVIEW, PWV,&
 & ZABCU &
 & )  

!     ------------------------------------------------------------------

!*         2.    COMPUTES PLANCK FUNCTIONS
!                -------------------------
!                PERFORMS THE VERTICAL INTEGRATION
!                ---------------------------------

CALL LWBV &
 & ( KIDIA, KFDIA, KLON , KLEV  , KMODE, KTRAER, &
 & PDT0 , PEMIS, PEMIW, PTL   , PTAVE,&
 & PEMIT, PFLUC,&
 & ZABCU, ZBINT, ZBSUI, ZCNTRB, &
! for adjoint computation
 & ZB, ZBSUR, ZBTOP, ZDBSL, &
 & ZGA, ZGB, ZGASUR, ZGBSUR, ZGATOP, ZGBTOP, &
 & ZADJD, ZADJU, ZDBDT, ZDISD, ZDISU, ZDWFSU, &
 & ZCOND  , ZTTPA  , ZTTPB , ZTTA , ZTTB  ,&
 & ZZZA   , ZZZB   , ZXNA  , ZXNB , ZXDIVA,&
 & ZXDIVB , ZZZA1  , ZZZB1 , ZXNA1, ZXNB1 ,&
 & ZXDIVA1, ZXDIVB1, ZTTPA1, ZTTPB1 &
 & )  

!     ------------------------------------------------------------------

!*         4.    INTRODUCES THE EFFECTS OF CLOUDS
!                --------------------------------

CALL LWC &
 & ( KIDIA , KFDIA, KLON  , KLEV, KTOPC,&
 & ZBINT , ZBSUI, PCLFR, PCLDLD, PCLDLU,&
 & ZCNTRB, PEMIT, PFLUC,&
 & PFLUX    &
 & )  

!     ------------------------------------------------------------------

IF (LPHYLIN .AND. LH2OCO2) THEN
  DEALLOCATE(ZCOND)
  DEALLOCATE(ZTTPA)
  DEALLOCATE(ZTTPB)
  DEALLOCATE(ZTTA)
  DEALLOCATE(ZTTB)
  DEALLOCATE(ZZZA)
  DEALLOCATE(ZZZB)
  DEALLOCATE(ZXNA)
  DEALLOCATE(ZXNB)
  DEALLOCATE(ZXDIVA)
  DEALLOCATE(ZXDIVB)
  DEALLOCATE(ZZZA1)
  DEALLOCATE(ZZZB1)
  DEALLOCATE(ZXNA1)
  DEALLOCATE(ZXNB1)
  DEALLOCATE(ZXDIVA1)
  DEALLOCATE(ZXDIVB1)
ELSEIF (LPHYLIN .AND. LWLOPT) THEN
  DEALLOCATE(ZTTA)
  DEALLOCATE(ZTTB)
ENDIF

IF (LHOOK) CALL DR_HOOK('LW',1,ZHOOK_HANDLE)
END SUBROUTINE LW
