!MNH_LIC Copyright 1994-2019 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. !----------------------------------------------------------------- ! ###################### MODULE MODI_GRADIENT_U ! ###################### ! INTERFACE ! ! FUNCTION GX_U_M(KKA,KKU,KL,PA,PDXX,PDZZ,PDZX) RESULT(PGX_U_M) INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX ! metric coefficient dxx REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX ! metric coefficient dzx ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGX_U_M ! result mass point ! END FUNCTION GX_U_M ! ! #ifdef MNH_OPENACC SUBROUTINE GX_U_M_DEVICE(KKA,KKU,KL,PA,PDXX,PDZZ,PDZX,PGX_U_M_DEVICE) INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX ! metric coefficient dxx REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX ! metric coefficient dzx ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point ! END SUBROUTINE GX_U_M_DEVICE #endif ! ! FUNCTION GY_U_UV(KKA,KKU,KL,PA,PDYY,PDZZ,PDZY) RESULT(PGY_U_UV) ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY ! metric coefficient dyy REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY ! metric coefficient dzy ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGY_U_UV ! result UV point ! END FUNCTION GY_U_UV ! ! #ifdef MNH_OPENACC SUBROUTINE GY_U_UV_DEVICE(KKA,KKU,KL,PA,PDYY,PDZZ,PDZY,PGY_U_UV_DEVICE) INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY ! metric coefficient dyy REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY ! metric coefficient dzy ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point ! END SUBROUTINE GY_U_UV_DEVICE #endif ! ! FUNCTION GZ_U_UW(KKA,KKU,KL,PA,PDZZ) RESULT(PGZ_U_UW) ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGZ_U_UW ! result UW point ! END FUNCTION GZ_U_UW ! ! #ifdef MNH_OPENACC SUBROUTINE GZ_U_UW_DEVICE(KKA,KKU,KL,PA,PDZZ,PGZ_U_UW_DEVICE) INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point ! END SUBROUTINE GZ_U_UW_DEVICE #endif ! ! END INTERFACE ! END MODULE MODI_GRADIENT_U ! ! ! ! ! ####################################################### FUNCTION GX_U_M(KKA,KKU,KL,PA,PDXX,PDZZ,PDZX) RESULT(PGX_U_M) ! ####################################################### ! !!**** *GX_U_M* - Cartesian Gradient operator: !! computes the gradient in the cartesian X !! direction for a variable placed at the !! U point and the result is placed at !! the mass point. !! PURPOSE !! ------- ! The purpose of this function is to compute the discrete gradient ! along the X cartesian direction for a field PA placed at the ! U point. The result is placed at the mass point. ! ! ! ( ______________z ) ! ( (___________x ) ) ! 1 ( (d*zx dzm(PA) ) ) ! PGX_U_M = ---- (dxf(PA) - (------------)) ) ! ___x ( ( ) ) ! d*xx ( ( d*zz ) ) ! ! ! !!** METHOD !! ------ !! The Chain rule of differencing is applied to variables expressed !! in the Gal-Chen & Somerville coordinates to obtain the gradient in !! the cartesian system !! !! EXTERNAL !! -------- !! MXF,MZF : Shuman functions (mean operators) !! DXF,DZF : Shuman functions (finite difference operators) !! !! IMPLICIT ARGUMENTS !! ------------------ !! NONE !! !! REFERENCE !! --------- !! Book2 of documentation of Meso-NH (GRAD_CAR operators) !! A Turbulence scheme for the Meso-NH model (Chapter 6) !! !! AUTHOR !! ------ !! Joan Cuxart *INM and Meteo-France* !! !! MODIFICATIONS !! ------------- !! Original 19/07/94 !! 18/10/00 (V.Masson) add LFLAT switch !------------------------------------------------------------------------- ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN USE MODD_CONF ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX ! metric coefficient dxx REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX ! metric coefficient dzx ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGX_U_M ! result mass point ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- ! !* 1. DEFINITION of GX_U_M ! -------------------- ! IF (.NOT. LFLAT) THEN PGX_U_M(:,:,:)= ( DXF(PA) - & MZF(KKA,KKU,KL,MXF(PDZX*DZM(KKA,KKU,KL,PA)) / PDZZ ) & ) / MXF(PDXX) ELSE PGX_U_M(:,:,:)= DXF(PA) / MXF(PDXX) END IF ! !---------------------------------------------------------------------------- ! END FUNCTION GX_U_M ! ! #ifdef MNH_OPENACC ! ####################################################### SUBROUTINE GX_U_M_DEVICE(KKA,KKU,KL,PA,PDXX,PDZZ,PDZX,PGX_U_M_DEVICE) ! ####################################################### ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN_DEVICE USE MODD_CONF ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX ! metric coefficient dxx REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZX ! metric coefficient dzx ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGX_U_M_DEVICE ! result mass point ! REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- !$acc data present( PA, PDXX, PDZZ, PDZX, PGX_U_M_DEVICE ) allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) !$acc data create( ztmp1_device, ztmp2_device, ztmp3_device ) ! !* 1. DEFINITION of GX_U_M_DEVICE ! -------------------- IF (.NOT. LFLAT) THEN CALL DXF_DEVICE(PA,ZTMP1_DEVICE) CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP2_DEVICE) !$acc kernels ZTMP3_DEVICE(:,:,:) = PDZX(:,:,:) * ZTMP2_DEVICE(:,:,:) !$acc end kernels CALL MXF_DEVICE(ZTMP3_DEVICE,ZTMP2_DEVICE) !$acc kernels ZTMP3_DEVICE(:,:,:) = ZTMP2_DEVICE(:,:,:) / PDZZ(:,:,:) !$acc end kernels CALL MZF_DEVICE(KKA,KKU,KL,ZTMP3_DEVICE,ZTMP2_DEVICE) CALL MXF_DEVICE(PDXX,ZTMP3_DEVICE) !$acc kernels PGX_U_M_DEVICE(:,:,:)= ( ZTMP1_DEVICE(:,:,:) - ZTMP2_DEVICE(:,:,:) ) / ZTMP3_DEVICE(:,:,:) !$acc end kernels ELSE CALL DXF_DEVICE(PA,ZTMP1_DEVICE) CALL MXF_DEVICE(PDXX,ZTMP2_DEVICE) !$acc kernels PGX_U_M_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:) !$acc end kernels END IF !$acc end data !$acc end data !---------------------------------------------------------------------------- ! END SUBROUTINE GX_U_M_DEVICE #endif ! ! ! ######################################################### FUNCTION GY_U_UV(KKA,KKU,KL,PA,PDYY,PDZZ,PDZY) RESULT(PGY_U_UV) ! ######################################################### ! !!**** *GY_U_UV* - Cartesian Gradient operator: !! computes the gradient in the cartesian Y !! direction for a variable placed at the !! U point and the result is placed at !! the UV vorticity point. !! PURPOSE !! ------- ! The purpose of this function is to compute the discrete gradient ! along the Y cartesian direction for a field PA placed at the ! U point. The result is placed at the UV vorticity point. ! ! ! ! ( _________________z ) ! ( (___x _________y ) ) ! 1 ( (d*zy (dzm(PA))) ) ) ! PGY_U_UV= ---- (dym(PA) - ( (------ ) ) ) ! ___x ( ( ( ___x ) ) ) ! d*yy ( ( ( d*zz ) ) ) ! ! ! !!** METHOD !! ------ !! The Chain rule of differencing is applied to variables expressed !! in the Gal-Chen & Somerville coordinates to obtain the gradient in !! the cartesian system !! !! EXTERNAL !! -------- !! MXM,MYM,MZF : Shuman functions (mean operators) !! DYM,DZM : Shuman functions (finite difference operators) !! !! IMPLICIT ARGUMENTS !! ------------------ !! NONE !! !! REFERENCE !! --------- !! Book2 of documentation of Meso-NH (GRAD_CAR operators) !! A Turbulence scheme for the Meso-NH model (Chapter 6) !! !! AUTHOR !! ------ !! Joan Cuxart *INM and Meteo-France* !! !! MODIFICATIONS !! ------------- !! Original 20/07/94 !! 18/10/00 (V.Masson) add LFLAT switch !------------------------------------------------------------------------- ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN USE MODD_CONF ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY ! metric coefficient dyy REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY ! metric coefficient dzy ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGY_U_UV ! result UV point ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- ! !* 1. DEFINITION of GY_U_UV ! --------------------- ! IF (.NOT. LFLAT) THEN PGY_U_UV(:,:,:)= (DYM(PA)- MZF(KKA,KKU,KL, MYM( DZM(KKA,KKU,KL,PA)/& MXM(PDZZ) ) *MXM(PDZY) ) ) / MXM(PDYY) ELSE PGY_U_UV(:,:,:)= DYM(PA) / MXM(PDYY) END IF ! !---------------------------------------------------------------------------- ! END FUNCTION GY_U_UV ! ! #ifdef MNH_OPENACC ! ######################################################### SUBROUTINE GY_U_UV_DEVICE(KKA,KKU,KL,PA,PDYY,PDZZ,PDZY,PGY_U_UV_DEVICE) ! ######################################################### ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN_DEVICE USE MODD_CONF ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDYY ! metric coefficient dyy REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZY ! metric coefficient dzy ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGY_U_UV_DEVICE ! result UV point ! REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE, ZTMP3_DEVICE ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- !$acc data present( PA, PDYY, PDZZ, PDZY, PGY_U_UV_DEVICE ) allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) allocate( ztmp3_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) !$acc data create( ztmp1_device, ztmp2_device, ztmp3_device ) ! !* 1. DEFINITION of GY_U_UV_DEVICE ! --------------------- ! IF (.NOT. LFLAT) THEN CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP1_DEVICE) CALL MXM_DEVICE(PDZZ,ZTMP2_DEVICE) !$acc kernels ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)/ZTMP2_DEVICE(:,:,:) !$acc end kernels CALL MYM_DEVICE(ZTMP3_DEVICE,ZTMP1_DEVICE) CALL MXM_DEVICE(PDZY,ZTMP2_DEVICE) !$acc kernels ZTMP3_DEVICE(:,:,:) = ZTMP1_DEVICE(:,:,:)*ZTMP2_DEVICE(:,:,:) !$acc end kernels CALL MZF_DEVICE(KKA,KKU,KL, ZTMP3_DEVICE,ZTMP2_DEVICE ) CALL DYM_DEVICE(PA,ZTMP1_DEVICE) CALL MXM_DEVICE(PDYY,ZTMP3_DEVICE) !$acc kernels PGY_U_UV_DEVICE(:,:,:)= ( ZTMP1_DEVICE(:,:,:) - ZTMP2_DEVICE(:,:,:) ) / ZTMP3_DEVICE(:,:,:) !$acc end kernels ELSE CALL DYM_DEVICE(PA,ZTMP1_DEVICE) CALL MXM_DEVICE(PDYY,ZTMP2_DEVICE) !$acc kernels PGY_U_UV_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:) !$acc end kernels END IF !$acc end data !$acc end data !---------------------------------------------------------------------------- ! END SUBROUTINE GY_U_UV_DEVICE #endif ! ! ! ####################################################### FUNCTION GZ_U_UW(KKA,KKU,KL,PA,PDZZ) RESULT(PGZ_U_UW) ! ####################################################### ! !!**** *GZ_U_UW - Cartesian Gradient operator: !! computes the gradient in the cartesian Z !! direction for a variable placed at the !! U point and the result is placed at !! the UW vorticity point. !! PURPOSE !! ------- ! The purpose of this function is to compute the discrete gradient ! along the Z cartesian direction for a field PA placed at the ! U point. The result is placed at the UW vorticity point. ! ! dzm(PA) ! PGZ_U_UW = ------ ! ____x ! d*zz ! !!** METHOD !! ------ !! The Chain rule of differencing is applied to variables expressed !! in the Gal-Chen & Somerville coordinates to obtain the gradient in !! the cartesian system !! !! EXTERNAL !! -------- !! MXM : Shuman functions (mean operators) !! DZM : Shuman functions (finite difference operators) !! !! IMPLICIT ARGUMENTS !! ------------------ !! NONE !! !! REFERENCE !! --------- !! Book2 of documentation of Meso-NH (GRAD_CAR operators) !! A Turbulence scheme for the Meso-NH model (Chapter 6) !! !! AUTHOR !! ------ !! Joan Cuxart *INM and Meteo-France* !! !! MODIFICATIONS !! ------------- !! Original 20/07/94 !------------------------------------------------------------------------- ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)) :: PGZ_U_UW ! result UW point ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- ! !* 1. DEFINITION of GZ_U_UW ! --------------------- ! PGZ_U_UW(:,:,:)= DZM(KKA,KKU,KL,PA) / MXM(PDZZ) ! !---------------------------------------------------------------------------- ! END FUNCTION GZ_U_UW ! ! #ifdef MNH_OPENACC ! ####################################################### SUBROUTINE GZ_U_UW_DEVICE(KKA,KKU,KL,PA,PDZZ,PGZ_U_UW_DEVICE) ! ####################################################### ! !* 0. DECLARATIONS ! ! USE MODI_SHUMAN_DEVICE ! IMPLICIT NONE ! ! !* 0.1 declarations of arguments and result ! INTEGER, INTENT(IN) :: KKA, KKU ! near ground and uppest atmosphere array indexes INTEGER, INTENT(IN) :: KL ! +1 if grid goes from ground to atmosphere top, -1 otherwise REAL, DIMENSION(:,:,:), INTENT(IN) :: PA ! variable at the U point REAL, DIMENSION(:,:,:), INTENT(IN) :: PDZZ ! metric coefficient dzz ! REAL, DIMENSION(SIZE(PA,1),SIZE(PA,2),SIZE(PA,3)), INTENT(OUT) :: PGZ_U_UW_DEVICE ! result UW point ! REAL, DIMENSION(:,:,:), allocatable :: ZTMP1_DEVICE, ZTMP2_DEVICE ! ! !* 0.2 declaration of local variables ! ! NONE ! !---------------------------------------------------------------------------- !$acc data present( PA, PDZZ, PGZ_U_UW_DEVICE ) allocate( ztmp1_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) allocate( ztmp2_device(size( pa, 1 ), size( pa, 2 ), size( pa, 3 ) ) ) !$acc data create( ztmp1_device, ztmp2_device ) ! !* 1. DEFINITION of GZ_U_UW_DEVICE ! --------------------- ! CALL DZM_DEVICE(KKA,KKU,KL,PA,ZTMP1_DEVICE) CALL MXM_DEVICE(PDZZ,ZTMP2_DEVICE) !$acc kernels PGZ_U_UW_DEVICE(:,:,:)= ZTMP1_DEVICE(:,:,:) / ZTMP2_DEVICE(:,:,:) !$acc end kernels !$acc end data !$acc end data !---------------------------------------------------------------------------- ! END SUBROUTINE GZ_U_UW_DEVICE #endif