!MNH_LIC Copyright 1994-2021 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_EOL_MAIN ! ####################### ! INTERFACE ! SUBROUTINE EOL_MAIN(KTCOUNT, PTSTEP, & PDXX, PDYY, PDZZ, & PRHODJ, PUT, PVT, PWT, & PRUS, PRVS, PRWS ) ! INTEGER, INTENT(IN) :: KTCOUNT ! iteration count REAL, INTENT(IN) :: PTSTEP ! timestep except ! REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ ! mesh size REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! dry Density * Jacobian REAL, DIMENSION(:,:,:), INTENT(IN) :: PUT, PVT, PWT ! wind speed variables ! REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PRUS, PRVS, PRWS ! Sources of Momentum ! END SUBROUTINE EOL_MAIN ! END INTERFACE ! END MODULE MODI_EOL_MAIN ! ! ################################################################### SUBROUTINE EOL_MAIN(KTCOUNT, PTSTEP, & PDXX, PDYY, PDZZ, & PRHODJ, PUT, PVT, PWT, & PRUS, PRVS, PRWS ) ! ################################################################### ! !!**** *EOL_MAIN * - !! !! PURPOSE !! ------- !! It is possible to include wind turbines parameterization in Meso-NH, !! and several models are available. EOL_MAIN is the main subroutine !! to compute the aerodynamics of the wind turbine, according to the !! model chosen. !! !!** METHOD !! ------ !! !! REFERENCE !! --------- !! !! !! AUTHOR !! ------ !! PA. Joulin *CNRM & IFPEN* !! !! MODIFICATIONS !! ------------- !! 21/10/20 Original !! !!--------------------------------------------------------------- ! ! !* 0. DECLARATIONS ! ------------ ! ! To work with wind turbines USE MODD_EOL_MAIN USE MODI_EOL_ADNR USE MODI_EOL_ALM USE MODI_EOL_SMEAR ! To play with MPI USE MODD_ARGSLIST_ll, ONLY: LIST_ll USE MODE_ll , ONLY: ADD3DFIELD_ll USE MODE_ll , ONLY: UPDATE_HALO_ll USE MODE_ll , ONLY: CLEANLIST_ll ! To use some toolkit USE MODI_SHUMAN , ONLY: MXF, MYF, MZF USE MODI_SHUMAN , ONLY: MXM, MYM, MZM ! use modd_budget, only: lbudget_u, lbudget_v, lbudget_w, NBUDGET_U, NBUDGET_V, NBUDGET_W, tbudgets use mode_budget, only: budget_store_init, budget_store_end ! ! IMPLICIT NONE ! !* 0.1 Declarations of dummy arguments : ! INTEGER, INTENT(IN) :: KTCOUNT ! iteration count REAL, INTENT(IN) :: PTSTEP ! timestep except REAL, DIMENSION(:,:,:), INTENT(IN) :: PDXX,PDYY,PDZZ ! mesh size REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! dry Density * Jacobian REAL, DIMENSION(:,:,:), INTENT(IN) :: PUT, PVT, PWT ! Wind speed REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PRUS, PRVS, PRWS ! Sources of Momentum ! ! !* 0.2 Declarations of local variables : ! ! Pointeurs and exchanges TYPE(LIST_ll), POINTER :: TZFIELDS_W_ll ! Field list of Wind for exchange TYPE(LIST_ll), POINTER :: TZFIELDS_F_ll ! Field list of aero Forces for exchange TYPE(LIST_ll), POINTER :: TZFIELDS_S_ll ! Field list of Smeared aero forces for exchange TYPE(LIST_ll), POINTER :: TZFIELDS_R_ll ! Field list of mnh foRces for exchange INTEGER :: IINFO ! Info integer INTEGER :: IKU ! Vertical size of the domain ! ! ABL REAL, DIMENSION(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)) :: ZUT_M, ZVT_M, ZWT_M ! Wind speed at mass point REAL, DIMENSION(SIZE(PUT,1),SIZE(PUT,2),SIZE(PUT,3)) :: ZRHO_M ! Air density at mass point ! ! !* 0.3 Implicit arguments !* From MODD_EOL_MAIN ! Aerodynamic forces in cartesian mesh !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFX_RG ! Along X in RG frame [F] !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFY_RG ! Along Y in RG frame [F] !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFZ_RG ! Along Z in RG frame [F] ! Smeared forces !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFX_SMR_RG ! Along X in RG frame [F] !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFY_SMR_RG ! Along Y in RG frame [F] !REAL, DIMENSION(:,:,:), ALLOCATABLE :: XFZ_SMR_RG ! ALong Z in RG frame [F] ! !* From NAM_EOL namelist !CHARACTER(LEN=4) :: CMETH_EOL ! Aerodynamic method !CHARACTER(LEN=4) :: CSMEAR ! Type of smearing ! ! !-------------------------------------------------------- ! !* 1. INITIALIZATIONS ! --------------- ! !* 1.1 Indices ! IKU = SIZE(PUT,3) ! !* 1.2 Pointers ! NULLIFY(TZFIELDS_W_ll) NULLIFY(TZFIELDS_F_ll) NULLIFY(TZFIELDS_S_ll) NULLIFY(TZFIELDS_R_ll) ! !* 1.3 Forces ! XFX_RG(:,:,:) = 0. XFY_RG(:,:,:) = 0. XFZ_RG(:,:,:) = 0. XFX_SMR_RG(:,:,:) = 0. XFY_SMR_RG(:,:,:) = 0. XFZ_SMR_RG(:,:,:) = 0. ! ! !----------------------------------------------------------------------- ! !* 2. COMPUTES VELOCITY COMPONENTS AND DENSITY AT MASS POINT ! ------------------------------------------------------ ! !* 2.1 Sharing the input ! CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PUT, 'EOL_MAIN::PUT') CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PWT, 'EOL_MAIN::PWT') CALL ADD3DFIELD_ll( TZFIELDS_W_ll,PVT, 'EOL_MAIN::PVT') CALL UPDATE_HALO_ll(TZFIELDS_W_ll,IINFO) CALL CLEANLIST_ll( TZFIELDS_W_ll) ! !* 2.2 Masss point evaluation ! ZUT_M(:,:,:) = MXF( PUT(:,:,:) ) ZVT_M(:,:,:) = MYF( PVT(:,:,:) ) ZWT_M(:,:,:) = MZF( PWT(:,:,:) ) ZRHO_M(:,:,:) = PRHODJ(:,:,:)/(PDXX(:,:,:)*PDYY(:,:,:)*PDZZ(:,:,:)) ! !* 2.3 Sharing the new wind ! CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZUT_M, 'EOL_MAIN::ZUT_M') CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZWT_M, 'EOL_MAIN::ZWT_M') CALL ADD3DFIELD_ll( TZFIELDS_W_ll,ZVT_M, 'EOL_MAIN::ZVT_M') CALL UPDATE_HALO_ll(TZFIELDS_W_ll,IINFO) CALL CLEANLIST_ll( TZFIELDS_W_ll) ! ! !-------------------------------------------------------- ! !* 3. COMPUTES AERODYNAMICS FORCES ! ---------------------------- ! !* 3.1 Model selection ! ! SELECT CASE(CMETH_EOL) ! CASE('ADNR') ! Actuator Disc Non-Rotating CALL EOL_ADNR(PDXX, PDYY, PDZZ, & ZRHO_M, & ZUT_M, & XFX_RG ) ! CASE('ALM') ! Actuator Line Method CALL EOL_ALM(KTCOUNT, PTSTEP, & PDXX, PDYY, PDZZ, & ZRHO_M, & ZUT_M, ZVT_M, ZWT_M, & XFX_RG, XFY_RG, XFZ_RG ) ! END SELECT ! !* 3.2 Sharing 3D field ! CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFX_RG, 'EOL_MAIN::XFX_RG' ) CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFY_RG, 'EOL_MAIN::XFY_RG' ) CALL ADD3DFIELD_ll( TZFIELDS_F_ll,XFZ_RG, 'EOL_MAIN::XFZ_RG' ) CALL UPDATE_HALO_ll(TZFIELDS_F_ll,IINFO) CALL CLEANLIST_ll( TZFIELDS_F_ll) ! ! !-------------------------------------------------------- ! !* 4. SMEARING THE FORCES ! ------------------- ! !* 4.1 Smearing technique selection ! SELECT CASE (CSMEAR) ! CASE( 'NULL' ) ! No smearing XFX_SMR_RG(:,:,:) = XFX_RG(:,:,:) XFY_SMR_RG(:,:,:) = XFY_RG(:,:,:) XFZ_SMR_RG(:,:,:) = XFZ_RG(:,:,:) ! CASE( '1LIN' ) ! Linear smearing CALL SMEAR_1LIN(XFX_RG, & XFX_SMR_RG) ! CASE( '3LIN' ) ! Linear smearing CALL SMEAR_3LIN(XFX_RG, & XFY_RG, & XFZ_RG, & XFX_SMR_RG,& XFY_SMR_RG,& XFZ_SMR_RG) ! END SELECT ! !* 4.2 Sharing 3D field ! CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFX_SMR_RG, 'EOL_MAIN::XFX_SMR_RG' ) CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFY_SMR_RG, 'EOL_MAIN::XFY_SMR_RG' ) CALL ADD3DFIELD_ll( TZFIELDS_S_ll,XFZ_SMR_RG, 'EOL_MAIN::XFZ_SMR_RG' ) CALL UPDATE_HALO_ll(TZFIELDS_S_ll,IINFO) CALL CLEANLIST_ll( TZFIELDS_S_ll) ! ! !------------------------------------------------------------------------------- ! !* 5. ADDING THE FORCES TO THE FIELD ! ------------------------------ ! !* 5.1 Adding them to flux points, rotor->wind ! if (lbudget_u) call Budget_store_init( tbudgets(NBUDGET_U), 'EOL', prus(:,:,:) ) if (lbudget_v) call Budget_store_init( tbudgets(NBUDGET_V), 'EOL', prvs(:,:,:) ) if (lbudget_w) call Budget_store_init( tbudgets(NBUDGET_W), 'EOL', prws(:,:,:) ) ! PRUS(:,:,:)=PRUS(:,:,:)-MXM(XFX_SMR_RG(:,:,:)) PRVS(:,:,:)=PRVS(:,:,:)-MYM(XFY_SMR_RG(:,:,:)) PRWS(:,:,:)=PRWS(:,:,:)-MZM(XFZ_SMR_RG(:,:,:)) ! if (lbudget_u) call Budget_store_end( tbudgets(NBUDGET_U), 'EOL', prus(:,:,:) ) if (lbudget_v) call Budget_store_end( tbudgets(NBUDGET_V), 'EOL', prvs(:,:,:) ) if (lbudget_w) call Budget_store_end( tbudgets(NBUDGET_W), 'EOL', prws(:,:,:) ) ! ! !* 5.2 Sharing the field ! CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRUS,'EOL_MAIN::PRUS' ) CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRVS,'EOL_MAIN::PRVS' ) CALL ADD3DFIELD_ll( TZFIELDS_R_ll,PRWS,'EOL_MAIN::PRWS' ) CALL UPDATE_HALO_ll(TZFIELDS_R_ll,IINFO) CALL CLEANLIST_ll( TZFIELDS_R_ll) ! END SUBROUTINE EOL_MAIN