SUBROUTINE M7_NEGAT &
 & ( KIDIA  , KFDIA , KLON, KLEV, KTRAC, &
 &   PTSPHY , &
 &   PCAERO , PTAERO, PAPHP1, &
 &   PFAERNG )  

!**** *M7_NEGAT* - AVOIDS NEGATIVE VALUES FOR AEROSOL QUANTITIES.

!     JJMorcrette  ECMWF 2005/08/16
!     from QNEGAT by B.RITTER     E.C.M.W.F.     29/04/83.

!     PURPOSE.
!     --------

!          THIS ROUTINE RESETS TO A VERY SMALL MINIMUM VALUE ALL THE
!     AEROSOL MIXING RATIOS SMALLER THAN THIS (IN PARTICULAR ALL THE
!     NEGATIVE VALUES THAT MIGHT HAVE APPEARED IN THE COURSE OF THE
!     TIME STEP).

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

!          *M7_NEGAT* IS CALLED FROM *M7_INTERFACE*.
!          THE ROUTINE TAKES ITS INPUT FROM THE LONG-TERM STORAGE: PCAERO
!     AT T+1 AND P ON LEVEL BOUNDARIES AT T+1. IT RETURNS ITS OUTPUT
!     TO THE SAME SPACE: CORRECTED PTAERO TENDENCIES.
!     THE TEMPERATURE WILL NOT BE ADJUSTED AND SURFACE
!     FLUXES (OF AEROSOLS) WILL NOT BE MODIFIED.

!     METHOD.
!     -------

!          FOR EACH LAYER (FROM TOP TO BOTTOM) THE AEROSOL CONCENTRATION 
!     IS COMPARED WITH ITS CRITICAL VALUE. IF NECESSARY THE ADJUSTMENT IS
!     PERFORMED AND THE NECESSARY WATER IS TAKEN FROM THE LAYER UNDERNEATH.

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

!          NONE.

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

!          SEE RELEVANT PART OF THE DOCUMENTATION.

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMCST   , ONLY : RG
USE YOEAERATM, ONLY : REPSCAER

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)  :: KTRAC 

REAL(KIND=JPRB)   ,INTENT(IN)    :: PTSPHY 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCAERO(KLON,KLEV,KTRAC) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTAERO(KLON,KLEV,KTRAC) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAPHP1(KLON,KLEV+1) 

REAL(KIND=JPRB)   ,INTENT(OUT)   :: PFAERNG(KLON,KLEV+1,KTRAC) 

!*         flux outputs

! PFAERNG  : PSEUDO-FLUX OF AEROSOLS TO CORRECT FOR NEGATIVE AEROSOL CONCENTRATION


REAL(KIND=JPRB) :: ZDP(KLON), ZDPO(KLON), ZFAERNG(KLON,KLEV+1)
REAL(KIND=JPRB) :: ZAEROLD(KLON,KLEV), ZCAERO(KLON,KLEV), ZTAERO(KLON,KLEV)

INTEGER(KIND=JPIM) :: JK, JL, JT

REAL(KIND=JPRB) :: ZCONS1, ZDAER, ZGDPH, ZTMST
REAL(KIND=JPRB) :: ZHOOK_HANDLE

!-------------------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('M7_NEGAT',0,ZHOOK_HANDLE)

!*    COMPUTATIONAL CONSTANTS.
!     ------------- ----------

ZTMST=PTSPHY

ZCONS1=1.0_JPRB/ZTMST
!***

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

!*         2.     ADJUSTMENT FOR ALL LAYERS.
!                 ---------- --- --- -------

DO JT=1,KTRAC

!*         2.1      SAVE INITIAL TENDENCY VALUES

  DO JK=1,KLEV
    DO JL=KIDIA,KFDIA
      ZAEROLD(JL,JK)=PTAERO(JL,JK,JT)
      ZCAERO(JL,JK) =PCAERO(JL,JK,JT)
      ZTAERO(JL,JK) =PTAERO(JL,JK,JT)
    ENDDO
   ENDDO

!*         2.2      PRELIMINARY COMPUTATIONS FOR THE TOP LAYER.

  DO JL=KIDIA,KFDIA
    ZDP(JL)=PAPHP1(JL,2)-PAPHP1(JL,1)
  ENDDO

!*         2.2     VERTICAL LOOP EXCLUDING THE BOTTOM LAYER.

  DO JK=1,KLEV-1
    DO JL=KIDIA,KFDIA
      ZDPO(JL)=ZDP(JL)
    ENDDO
    DO JL=KIDIA,KFDIA
      ZDP(JL)=PAPHP1(JL,JK+2)-PAPHP1(JL,JK+1)
      ZDAER=ZCONS1*MAX(0.0_JPRB,REPSCAER-(ZCAERO(JL,JK)+ZTMST*ZTAERO(JL,JK)))
      ZTAERO(JL,JK)=ZTAERO(JL,JK)+ZDAER
      ZDAER=ZDAER*ZDPO(JL)/ZDP(JL)
      ZTAERO(JL,JK+1)=ZTAERO(JL,JK+1)-ZDAER
    ENDDO
  ENDDO

!*         2.3      BOTTOM LAYER.

  DO JL=KIDIA,KFDIA
    ZDAER=ZCONS1*MAX(0.0_JPRB,REPSCAER-(ZCAERO(JL,KLEV)+ZTMST*ZTAERO(JL,KLEV)))
    ZTAERO(JL,KLEV)=ZTAERO(JL,KLEV)+ZDAER
  ENDDO

!*         3.       FLUX COMPUTATIONS

  DO JL=KIDIA,KFDIA
    ZFAERNG(JL,1)=0.0_JPRB
  ENDDO
  DO JK=1,KLEV
    DO JL=KIDIA,KFDIA
      ZGDPH = -RG  /(PAPHP1(JL,JK+1)-PAPHP1(JL,JK))
      ZFAERNG(JL,JK+1)=(ZTAERO(JL,JK)-ZAEROLD(JL,JK))/ZGDPH + ZFAERNG(JL,JK)
    ENDDO
  ENDDO

!*         4.	    BACK TO PROPER LOCATION

  DO JK=1,KLEV
    DO JL=KIDIA,KIDIA
      PTAERO(JL,JK,JT)=ZTAERO(JL,JK)
      PFAERNG(JL,JK,JT)=ZFAERNG(JL,JK)
    ENDDO
  ENDDO
  DO JL=KIDIA,KFDIA
    PFAERNG(JL,KLEV+1,JT)=ZFAERNG(JL,KLEV+1)
  ENDDO

ENDDO
!-------------------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('M7_NEGAT',1,ZHOOK_HANDLE)
END SUBROUTINE M7_NEGAT
