!OPTIONS XOPT(NOEVAL)
SUBROUTINE ACDIFOZ ( KIDIA,KFDIA,KLON,KTDIA,KLEV,&
 !-----------------------------------------------------------------------
 ! - INPUT  2D .
 & PAPRSF,PDELP,PFPLCL,PFPLSL,PFRSO,&
 & PKTROV,POZONE,PRDELP,PT,PXTROV,&
 ! - INPUT  1D .
 & PNEIJ,PGEMU,PIVEG,&
 ! - INPUT/OUTPUT 2D .
 & PDIFTO,&
 ! - LOCK ARGUMENTS .
 & CDLOCK)  

!**** *ACDIFOZ * - DIFFUSION VERTICALE TURBULENTE DU RAPPORT DE MELANGE
!                  MASSIQUE D'OZONE

!     Sujet.
!     ------
!     - ROUTINE DE CALCUL ACTIF .
!       CALCULS DE DIFFUSION VERTICALE TURBULENTE DU RAPPORT DE MELANGE  

!     - COMPUTATION OF VERTICAL TURBULENT DIFFUSION OF OZONE MASS MIXING
!       RATIO : VERTICAL TURBULENT FLUXES.

!**   Interface.
!     ----------
!        *CALL* *ACDIFOZ*

!-----------------------------------------------------------------------
! WARNING: THE ENGLISH VERSION OF VARIABLES' NAMES IS TO BE READ IN THE
!          "APLPAR" CODE.
!-----------------------------------------------------------------------

! -   ARGUMENTS D'ENTREE.
!     -------------------

! - NOM DES PARAMETRES DE DIMENSIONNEMENT DE LA PHYSIQUE.

! KIDIA      : INDICE DE DEPART DES BOUCLES VECTORISEES SUR L'HORIZONT..
! KFDIA      : INDICE DE FIN DES BOUCLES VECTORISEES SUR L'HORIZONTALE.
! KLON       : DIMENSION HORIZONTALE DES TABLEAUX.
! KTDIA      : INDICE DE DEPART DES BOUCLES VERTICALES (1 EN GENERAL).
! KLEV       : DIMENSION VERTICALE DES TABLEAUX "FULL LEVEL".

! - NOM DES VARIABLES DE LA PHYSIQUE (PAR ORDRE ALPHABETIQUE DANS CHAQUE
!   CATEGORIE).

! - 2D (0:KLEV) .

! PFPLCL     : PRECIPITATIONS CONVECTIVES SOUS FORME LIQUIDE.
! PFPLSL     : PRECIPITATIONS STRATIFORMES SOUS FORME LIQUIDE.
! PFRSO      : FLUX DE RAYONNEMENT SOLAIRE.
! PKTROV     : COEFFICIENT D'ECHANGE VERTICAL DE T  EN KG/(M*M*S).
! PXTROV     : MULTIPLICATEUR "ANTI-FIBRILLATION" DE PKTROV.

! - 2D (1:KLEV) .

! PAPRSF     : PRESSION AUX NIVEAUX DES COUCHES.
! PDELP      : EPAISSEUR EN PRESSION DE LA COUCHE.
! POZONE     : RAPPORT DE MELANGE MASSIQUE D'OZONE.
! PRDELP     : INVERSE DE L'EPAISSEUR EN PRESSION DE LA COUCHE.
! PT         : TEMPERATURE.

! - 1D (GEOGRAPHIQUE) .
! PGEMU      : SINE OF LATITUDE ON THE REAL EARTH
! PIVEG      : TYPE DE VEGETATION.

! - 1D (DIAGNOSTIQUE) .
! PNEIJ      : PROPORTION DE SOL ENNEIGE.

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

! -   ARGUMENTS DE SORTIE.
!     --------------------

! - 2D (0:KLEV) .

! PDIFTO     : FLUX D'ENTREE + 
!            :   FLUX TURBULENT DU RAPPORT DE MELANGE D'OZONE 

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

