!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier !MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence !MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt !MNH_LIC for details. version 1. !----------------------------------------------------------------- !--------------- special set of characters for RCS information !----------------------------------------------------------------- ! $Source: /home/cvsroot/MNH-VX-Y-Z/src/MNH/turb_hor_sv_flux.f90,v $ $Revision: 1.1.10.2.2.1.2.1.2.1 $ ! MASDEV4_7 turb 2006/05/18 13:07:25 !----------------------------------------------------------------- ! ############################ MODULE MODI_TURB_HOR_SV_FLUX ! ############################ ! INTERFACE ! SUBROUTINE TURB_HOR_SV_FLUX(KSPLT, & OCLOSE_OUT,OTURB_FLX, & HFMFILE,HLUOUT, & PK,PINV_PDXX,PINV_PDYY,PINV_PDZZ,PMZM_PRHODJ, & PDXX,PDYY,PDZZ,PDZX,PDZY, & PDIRCOSXW,PDIRCOSYW, & PRHODJ,PWM, & PSFSVM, & PSVM, & PRSVS ) ! INTEGER, INTENT(IN) :: KSPLT ! split process index LOGICAL, INTENT(IN) :: OCLOSE_OUT ! switch for syncronous ! file opening LOGICAL, INTENT(IN) :: OTURB_FLX ! switch to write the ! turbulent fluxes in the syncronous FM-file CHARACTER(LEN=*), INTENT(IN) :: HFMFILE ! Name of the output ! FM-file CHARACTER(LEN=*), INTENT(IN) :: HLUOUT ! Output-listing name ! for model n ! REAL, DIMENSION(:,:,:), INTENT(IN) :: PK ! Turbulent diffusion doef. ! PK = PLM * SQRT(PTKEM) REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDXX ! 1./PDXX REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDYY ! 1./PDYY REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDZZ ! 1./PDZZ REAL, DIMENSION(:,:,:), INTENT(IN) :: PMZM_PRHODJ ! MZM(PRHODJ) REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX, PDYY, PDZZ, PDZX, PDZY ! Metric coefficients REAL, DIMENSION(:,:), INTENT(IN) :: PDIRCOSXW, PDIRCOSYW ! Director Cosinus along x and y directions at surface w-point REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! density * grid volume REAL, DIMENSION(:,:,:), INTENT(IN) :: PWM ! vertical wind ! REAL, DIMENSION(:,:,:), INTENT(IN) :: PSFSVM ! surface fluxes ! ! ! Variables at t-1 REAL, DIMENSION(:,:,:,:), INTENT(IN) :: PSVM ! scalar var. at t-1 ! REAL, DIMENSION(:,:,:,:), INTENT(INOUT) :: PRSVS ! var. at t+1 -split- ! ! ! END SUBROUTINE TURB_HOR_SV_FLUX ! END INTERFACE ! END MODULE MODI_TURB_HOR_SV_FLUX ! ################################################################ SUBROUTINE TURB_HOR_SV_FLUX(KSPLT, & OCLOSE_OUT,OTURB_FLX, & HFMFILE,HLUOUT, & PK,PINV_PDXX,PINV_PDYY,PINV_PDZZ,PMZM_PRHODJ, & PDXX,PDYY,PDZZ,PDZX,PDZY, & PDIRCOSXW,PDIRCOSYW, & PRHODJ,PWM, & PSFSVM, & PSVM, & PRSVS ) ! ################################################################ ! ! !!**** *TURB_HOR* -routine to compute the source terms in the meso-NH !! model equations due to the non-vertical turbulent fluxes. !! !! PURPOSE !! ------- !! !! see TURB_HOR !! !!** METHOD !! ------ !! !! EXTERNAL !! -------- !! !! IMPLICIT ARGUMENTS !! ------------------ !! !! REFERENCE !! --------- !! !! AUTHOR !! ------ !! !! Joan Cuxart * INM and Meteo-France * !! !! MODIFICATIONS !! ------------- !! Aug , 1997 (V. Saravane) spliting of TURB_HOR !! Nov 27, 1997 (V. Masson) clearing of the routine !! Oct 18, 2000 (V. Masson) LES computations + LFLAT swith !! + bug on Y scalar flux !! Jun 20, 2001 (J Stein) case of lagragian variables !! Nov 06, 2002 (V. Masson) LES budgets !! October 2009 (G. Tanguy) add ILENCH=LEN(YCOMMENT) after !! change of YCOMMENT !! -------------------------------------------------------------------------- ! !* 0. DECLARATIONS ! ------------ ! USE MODD_IBM_PARAM_n USE MODD_CST USE MODD_CONF USE MODD_CTURB USE MODD_PARAMETERS USE MODD_NSV, ONLY : NSV_LGBEG,NSV_LGEND USE MODD_LES ! USE MODE_FMWRIT USE MODI_GRADIENT_M USE MODI_GRADIENT_U USE MODI_GRADIENT_V USE MODI_GRADIENT_W USE MODI_SHUMAN USE MODI_COEFJ USE MODI_LES_MEAN_SUBGRID ! USE MODI_SECOND_MNH ! IMPLICIT NONE ! ! !* 0.1 declaration of arguments ! ! ! INTEGER, INTENT(IN) :: KSPLT ! split process index LOGICAL, INTENT(IN) :: OCLOSE_OUT ! switch for syncronous ! file opening LOGICAL, INTENT(IN) :: OTURB_FLX ! switch to write the ! turbulent fluxes in the syncronous FM-file CHARACTER(LEN=*), INTENT(IN) :: HFMFILE ! Name of the output ! FM-file CHARACTER(LEN=*), INTENT(IN) :: HLUOUT ! Output-listing name ! for model n ! REAL, DIMENSION(:,:,:), INTENT(IN) :: PK ! Turbulent diffusion doef. ! PK = PLM * SQRT(PTKEM) REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDXX ! 1./PDXX REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDYY ! 1./PDYY REAL, DIMENSION(:,:,:), INTENT(IN) :: PINV_PDZZ ! 1./PDZZ REAL, DIMENSION(:,:,:), INTENT(IN) :: PMZM_PRHODJ ! MZM(PRHODJ) REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX, PDYY, PDZZ, PDZX, PDZY ! Metric coefficients REAL, DIMENSION(:,:), INTENT(IN) :: PDIRCOSXW, PDIRCOSYW ! Director Cosinus along x and y directions at surface w-point REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! density * grid volume REAL, DIMENSION(:,:,:), INTENT(IN) :: PWM ! vertical wind ! REAL, DIMENSION(:,:,:), INTENT(IN) :: PSFSVM ! surface fluxes ! ! ! Variables at t-1 REAL, DIMENSION(:,:,:,:), INTENT(IN) :: PSVM ! scalar var. at t-1 ! REAL, DIMENSION(:,:,:,:), INTENT(INOUT) :: PRSVS ! var. at t+1 -split- ! ! ! !* 0.2 declaration of local variables ! REAL, DIMENSION(SIZE(PSVM,1),SIZE(PSVM,2),SIZE(PSVM,3)) & :: ZFLXX,ZFLXY ! work arrays REAL, DIMENSION(SIZE(PSVM,1),SIZE(PSVM,2),1) :: ZWORK2D ! INTEGER :: IRESP ! Return code of FM routines INTEGER :: IGRID ! C-grid indicator in LFIFM file INTEGER :: ILENCH ! Length of comment string in LFIFM file INTEGER :: IKB,IKE ! Index values for the Beginning and End ! mass points of the domain INTEGER :: JSV ! loop counter INTEGER :: ISV ! number of scalar var. CHARACTER (LEN=100) :: YCOMMENT ! comment string in LFIFM file CHARACTER (LEN=16) :: YRECFM ! Name of the desired field in LFIFM file REAL, DIMENSION(SIZE(PDZZ,1),SIZE(PDZZ,2),1+JPVEXT:3+JPVEXT) :: ZCOEFF ! coefficients for the uncentred gradient ! computation near the ground ! INTEGER :: IKU REAL :: ZTIME1, ZTIME2 ! --------------------------------------------------------------------------- ! !* 1. PRELIMINARY COMPUTATIONS ! ------------------------ ! IKB = 1+JPVEXT IKE = SIZE(PSVM,3)-JPVEXT IKU = SIZE(PSVM,3) ! ISV = SIZE(PSVM,4) ! ! ! compute the coefficients for the uncentred gradient computation near the ! ground ZCOEFF(:,:,IKB+2)= - PDZZ(:,:,IKB+1) / & ( (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) * PDZZ(:,:,IKB+2) ) ZCOEFF(:,:,IKB+1)= (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) / & ( PDZZ(:,:,IKB+1) * PDZZ(:,:,IKB+2) ) ZCOEFF(:,:,IKB)= - (PDZZ(:,:,IKB+2)+2.*PDZZ(:,:,IKB+1)) / & ( (PDZZ(:,:,IKB+2)+PDZZ(:,:,IKB+1)) * PDZZ(:,:,IKB+1) ) ! ! !* 15. HORIZONTAL FLUXES OF PASSIVE SCALARS ! ------------------------------------ ! ! DO JSV=1,ISV ! IF (LNOMIXLG .AND. JSV >= NSV_LGBEG .AND. JSV<= NSV_LGEND) CYCLE ! ! 15.1 ! ---------- ! ! Computes the flux in the X direction ZFLXX(:,:,:) = -XCHF * MXM(PK) * GX_M_U(1,IKU,1,PSVM(:,:,:,JSV),PDXX,PDZZ,PDZX) ZFLXX(:,:,IKE+1) = ZFLXX(:,:,IKE) ! ! Compute the flux at the first inner U-point with an uncentred vertical ! gradient ZFLXX(:,:,IKB:IKB) = -XCHF * MXM( PK(:,:,IKB:IKB) ) * & ( DXM(PSVM(:,:,IKB:IKB,JSV)) * PINV_PDXX(:,:,IKB:IKB) & -MXM ( ZCOEFF(:,:,IKB+2:IKB+2)*PSVM(:,:,IKB+2:IKB+2,JSV) & +ZCOEFF(:,:,IKB+1:IKB+1)*PSVM(:,:,IKB+1:IKB+1,JSV) & +ZCOEFF(:,:,IKB :IKB )*PSVM(:,:,IKB :IKB ,JSV) & ) * 0.5 * ( PDZX(:,:,IKB+1:IKB+1)+PDZX(:,:,IKB:IKB) ) & * PINV_PDXX(:,:,IKB:IKB) & ) ! extrapolates the flux under the ground so that the vertical average with ! the IKB flux gives the ground value ZWORK2D(:,:,1)=PSFSVM(:,:,JSV) * PDIRCOSXW(:,:) ZFLXX(:,:,IKB-1:IKB-1) = 2. * MXM( ZWORK2D(:,:,1:1) ) - ZFLXX(:,:,IKB:IKB) ! ! stores IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN WRITE(YRECFM,'("USV_FLX_",I3.3)') JSV YCOMMENT='X_Y_Z_'//YRECFM//' (SVUNIT*M/S)' IGRID = 2 ILENCH=LEN(YCOMMENT) CALL FMWRIT(HFMFILE,YRECFM,HLUOUT,'XY',ZFLXX,IGRID,ILENCH,YCOMMENT,IRESP) END IF ! IF (LLES_CALL .AND. KSPLT==1) THEN CALL SECOND_MNH(ZTIME1) CALL LES_MEAN_SUBGRID( MXF(ZFLXX), X_LES_SUBGRID_USv(:,:,:,JSV) ) CALL LES_MEAN_SUBGRID( MZF(1,IKU,1,MXF(GX_W_UW(1,IKU,1,PWM,PDXX,PDZZ,PDZX)*MZM(1,IKU,1,ZFLXX))), & X_LES_RES_ddxa_W_SBG_UaSv(:,:,:,JSV) , .TRUE. ) CALL LES_MEAN_SUBGRID( GX_M_M(1,IKU,1,PSVM(:,:,:,JSV),PDXX,PDZZ,PDZX)*MXF(ZFLXX), & X_LES_RES_ddxa_Sv_SBG_UaSv(:,:,:,JSV), .TRUE. ) CALL SECOND_MNH(ZTIME2) XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1 END IF ! ! 15.2 ! ---------- ! IF (.NOT. L2D) THEN ! ! Computes the flux in the Y direction ZFLXY(:,:,:)=-XCHF * MYM(PK) * GY_M_V(1,IKU,1,PSVM(:,:,:,JSV),PDYY,PDZZ,PDZY) ZFLXY(:,:,IKE+1) = ZFLXY(:,:,IKE) ! ! Compute the flux at the first inner V-point with an uncentred vertical ! gradient ! ZFLXY(:,:,IKB:IKB) = -XCHF * MYM( PK(:,:,IKB:IKB) ) * & ( DYM(PSVM(:,:,IKB:IKB,JSV)) * PINV_PDYY(:,:,IKB:IKB) & -MYM ( ZCOEFF(:,:,IKB+2:IKB+2)*PSVM(:,:,IKB+2:IKB+2,JSV) & +ZCOEFF(:,:,IKB+1:IKB+1)*PSVM(:,:,IKB+1:IKB+1,JSV) & +ZCOEFF(:,:,IKB :IKB )*PSVM(:,:,IKB :IKB ,JSV) & ) * 0.5 * ( PDZY(:,:,IKB+1:IKB+1)+PDZY(:,:,IKB:IKB) ) & * PINV_PDYY(:,:,IKB:IKB) & ) ! extrapolates the flux under the ground so that the vertical average with ! the IKB flux gives the ground value ZWORK2D(:,:,1)=PSFSVM(:,:,JSV) * PDIRCOSYW(:,:) ZFLXY(:,:,IKB-1:IKB-1) = 2. * MYM( ZWORK2D(:,:,1:1) ) - ZFLXY(:,:,IKB:IKB) ! ! stores IF ( OCLOSE_OUT .AND. OTURB_FLX ) THEN WRITE(YRECFM,'("VSV_FLX_",I3.3)') JSV YCOMMENT='X_Y_Z_'//YRECFM//' (SVUNIT*M/S)' IGRID = 3 ILENCH=LEN(YCOMMENT) CALL FMWRIT(HFMFILE,YRECFM,HLUOUT,'XY',ZFLXY,IGRID,ILENCH,YCOMMENT,IRESP) END IF ! ELSE ZFLXY=0. END IF ! IF (LLES_CALL .AND. KSPLT==1) THEN CALL SECOND_MNH(ZTIME1) CALL LES_MEAN_SUBGRID( MYF(ZFLXY), X_LES_SUBGRID_VSv(:,:,:,JSV) ) CALL LES_MEAN_SUBGRID( MZF(1,IKU,1,MYF(GY_W_VW(1,IKU,1,PWM,PDYY,PDZZ,PDZY)*MZM(1,IKU,1,ZFLXY))), & X_LES_RES_ddxa_W_SBG_UaSv(:,:,:,JSV) , .TRUE. ) CALL LES_MEAN_SUBGRID( GY_M_M(1,IKU,1,PSVM(:,:,:,JSV),PDYY,PDZZ,PDZY)*MYF(ZFLXY), & X_LES_RES_ddxa_Sv_SBG_UaSv(:,:,:,JSV) , .TRUE. ) CALL SECOND_MNH(ZTIME2) XTIME_LES = XTIME_LES + ZTIME2 - ZTIME1 END IF ! ! ! 15.3 Horizontal source terms ! ----------------------- ! IF (.NOT. L2D) THEN IF (.NOT. LFLAT) THEN PRSVS(:,:,:,JSV)= PRSVS(:,:,:,JSV) & -DXF( XRHODJ2(:,:,:,1) * ZFLXX * PINV_PDXX ) & -DYF( XRHODJ2(:,:,:,2) * ZFLXY * PINV_PDYY ) & +DZF( 1,IKU,1,PMZM_PRHODJ * PINV_PDZZ * & ( MXF( MZM(1,IKU,1,ZFLXX * PINV_PDXX) * PDZX ) + MYF( MZM(1,IKU,1,ZFLXY * PINV_PDYY) * PDZY ) ) & ) ELSE PRSVS(:,:,:,JSV)= PRSVS(:,:,:,JSV) & -DXF( XRHODJ2(:,:,:,1) * ZFLXX * PINV_PDXX ) & -DYF( XRHODJ2(:,:,:,2) * ZFLXY * PINV_PDYY ) END IF ELSE IF (.NOT. LFLAT) THEN PRSVS(:,:,:,JSV)= PRSVS(:,:,:,JSV) & -DXF( XRHODJ2(:,:,:,1) * ZFLXX * PINV_PDXX ) & +DZF(1,IKU,1, PMZM_PRHODJ * PINV_PDZZ * & ( MXF( MZM(1,IKU,1,ZFLXX * PINV_PDXX) * PDZX ) ) & ) ELSE PRSVS(:,:,:,JSV)= PRSVS(:,:,:,JSV) & -DXF( XRHODJ2(:,:,:,1) *ZFLXX * PINV_PDXX ) END IF END IF ! ! END DO ! end loop JSV ! ! END SUBROUTINE TURB_HOR_SV_FLUX