diff --git a/src/common/turb/bl89.f90 b/src/common/turb/bl89.f90 new file mode 100644 index 0000000000000000000000000000000000000000..303d92d262407a571fbe894e1da0274d1626abf3 --- /dev/null +++ b/src/common/turb/bl89.f90 @@ -0,0 +1,335 @@ +! ######spl + SUBROUTINE BL89(KKA,KKU,KKL,PZZ,PDZZ,PTHVREF,PTHLM,KRR,PRM,PTKEM,PSHEAR,PLM) + USE PARKIND1, ONLY : JPRB + USE YOMHOOK , ONLY : LHOOK, DR_HOOK +! ######################################################### +! +!!**** *BL89* - +!! +!! PURPOSE +!! ------- +!! This routine computes the mixing length from Bougeault-Lacarrere 89 +!! formula. +!! +!!** METHOD +!! ------ +!! +!! EXTERNAL +!! -------- +!! +!! IMPLICIT ARGUMENTS +!! ------------------ +!! +!! +!! REFERENCE +!! --------- +!! +!! Book 2 +!! +!! AUTHOR +!! ------ +!! +!! J. Cuxart INM and Meteo-France +!! +!! MODIFICATIONS +!! ------------- +!! Original 27/04/97 (V. Masson) separation from turb.f90 +!! and optimization +!! 06/01/98 (V. Masson and P. Jabouille) optimization +!! 15/03/99 (V. Masson) new lup ldown averaging +!! 21/02/01 (P. Jabouille) improve vectorization +!! 2012-02 (Y. Seity) add possibility to run with +!! reversed vertical levels +!! Philippe 13/02/2018: use ifdef MNH_REAL to prevent problems with intrinsics on Blue Gene/Q +!! 01/2019 (Q. Rodier) support for RM17 mixing length +!! 03/2021 (JL Redelsperger) Ocean model case +!! 06/2021 (P. Marquet) correction of exponent on final length according to Lemarié et al. 2021 +!------------------------------------------------------------------------------- +! +!* 0. DECLARATIONS +! ------------ +! +USE MODD_CONF, ONLY: CPROGRAM +USE MODD_CST +USE MODD_CTURB +USE MODD_DYN_n, ONLY: LOCEAN +USE MODD_PARAMETERS +USE MODD_PRECISION, ONLY: MNHREAL +! +! +IMPLICIT NONE +! +!* 0.1 Declaration of arguments +! ------------------------ +! +INTEGER, INTENT(IN) :: KKA !near ground array index +INTEGER, INTENT(IN) :: KKU !uppest atmosphere array index +INTEGER, INTENT(IN) :: KKL !vert. levels type 1=MNH -1=ARO +REAL, DIMENSION(:,:,:), INTENT(IN) :: PZZ +REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ +REAL, DIMENSION(:,:,:), INTENT(IN) :: PTHVREF +REAL, DIMENSION(:,:,:), INTENT(IN) :: PTHLM ! conservative pot. temp. +INTEGER, INTENT(IN) :: KRR +REAL, DIMENSION(:,:,:,:), INTENT(IN) :: PRM ! water var. +REAL, DIMENSION(:,:,:), INTENT(IN) :: PTKEM ! TKE +REAL, DIMENSION(:,:,:), INTENT(IN) :: PSHEAR +REAL, DIMENSION(:,:,:), INTENT(OUT) :: PLM ! Mixing length +! thermodynamical variables PTHLM=Theta at the begining +! +!* 0.2 Declaration of local variables +! ------------------------------ +! +INTEGER :: IKB,IKE +INTEGER :: IKT ! array size in k direction +INTEGER :: IKTB,IKTE ! start, end of k loops in physical domain + +REAL, DIMENSION(SIZE(PTKEM,1)*SIZE(PTKEM,2),SIZE(PTKEM,3)) :: ZVPT ! Virtual Potential Temp at half levels +REAL, DIMENSION(SIZE(PTKEM,1)*SIZE(PTKEM,2),SIZE(PTKEM,3)) :: ZDELTVPT + ! Increment of Virtual Potential Temp between two following levels +REAL, DIMENSION(SIZE(PTKEM,1)*SIZE(PTKEM,2),SIZE(PTKEM,3)) :: ZHLVPT + ! Virtual Potential Temp at half levels +REAL, DIMENSION(SIZE(PTKEM,1)*SIZE(PTKEM,2)) :: ZLWORK,ZINTE +! ! downwards then upwards vertical displacement, +! ! residual internal energy, +! ! residual potential energy +REAL, DIMENSION(SIZE(PTKEM,1)*SIZE(PTKEM,2),SIZE(PTKEM,3)) :: ZZZ,ZDZZ, & + ZG_O_THVREF, & + ZTHM,ZTKEM,ZLM, & + ZLMDN,ZSHEAR, & + ZSQRT_TKE +! ! input and output arrays packed according one horizontal coord. +REAL, DIMENSION(SIZE(PRM,1)*SIZE(PRM,2),SIZE(PRM,3),SIZE(PRM,4)) :: ZRM +! ! input array packed according one horizontal coord. +REAL, DIMENSION(SIZE(PRM,1)*SIZE(PRM,2),SIZE(PRM,3)) :: ZSUM ! to replace SUM function +! +INTEGER :: IIU,IJU +INTEGER :: J1D ! horizontal loop counter +INTEGER :: JK,JKK ! loop counters +INTEGER :: JRR ! moist loop counter +REAL :: ZRVORD ! Rv/Rd +REAL :: ZPOTE,ZLWORK1,ZLWORK2 +REAL :: ZTEST,ZTEST0,ZTESTM ! test for vectorization +REAL :: Z2SQRT2,ZUSRBL89,ZBL89EXP +!------------------------------------------------------------------------------- +! +REAL(KIND=JPRB) :: ZHOOK_HANDLE +IF (LHOOK) CALL DR_HOOK('BL89',0,ZHOOK_HANDLE) +Z2SQRT2=2.*SQRT(2.) +IIU=SIZE(PTKEM,1) +IJU=SIZE(PTKEM,2) +! +IKB=KKA+JPVEXT_TURB*KKL +IKE=KKU-JPVEXT_TURB*KKL +! +IKTB = JPVEXT_TURB + 1 +IKT = SIZE(PTKEM,3) +IKTE = IKT-JPVEXT_TURB +ZRVORD = XRV / XRD +! +!------------------------------------------------------------------------------- +! +!* 1. pack the horizontal dimensions into one +! --------------------------------------- +! +IF (CPROGRAM=='AROME ') THEN + DO JK=1,IKT + ZZZ (:,JK) = PZZ (:,1,JK) + ZDZZ (:,JK) = PDZZ (:,1,JK) + ZTHM (:,JK) = PTHLM (:,1,JK) + ZTKEM (:,JK) = PTKEM (:,1,JK) + ZG_O_THVREF(:,JK) = XG/PTHVREF(:,1,JK) + END DO + DO JK=1,IKT + DO JRR=1,KRR + ZRM (:,JK,JRR) = PRM (:,1,JK,JRR) + END DO + END DO +ELSE + DO JK=1,IKT + ZZZ (:,JK) = RESHAPE(PZZ (:,:,JK),(/ IIU*IJU /) ) + ZDZZ (:,JK) = RESHAPE(PDZZ (:,:,JK),(/ IIU*IJU /) ) + ZTHM (:,JK) = RESHAPE(PTHLM (:,:,JK),(/ IIU*IJU /) ) + ZSHEAR (:,JK) = RESHAPE(PSHEAR (:,:,JK),(/ IIU*IJU /) ) + ZTKEM (:,JK) = RESHAPE(PTKEM (:,:,JK),(/ IIU*IJU /) ) + ZG_O_THVREF(:,JK) = RESHAPE(XG/PTHVREF(:,:,JK),(/ IIU*IJU /) ) + IF (LOCEAN) ZG_O_THVREF(:,JK) = XG * XALPHAOC + DO JRR=1,KRR + ZRM (:,JK,JRR) = RESHAPE(PRM (:,:,JK,JRR),(/ IIU*IJU /) ) + END DO + END DO +END IF +! +ZSQRT_TKE = SQRT(ZTKEM) +! +!ZBL89EXP is defined here because (and not in ini_cturb) because XCED is defined in read_exseg (depending on BL89/RM17) +ZBL89EXP = LOG(16.)/(4.*LOG(XKARMAN)+LOG(XCED)-3.*LOG(XCMFS)) +ZUSRBL89 = 1./ZBL89EXP +!------------------------------------------------------------------------------- +! +!* 2. Virtual potential temperature on the model grid +! ----------------------------------------------- +! +IF(KRR /= 0) THEN + ZSUM(:,:) = 0. + DO JRR=1,KRR + ZSUM(:,:) = ZSUM(:,:)+ZRM(:,:,JRR) + ENDDO + ZVPT(:,1:)=ZTHM(:,:) * ( 1. + ZRVORD*ZRM(:,:,1) ) & + / ( 1. + ZSUM(:,:) ) +ELSE + ZVPT(:,1:)=ZTHM(:,:) +END IF +! +!!!!!!!!!!!! +!!!!!!!!!!!! +!!!!!!!!!!!!!!!!!! WARNING !! +!!!!!!!!!!!! +!!!!!!!!!!!! +!Any modification done to the following lines and to the sections 4 and +!6 must be copied in compute_bl89_ml routine. +!We do not call directly this routine for numerical performance reasons +!but algorithm must remain the same. +!!!!!!!!!!!! + +ZDELTVPT(:,IKTB:IKTE)=ZVPT(:,IKTB:IKTE)-ZVPT(:,IKTB-KKL:IKTE-KKL) +ZDELTVPT(:,KKU)=ZVPT(:,KKU)-ZVPT(:,KKU-KKL) +ZDELTVPT(:,KKA)=0. +WHERE (ABS(ZDELTVPT(:,:))<XLINF) + ZDELTVPT(:,:)=XLINF +END WHERE +! +ZHLVPT(:,IKTB:IKTE)= 0.5 * ( ZVPT(:,IKTB:IKTE)+ZVPT(:,IKTB-KKL:IKTE-KKL) ) +ZHLVPT(:,KKU)= 0.5 * ( ZVPT(:,KKU)+ZVPT(:,KKU-KKL) ) +ZHLVPT(:,KKA) = ZVPT(:,KKA) +!------------------------------------------------------------------------------- +! +!* 3. loop on model levels +! -------------------- +! +DO JK=IKTB,IKTE +! +!------------------------------------------------------------------------------- +! +!* 4. mixing length for a downwards displacement +! ------------------------------------------ + ZINTE(:)=ZTKEM(:,JK) + ZLWORK=0. + ZTESTM=1. + DO JKK=JK,IKB,-KKL + IF(ZTESTM > 0.) THEN + ZTESTM=0. + DO J1D=1,IIU*IJU + ZTEST0=0.5+SIGN(0.5,ZINTE(J1D)) + !--------- SHEAR + STABILITY ----------- + ZPOTE = ZTEST0* & + (-ZG_O_THVREF(J1D,JK)*(ZHLVPT(J1D,JKK)-ZVPT(J1D,JK)) & + + XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + )*ZDZZ(J1D,JKK) + + ZTEST =0.5+SIGN(0.5,ZINTE(J1D)-ZPOTE) + ZTESTM=ZTESTM+ZTEST0 + ZLWORK1=ZDZZ(J1D,JKK) + + !--------- SHEAR + STABILITY ----------- + ZLWORK2 = (ZG_O_THVREF(J1D,JK) *(ZVPT(J1D,JKK) - ZVPT(J1D,JK)) & + -XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + + sqrt(abs( (XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + + ( -ZG_O_THVREF(J1D,JK) * (ZVPT(J1D,JKK) - ZVPT(J1D,JK)) ))**2.0 + & + 2. * ZINTE(J1D) * & + (ZG_O_THVREF(J1D,JK) * ZDELTVPT(J1D,JKK)/ ZDZZ(J1D,JKK))))) / & + (ZG_O_THVREF(J1D,JK) * ZDELTVPT(J1D,JKK) / ZDZZ(J1D,JKK)) + ZLWORK(J1D)=ZLWORK(J1D)+ZTEST0*(ZTEST*ZLWORK1+(1-ZTEST)*ZLWORK2) + ZINTE(J1D) = ZINTE(J1D) - ZPOTE + END DO + ENDIF + END DO +!------------------------------------------------------------------------------- +! +!* 5. intermediate storage of the final mixing length +! ----------------------------------------------- +! + ZLMDN(:,JK)=MIN(ZLWORK(:),0.5*(ZZZ(:,JK)+ZZZ(:,JK+KKL))-ZZZ(:,IKB)) +! +!------------------------------------------------------------------------------- +! +!* 6. mixing length for an upwards displacement +! ----------------------------------------- +! + ZINTE(:)=ZTKEM(:,JK) + ZLWORK=0. + ZTESTM=1. +! + DO JKK=JK+KKL,IKE,KKL + IF(ZTESTM > 0.) THEN + ZTESTM=0. + DO J1D=1,IIU*IJU + !--------- SHEAR + STABILITY ----------- + ZPOTE = ZTEST0* & + (ZG_O_THVREF(J1D,JK)*(ZHLVPT(J1D,JKK)-ZVPT(J1D,JK)) & + +XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + )*ZDZZ(J1D,JKK) + ZTEST =0.5+SIGN(0.5,ZINTE(J1D)-ZPOTE) + ZTESTM=ZTESTM+ZTEST0 + ZLWORK1=ZDZZ(J1D,JKK) + !--------- SHEAR + STABILITY ----------- + ZLWORK2= ( - ZG_O_THVREF(J1D,JK) *(ZVPT(J1D,JKK-KKL) - ZVPT(J1D,JK) ) & + - XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + + SQRT (ABS( & + (XRM17*ZSHEAR(J1D,JKK)*ZSQRT_TKE(J1D,JK) & + + ( ZG_O_THVREF(J1D,JK) * (ZVPT(J1D,JKK-KKL) - ZVPT(J1D,JK))) )**2 & + + 2. * ZINTE(J1D) * & + ( ZG_O_THVREF(J1D,JK)* ZDELTVPT(J1D,JKK)/ZDZZ(J1D,JKK))))) / & + (ZG_O_THVREF(J1D,JK) * ZDELTVPT(J1D,JKK) / ZDZZ(J1D,JKK)) + ZLWORK(J1D)=ZLWORK(J1D)+ZTEST0*(ZTEST*ZLWORK1+(1-ZTEST)*ZLWORK2) + ZINTE(J1D) = ZINTE(J1D) - ZPOTE + END DO + ENDIF + END DO +! +!------------------------------------------------------------------------------- +! +!* 7. final mixing length +! + DO J1D=1,IIU*IJU + ZLWORK1=MAX(ZLMDN(J1D,JK),1.E-10_MNHREAL) + ZLWORK2=MAX(ZLWORK(J1D),1.E-10_MNHREAL) + ZPOTE = ZLWORK1 / ZLWORK2 + ZLWORK2=1.d0 + ZPOTE**ZBL89EXP + ZLM(J1D,JK) = ZLWORK1*(2./ZLWORK2)**ZUSRBL89 + END DO + +ZLM(:,JK)=MAX(ZLM(:,JK),XLINI) + +!------------------------------------------------------------------------------- +!* 8. end of the loop on the vertical levels +! -------------------------------------- +! +END DO +! +!------------------------------------------------------------------------------- +! +!* 9. boundaries +! ---------- +! +ZLM(:,KKA)=ZLM(:,IKB) +ZLM(:,IKE)=ZLM(:,IKE-KKL) +ZLM(:,KKU)=ZLM(:,IKE-KKL) +! +!------------------------------------------------------------------------------- +! +!* 10. retrieve output array in model coordinates +! ------------------------------------------ +! +IF (CPROGRAM=='AROME ') THEN + DO JK=1,IKT + PLM (:,1,JK) = ZLM (:,JK) + END DO +ELSE + DO JK=1,IKT + PLM (:,:,JK) = RESHAPE(ZLM (:,JK), (/ IIU,IJU /) ) + END DO +END IF + +! +IF (LHOOK) CALL DR_HOOK('BL89',1,ZHOOK_HANDLE) +END SUBROUTINE BL89 diff --git a/src/common/turb/compute_bl89_ml.f90 b/src/common/turb/compute_bl89_ml.f90 new file mode 100644 index 0000000000000000000000000000000000000000..5a75011c8ed80ee7d7a3b364136a9ecff36168ea --- /dev/null +++ b/src/common/turb/compute_bl89_ml.f90 @@ -0,0 +1,216 @@ +! ######spl + SUBROUTINE COMPUTE_BL89_ML(KKA,KKB,KKE,KKU,KKL,PDZZ2D, & + PTKEM_DEP,PG_O_THVREF,PVPT,KK,OUPORDN,OFLUX,PSHEAR,PLWORK) + + USE PARKIND1, ONLY : JPRB + USE YOMHOOK , ONLY : LHOOK, DR_HOOK +! ################################################################### +!! +!! COMPUTE_BL89_ML routine to: +!! 1/ compute upward or downward mixing length with BL89 formulation +!! +!! AUTHOR +!! ------ +!! J. PERGAUD +!! +!! MODIFICATIONS +!! ------------- +!! Original 19/01/06 +!! S. Riette Jan 2012: support for both order of vertical levels and cleaning +!! R.Honnert Oct 2016 : Update with AROME +!! Q.Rodier 01/2019 : support RM17 mixing length as in bl89.f90 +! P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg +!! +!------------------------------------------------------------------------------- +! +!* 0. DECLARATIONS +! +! ------------ +! +!!!!!!!!!!!! +!!!!!!!!!!!! +!!!!!!!!!!!!!!!!!! WARNING !! +!!!!!!!!!!!! +!!!!!!!!!!!! +!Any modification done to this routine must be copied in bl89.f90. +!This routine was inlined in bl89 for numerical performance reasons +!but algorithm must remain the same. +!!!!!!!!!!!! +! +USE MODD_CTURB +USE MODD_PARAMETERS, ONLY: JPVEXT +! +USE MODE_MSG +! +USE MODI_SHUMAN_MF +! +IMPLICIT NONE +! +! 0.1 arguments +! +INTEGER, INTENT(IN) :: KKA ! near ground array index +INTEGER, INTENT(IN) :: KKB ! near ground physical index +INTEGER, INTENT(IN) :: KKE ! uppest atmosphere physical index +INTEGER, INTENT(IN) :: KKU ! uppest atmosphere array index +INTEGER, INTENT(IN) :: KKL ! +1 if grid goes from ground to atmosphere top, -1 otherwise +REAL, DIMENSION(:,:), INTENT(IN) :: PDZZ2D ! height difference between two mass levels +REAL, DIMENSION(:), INTENT(IN) :: PTKEM_DEP ! TKE to consume +REAL, DIMENSION(:), INTENT(IN) :: PG_O_THVREF ! g/ThetaVRef at the departure point +REAL, DIMENSION(:,:), INTENT(IN) :: PVPT ! ThetaV on mass levels +INTEGER, INTENT(IN) :: KK ! index of departure level +LOGICAL, INTENT(IN) :: OUPORDN ! switch to compute upward (true) or + ! downward (false) mixing length +LOGICAL, INTENT(IN) :: OFLUX ! Computation must be done from flux level +REAL, DIMENSION(:), INTENT(OUT) :: PLWORK ! Resulting mixing length +REAL, DIMENSION(:,:), INTENT(IN) :: PSHEAR ! vertical wind shear for RM17 mixing length + +! 0.2 Local variable +! +REAL, DIMENSION(SIZE(PVPT,1)) :: ZLWORK1,ZLWORK2 ! Temporary mixing length +REAL, DIMENSION(SIZE(PVPT,1)) :: ZINTE,ZPOTE ! TKE and potential energy + ! between 2 levels +REAL, DIMENSION(SIZE(PVPT,1)) :: ZVPT_DEP ! Thetav on departure point +! +REAL, DIMENSION(SIZE(PVPT,1),SIZE(PVPT,2)) :: ZDELTVPT,ZHLVPT + !Virtual Potential Temp at Half level and DeltaThv between + !2 mass levels + +INTEGER :: IIJU !Internal Domain +INTEGER :: J1D !horizontal loop counter +INTEGER :: JKK !loop counters +REAL :: ZTEST,ZTEST0,ZTESTM !test for vectorization +!------------------------------------------------------------------------------------- +! +!* 1. INITIALISATION +! -------------- +REAL(KIND=JPRB) :: ZHOOK_HANDLE +IF (LHOOK) CALL DR_HOOK('COMPUTE_BL89_ML',0,ZHOOK_HANDLE) +IIJU=SIZE(PVPT,1) +! +ZDELTVPT(:,:)=DZM_MF(KKA,KKU,KKL,PVPT(:,:)) +ZDELTVPT(:,KKA)=0. +WHERE (ABS(ZDELTVPT(:,:))<XLINF) + ZDELTVPT(:,:)=XLINF +END WHERE +! +ZHLVPT(:,:)=MZM_MF(KKA,KKU,KKL,PVPT(:,:)) +! +!We consider that gradient between mass levels KKB and KKB+KKL is the same as +!the gradient between flux level KKB and mass level KKB +ZDELTVPT(:,KKB)=PDZZ2D(:,KKB)*ZDELTVPT(:,KKB+KKL)/PDZZ2D(:,KKB+KKL) +ZHLVPT(:,KKB)=PVPT(:,KKB)-ZDELTVPT(:,KKB)*0.5 +! +! +! +!* 2. CALCULATION OF THE UPWARD MIXING LENGTH +! --------------------------------------- +! + +IF (OUPORDN.EQV..TRUE.) THEN + ZINTE(:)=PTKEM_DEP(:) + PLWORK=0. + ZTESTM=1. + IF(OFLUX)THEN + ZVPT_DEP(:)=ZHLVPT(:,KK) ! departure point is on flux level + !We must compute what happens between flux level KK and mass level KK + DO J1D=1,IIJU + ZTEST0=0.5+SIGN(0.5,ZINTE(J1D)) ! test if there's energy to consume + ! Energy consumed if parcel cross the entire layer + ZPOTE(J1D) = ZTEST0*(PG_O_THVREF(J1D) * & + (0.5*(ZHLVPT(J1D,KK)+ PVPT(J1D,KK)) - ZVPT_DEP(J1D)) + & + XRM17*PSHEAR(J1D,KK)*SQRT(ABS(PTKEM_DEP(J1D)))) * & + PDZZ2D(J1D,KK)*0.5 + ! Test if it rests some energy to consume + ZTEST =0.5+SIGN(0.5,ZINTE(J1D)-ZPOTE(J1D)) + ! Length travelled by parcel if it rests energy to consume + ZLWORK1(J1D)=PDZZ2D(J1D,KK)*0.5 + ! Lenght travelled by parcel to nullify energy + ZLWORK2(J1D)= ( - PG_O_THVREF(J1D) * & + ( ZHLVPT(J1D,KK) - ZVPT_DEP(J1D) ) & + - XRM17*PSHEAR(J1D,JKK)*SQRT(ABS(PTKEM_DEP(J1D))) & + + SQRT (ABS( & + (XRM17*PSHEAR(J1D,JKK)*SQRT(ABS(PTKEM_DEP(J1D))) + & + PG_O_THVREF(J1D) * (ZHLVPT(J1D,KK) - ZVPT_DEP(J1D)) )**2 & + + 2. * ZINTE(J1D) * PG_O_THVREF(J1D) & + * ZDELTVPT(J1D,KK) / PDZZ2D(J1D,KK) )) ) / & + ( PG_O_THVREF(J1D) * ZDELTVPT(J1D,KK) / PDZZ2D(J1D,KK) ) + ! Effective length travelled by parcel + PLWORK(J1D)=PLWORK(J1D)+ZTEST0*(ZTEST*ZLWORK1(J1D)+ & + (1-ZTEST)*ZLWORK2(J1D)) + ! Rest of energy to consume + ZINTE(J1D) = ZINTE(J1D) - ZPOTE(J1D) + ENDDO + ELSE + ZVPT_DEP(:)=PVPT(:,KK) ! departure point is on mass level + ENDIF + + DO JKK=KK+KKL,KKE,KKL + IF(ZTESTM > 0.) THEN + ZTESTM=0 + DO J1D=1,IIJU + ZTEST0=0.5+SIGN(0.5,ZINTE(J1D)) + ZPOTE(J1D) = ZTEST0*(PG_O_THVREF(J1D) * & + (ZHLVPT(J1D,JKK) - ZVPT_DEP(J1D)) & + + XRM17*PSHEAR(J1D,JKK)*SQRT(ABS(PTKEM_DEP(J1D))))* PDZZ2D(J1D,JKK) + ZTEST =0.5+SIGN(0.5,ZINTE(J1D)-ZPOTE(J1D)) + ZTESTM=ZTESTM+ZTEST0 + ZLWORK1(J1D)=PDZZ2D(J1D,JKK) + !ZLWORK2 jump of the last reached level + ZLWORK2(J1D)= ( - PG_O_THVREF(J1D) * & + ( PVPT(J1D,JKK-KKL) - ZVPT_DEP(J1D) ) & + - XRM17*PSHEAR(J1D,JKK)*sqrt(abs(PTKEM_DEP(J1D))) & + + SQRT (ABS( & + (XRM17*PSHEAR(J1D,JKK)*sqrt(abs(PTKEM_DEP(J1D))) + & + PG_O_THVREF(J1D) * (PVPT(J1D,JKK-KKL) - ZVPT_DEP(J1D)) )**2 & + + 2. * ZINTE(J1D) * PG_O_THVREF(J1D) & + * ZDELTVPT(J1D,JKK) / PDZZ2D(J1D,JKK) )) ) / & + ( PG_O_THVREF(J1D) * ZDELTVPT(J1D,JKK) / PDZZ2D(J1D,JKK) ) + ! + PLWORK(J1D)=PLWORK(J1D)+ZTEST0*(ZTEST*ZLWORK1(J1D)+ & + (1-ZTEST)*ZLWORK2(J1D)) + ZINTE(J1D) = ZINTE(J1D) - ZPOTE(J1D) + END DO + ENDIF + END DO +ENDIF +!! +!* 2. CALCULATION OF THE DOWNWARD MIXING LENGTH +! --------------------------------------- +! + +IF (OUPORDN.EQV..FALSE.) THEN + IF(OFLUX) CALL PRINT_MSG(NVERB_FATAL,'GEN','COMPUTE_BL89_ML','OFLUX option not coded for downward mixing length') + ZINTE(:)=PTKEM_DEP(:) + PLWORK=0. + ZTESTM=1. + DO JKK=KK,KKB,-KKL + IF(ZTESTM > 0.) THEN + ZTESTM=0 + DO J1D=1,IIJU + ZTEST0=0.5+SIGN(0.5,ZINTE(J1D)) + ZPOTE(J1D) = ZTEST0*(-PG_O_THVREF(J1D) * & + (ZHLVPT(J1D,JKK) - PVPT(J1D,KK)) & + + XRM17*PSHEAR(J1D,JKK)*SQRT(ABS(PTKEM_DEP(J1D))))* PDZZ2D(J1D,JKK) + ZTEST =0.5+SIGN(0.5,ZINTE(J1D)-ZPOTE(J1D)) + ZTESTM=ZTESTM+ZTEST0 + ZLWORK1(J1D)=PDZZ2D(J1D,JKK) + ZLWORK2(J1D)= ( + PG_O_THVREF(J1D) * & + ( PVPT(J1D,JKK) - PVPT(J1D,KK) ) & + -XRM17*PSHEAR(J1D,JKK)*sqrt(abs(PTKEM_DEP(J1D))) & + + SQRT (ABS( & + (XRM17*PSHEAR(J1D,JKK)*sqrt(abs(PTKEM_DEP(J1D))) - & + PG_O_THVREF(J1D) * (PVPT(J1D,JKK) - PVPT(J1D,KK)) )**2 & + + 2. * ZINTE(J1D) * PG_O_THVREF(J1D) & + * ZDELTVPT(J1D,JKK) / PDZZ2D(J1D,JKK) )) ) / & + ( PG_O_THVREF(J1D) * ZDELTVPT(J1D,JKK) / PDZZ2D(J1D,JKK) ) + ! + PLWORK(J1D)=PLWORK(J1D)+ZTEST0*(ZTEST*ZLWORK1(J1D)+ & + (1-ZTEST)*ZLWORK2(J1D)) + ZINTE(J1D) = ZINTE(J1D) - ZPOTE(J1D) + END DO + ENDIF + END DO +ENDIF + +IF (LHOOK) CALL DR_HOOK('COMPUTE_BL89_ML',1,ZHOOK_HANDLE) +END SUBROUTINE COMPUTE_BL89_ML