! -   ARGUMENTS IMPLICITES.
!     ---------------------

! COMMON/YOMPHY /
! COMMON/YOMCST /
! COMMON/YOMPHY2/
! COMMON/YOMRIP/
! COMMON/YOMVDOZ/

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

!     Externes.
!     ---------

!     Methode.
!     --------

!     Auteur.
!     -------
!        95-11, P. Mercier.

!     Modifications.
!     --------------
!        M.Hamrud      01-Oct-2003 CY28 Cleaning

!        97-08, PZx variables > Zx, introduce CDLOCK - J.M. Piriou.

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

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

USE YOMCST   , ONLY : RDAY     ,RG       ,RD
USE YOMPHY2  , ONLY : TSPHY
USE YOMRIP   , ONLY : NINDAT   ,RTIMTR
USE YOMVDOZ  , ONLY : VDHJS    ,VDHJH    ,VDHNS    ,VDHNH    ,&
 & VDPJS    ,VDPJH    ,VDPNS    ,VDPNH    ,VDEJS    ,&
 & VDEJH    ,VDENS    ,VDENH    ,VDAJS    ,VDAJH    ,&
 & VDANS    ,VDANH    ,VDNJS    ,VDNJH    ,VDNNS    ,&
 & VDNNH    ,VOZNJ    ,VOZHS    ,LRDIFOZ  ,LRDEPOZ  

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)    :: KTDIA 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAPRSF(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDELP(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PFPLCL(KLON,0:KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PFPLSL(KLON,0:KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PFRSO(KLON,0:KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PKTROV(KLON,0:KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: POZONE(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRDELP(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PT(KLON,KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PXTROV(KLON,0:KLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PNEIJ(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEMU(KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PIVEG(KLON) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PDIFTO(KLON,0:KLEV) 
CHARACTER(LEN=7)  ,INTENT(IN)    :: CDLOCK 
!*
!     ------------------------------------------------------------------

REAL(KIND=JPRB) :: ZIPOI(KLON,KLEV),ZN1(KLON,KLEV),ZPOID(KLON,KLEV)&
 & ,ZSUB1(KLON,KLEV),ZXTRO(KLON,0:KLEV)  
REAL(KIND=JPRB) :: ZGDIFO(99,2,2,5),ZVD(KLON)

INTEGER(KIND=JPIM) :: IA, IHS, IJS, INS, ISAISON, ISAISONHN, ISAISONHS,&
 & JLEV, JLON, JVEG  

REAL(KIND=JPRB) :: ZELIM, ZFLEVN, ZGDT, ZGDTI, ZMUL, ZPLTOT,&
 & ZRTIME0, ZRTIME1, ZRTIME2, ZRTIME3, ZRTIME4, &
 & ZRTIME5, ZRTIMTR, ZSEUILHS, ZSEUILNJ  
REAL(KIND=JPRB) :: ZHOOK_HANDLE

#include "abor1.intfb.h"

#include "fcttim.h"

!     CHECK RELIABILITY OF INPUT ARGUMENTS.

IF (LHOOK) CALL DR_HOOK('ACDIFOZ',0,ZHOOK_HANDLE)
IF(CDLOCK /= 'ACDIFOZ') CALL ABOR1('BAD NUMBER OF ARGUMENTS!')

!     ------------------------------------------------------------------
!     I - CALCUL DES PARAMETRES DERIVES ET CONSTANTE DE SECURITE

!          COMPUTATION OF DERIVED PARAMETERS AND SECURITY CONSTANT 

IF(.NOT.LRDIFOZ) THEN
  IF (LHOOK) CALL DR_HOOK('ACDIFOZ',1,ZHOOK_HANDLE)
  RETURN
ENDIF
ZGDT=RG*TSPHY
ZGDTI=1.0_JPRB/ZGDT

!     ------------------------------------------------------------------
!     II - CALCULS PRELIMINAIRES DE CARACTERISTIQUE DES NIVEAUX
!     DANS L'UNITE DES COEFFICIENTS D'ECHANGE NORMALISES (KG/M**2/S)
!     POUR "POID" ET SON INVERSE POUR "IPOI".

!          PRELIMINARY COMPUTATIONS OF LAYERS' CHARACTERISTICS
!     IN THE UNITS OF THE NORMALIZED EXCHANGE COEFFICIENTS (KG/M**2/S)
!     FOR "POID" AND ITS INVERSE FOR "IPOI".

! - TEMPORAIRE(S) 2D (1:KLEV) .

! ZPOID     : DP/(RG*DT) POUR UNE COUCHE ET UN PAS DE TEMPS DONNES.
!            : DP/(RG*DT) FOR A GIVEN LAYER AND A GIVEN TIME STEP.
! ZIPOI     : INVERSE DE ZPOID.
!            : INVERSE OF ZPOID.

DO JLEV=KTDIA,KLEV
  DO JLON=KIDIA,KFDIA
    ZPOID(JLON,JLEV)=PDELP(JLON,JLEV)*ZGDTI
    ZIPOI(JLON,JLEV)=PRDELP(JLON,JLEV)*ZGDT
  ENDDO
ENDDO

!*
!     ------------------------------------------------------------------
!     INTRODUCTION DES CALCULS POUR LE RAPPORT DE MELANGE D'OZONE :

!     III - CALCULS POUR LE RAPPORT DE MELANGE MASSIQUE D'OZONE
!      : PARTIE ELIMINATION.
!     DANS TOUTE LA SUITE ON UTILISERA ZELIM POUR DESIGNER L'ELEMENT
!     SUBDIAGONAL PAR LEQUEL IL FAUT MULTIPLIER LA LIGNE PRECEDENTE POUR
!     L'ELIMINER PAR SOUSTRACTION ET ZMUL POUR DESIGNER LE FACTEUR
!     MULTIPLICATIF DESTINE A METTRE LA DIAGONALE PRINCIPALE A "1".
!     ZSUB1 CONTIENDRA LES COEFFICIENTS SURDIAGONAUX MODIFIES QUI
!     SERONT UTILISES LORS DE LA SUBSTITUTION POUR RO3 ET ZN1
!     CONTIENDRA LES SECONDS MEMBRES DESTINES A DEVENIR LES VALEURS 
!     FINALES POUR RO3. 
!     LE CAS DE L'OZONE EST TRAITE COMME LA QUANTITE DE MOUVEMENT
!     MAIS EN PRENANT POUR COEFFICIENT D'ECHANGE VERTICAL CELUI DE Q

!     INTRODUCTION OF OZONE MIXING RATIO COMPUTATION :

!         COMPUTATIONS FOR OZONE MASS MIXING RATIO/ ELIMINATION PART.
!     IN ALL THE FOLLOWING ONE WILL USE ZELIM TO NAME THE SUBDIAGONAL
!     ELEMENT BY WHICH ONE SHOULD MULTIPLY THE PRECEEDING LINE TO 
!     ELIMINATE IT BY SUBSTRACTION AND ZMUL TO NAME THE MULTIPLYING
!     FACTOR TO PUT THE MAIN DIAGONAL TO "1". 
!     ZSUB1 WILL CONTAIN THE MODIFIED SUPERDIAGONAL COEFFICIENTS THAT
!     WILL BE USED IN THE SUBSTITUTION FOR RO3 AND ZN1 WILL CONTAIN
!     THE RIGHT HAND SIDES DUE TO BECOME THE FINAL VALUES FOR RO3.  
!     THE CASE OF OZONE IS TREATED AS MOMENTUM BUT WE TAKE THE Q'S  
!     VERTICAL EXCHANGE COEFFICIENT.

! - TEMPORAIRE(S) 2D (1:KLEV) .

! ZSUB1     : TABLEAU DE COEFFICIENTS POUR LA SUBSTITUTION EN RO3.
!            : ARRAY OF COEFFICIENTS FOR THE RO3 SUBSTITUTION.
! ZN1       : TABLEAU DE MEMBRES DE DROITE POUR RO3.
!            : ARRAY OF RIGHT HAND SIDES FOR RO3.
! ZXTRO     : PKTROV MODIFIE POUR ATTENUER LES FIBRILLATIONS
!            : PKTROV MODIFIED TO ATTENUATE FIBRILLATIONS

!   AMPLIFICATION EVENTUELLE "ANTI-FIBRILLATION" DES COEFFICIENTS
!   D'ECHANGE

DO JLEV=KTDIA,KLEV-1
  DO JLON=KIDIA,KFDIA
    ZXTRO(JLON,JLEV)=PKTROV(JLON,JLEV)*PXTROV(JLON,JLEV)
  ENDDO
ENDDO

!     ELIMINATION AU SOMMET.
!     ELIMINATION AT THE TOP.

DO JLON=KIDIA,KFDIA
  ZMUL=1.0_JPRB/(1.0_JPRB+ZXTRO(JLON,KTDIA)*ZIPOI(JLON,KTDIA))
  ZSUB1(JLON,KTDIA)=ZMUL*ZXTRO(JLON,KTDIA)*ZIPOI(JLON,KTDIA)
  ZN1(JLON,KTDIA)=ZMUL*POZONE(JLON,KTDIA)
ENDDO

!     ELIMINATION POUR UNE COUCHE STANDARD.
!     ELIMINATION FOR A STANDART LEVEL.

DO JLEV=KTDIA+1,KLEV-1
  DO JLON=KIDIA,KFDIA
    ZELIM=ZXTRO(JLON,JLEV-1)*ZIPOI(JLON,JLEV)
    ZMUL=1.0_JPRB/(1.0_JPRB+ZELIM*(1.0_JPRB-ZSUB1(JLON,JLEV-1))+ZXTRO(JLON,JLEV)&
     & *ZIPOI(JLON,JLEV))  
    ZSUB1(JLON,JLEV)=ZMUL*ZXTRO(JLON,JLEV)*ZIPOI(JLON,JLEV)
    ZN1(JLON,JLEV)=ZMUL*(POZONE(JLON,JLEV)+ZELIM*ZN1(JLON,JLEV-1))
  ENDDO
ENDDO

!*
!     ------------------------------------------------------------------

! IV) DETERMINATION DES VALEURS DE VITESSES DE DEPOT

!   1) DETERMINATION DE LA SAISON

!     1a) DETERMINATION DE LA SAISON DE L'HEMISPHERE NORD: ISAISONHN

ZRTIMTR=RTIMTR
IA=NCCAA(NINDAT)
ZRTIME0=RTIME(IA  , 1,  1, 0, RDAY)
ZRTIME1=RTIME(IA  , 3, 21, 0, RDAY)
ZRTIME2=RTIME(IA  , 6, 21, 0, RDAY)
ZRTIME3=RTIME(IA  , 9, 21, 0, RDAY)
ZRTIME4=RTIME(IA  ,12, 21, 0, RDAY)
ZRTIME5=RTIME(IA+1, 3, 21, 0, RDAY)
ISAISONHN=1
IF     ((ZRTIMTR >= ZRTIME0) .AND. (ZRTIMTR < ZRTIME1)) THEN
  ISAISONHN=1
ELSEIF ((ZRTIMTR >= ZRTIME1) .AND. (ZRTIMTR < ZRTIME2)) THEN
  ISAISONHN=2
ELSEIF ((ZRTIMTR >= ZRTIME2) .AND. (ZRTIMTR < ZRTIME3)) THEN
  ISAISONHN=3
ELSEIF ((ZRTIMTR >= ZRTIME3) .AND. (ZRTIMTR < ZRTIME4)) THEN
  ISAISONHN=4
ELSEIF ((ZRTIMTR >= ZRTIME4) .AND. (ZRTIMTR < ZRTIME5)) THEN
  ISAISONHN=1
ELSE
  CALL ABOR1('ACDIFOZ : WRONG SEASON')
ENDIF

!     1b) DETERMINATION DE LA SAISON DE L'HEMISPHERE SUD:  ISAISONHS

ISAISONHS=1+MOD(ISAISONHN+1,4)

!   2) DETERMINATION DE ZVD
!C
!       2.1) CONCATENATION DES TABLEAUX DE VITESSES DE DEPOT
DO JVEG=1,99
  ZGDIFO(JVEG,1,1,1)=VDHJS(JVEG)
  ZGDIFO(JVEG,1,2,1)=VDHJH(JVEG)
  ZGDIFO(JVEG,2,1,1)=VDHNS(JVEG)
  ZGDIFO(JVEG,2,2,1)=VDHNH(JVEG)

  ZGDIFO(JVEG,1,1,2)=VDPJS(JVEG)
  ZGDIFO(JVEG,1,2,2)=VDPJH(JVEG)
  ZGDIFO(JVEG,2,1,2)=VDPNS(JVEG)
  ZGDIFO(JVEG,2,2,2)=VDPNH(JVEG)

  ZGDIFO(JVEG,1,1,3)=VDEJS(JVEG)
  ZGDIFO(JVEG,1,2,3)=VDEJH(JVEG)
  ZGDIFO(JVEG,2,1,3)=VDENS(JVEG)
  ZGDIFO(JVEG,2,2,3)=VDENH(JVEG)

  ZGDIFO(JVEG,1,1,4)=VDAJS(JVEG)
  ZGDIFO(JVEG,1,2,4)=VDAJH(JVEG)
  ZGDIFO(JVEG,2,1,4)=VDANS(JVEG)
  ZGDIFO(JVEG,2,2,4)=VDANH(JVEG)

  ZGDIFO(JVEG,1,1,5)=VDNJS(JVEG)
  ZGDIFO(JVEG,1,2,5)=VDNJH(JVEG)
  ZGDIFO(JVEG,2,1,5)=VDNNS(JVEG)
  ZGDIFO(JVEG,2,2,5)=VDNNH(JVEG)
ENDDO

!      2.2) DIFFERENCIATION DES CAS JOUR,NUIT,SEC,HUMIDE,..

!     DIFFERENCIATION JOUR/NUIT A L'AIDE DU FLUX DE RAYONNEMENT
!     SOLAIRE
!     SEUIL POUR DIFFERENCIER LE JOUR ET LA NUIT EN W/M2
ZSEUILNJ=VOZNJ

!     DIFFERENCIATION SEC/HUMIDE A L'AIDE DE LA PLUIE TOTALE
!     SEUIL POUR DIFFERENCIER LE SEC ET L'HUMIDE EN MM/JOUR
ZSEUILHS=VOZHS

!     CAS JOUR        IJS=1, CAS NUIT       IJS=2
!     CAS HUMIDE      IHS=2, CAS SEC        IHS=1
!     CAS H. NORD     INS=1, CAS H. SUD     INS=0

DO JLON=KIDIA,KFDIA
  ZPLTOT=PFPLCL(JLON,KLEV)+PFPLSL(JLON,KLEV)
  IJS=2-INT(MIN(MAX(PFRSO(JLON,KLEV)/ZSEUILNJ,0.0_JPRB),1.0_JPRB))
  IHS=INT(MIN(MAX(ZPLTOT/ZSEUILHS,0.0_JPRB),1.0_JPRB))+1
  INS=INT(MIN(MAX(1.0_JPRB+PGEMU(JLON) ,0.0_JPRB),1.0_JPRB))
  ISAISON=ISAISONHN*INS+ISAISONHS*(1-INS)
  ZVD(JLON)=ZGDIFO(NINT(PIVEG(JLON)),IJS,IHS,ISAISON)&
   & *(1.0_JPRB-PNEIJ(JLON))&
   & +PNEIJ(JLON)*ZGDIFO(NINT(PIVEG(JLON)),IJS,IHS,5)  
ENDDO

!*
!     ------------------------------------------------------------------
!     V - CALCULS POUR LE RAPPORT DE MELANGE D'OZONE : CONDITION DE 
!     SURFACE PUIS SUBSTITUTION AVEC CALCUL DES FLUX A TOUS LES NIVEAUX.

!         COMPUTATION FOR OZONE MIXING RATIO : SURFACE CONDITION THEN 
!     SUBSTITUTION WITH 'FLUXES' COMPUTATION AT ALL LEVELS.

!     CALCULS EN SURFACE.
!     SURFACE CALCULATIONS.

!     ON IMPOSE QUE LE FLUX DE DIFFUSION TURBULENTE D'OZONE EST NUL
!     EN SURFACE (AU NIVEAU N) DANS LE CAS DE LA DIFFUSION SIMPLE
!     OU CONSTANT EN TENANT COMPTE DE LA VITESSE DE DEPOT
!     (VIA UNE CONSTANTE LOCALE ZFLEVN) 
!     CE QUI IMPLIQUE UNE MODIFICATION DE LA DERNIERE LIGNE
!     DE LA MATRICE PAR RAPPORT AU CALCUL DE U ET V

!     CALCUL DU FLUX AU SOL "ZFLEVN" AVEC LA VITESSE DE DEPOT "ZVD"
!     LE TERME "-ZIPOI(JLON,KLEV)*ZFLEVN" A ETE AJOUTE PAR RAPPORT 
!     AU CAS DE LA DIFFUSION TURBULENTE DE LA QUANTITE DE MOUVEMENT

IF (LRDEPOZ) THEN
  DO JLON=KIDIA,KFDIA
    ZELIM=ZXTRO(JLON,KLEV-1)*ZIPOI(JLON,KLEV)
    ZFLEVN=ZVD(JLON)*POZONE(JLON,KLEV)*(PAPRSF(JLON,KLEV)/(RD*PT(JLON,KLEV)))
    PDIFTO(JLON,KLEV)=PDIFTO(JLON,KLEV)+ZFLEVN
    ZMUL=1.0_JPRB/(1.0_JPRB+ZELIM*(1.0_JPRB-ZSUB1(JLON,KLEV-1)))
    ZN1(JLON,KLEV)=ZMUL*(POZONE(JLON,KLEV)+ZELIM*ZN1(JLON,KLEV-1)-&
     & ZIPOI(JLON,KLEV)*ZFLEVN)  
  ENDDO
ELSE
  DO JLON=KIDIA,KFDIA
    ZELIM=ZXTRO(JLON,KLEV-1)*ZIPOI(JLON,KLEV)
    ZMUL=1.0_JPRB/(1.0_JPRB+ZELIM*(1.0_JPRB-ZSUB1(JLON,KLEV-1)))
    ZN1(JLON,KLEV)=ZMUL*(POZONE(JLON,KLEV)+ZELIM*ZN1(JLON,KLEV-1))
  ENDDO
ENDIF

!     SUBSTITUTION POUR UNE COUCHE STANDARD ET AU SOMMET.
!     BACK-SUBSTITUTION FOR A STANDART LAYER AND AT THE TOP.

DO JLEV=KLEV-1,KTDIA,-1
  DO JLON=KIDIA,KFDIA
    ZN1(JLON,JLEV)=ZN1(JLON,JLEV)+ZSUB1(JLON,JLEV)*ZN1(JLON,JLEV+1)
    PDIFTO(JLON,JLEV)=PDIFTO(JLON,JLEV)+&
     & PKTROV(JLON,JLEV)*(ZN1(JLON,JLEV)-ZN1(JLON,JLEV+1))  
  ENDDO
ENDDO

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