From 71e0d56f80b8c031173e12a6364aa447d76d2b1f Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Thu, 1 Aug 2019 10:13:11 +0200 Subject: [PATCH] Philippe 01/08/2019: OpenACC: implementation of slow_terms --- src/MNH/slow_terms.f90 | 228 +++++++++++++++++++++++++++++++---------- 1 file changed, 175 insertions(+), 53 deletions(-) diff --git a/src/MNH/slow_terms.f90 b/src/MNH/slow_terms.f90 index 3699b5af8..5291742d1 100644 --- a/src/MNH/slow_terms.f90 +++ b/src/MNH/slow_terms.f90 @@ -156,12 +156,16 @@ END MODULE MODI_SLOW_TERMS !* 0. DECLARATIONS ! ------------ ! -USE MODD_PARAMETERS -USE MODD_CLOUDPAR -USE MODD_CST -USE MODD_CONF -USE MODD_BUDGET -! +USE MODD_BUDGET, only: LBUDGET_RC, LBUDGET_RR, LBUDGET_RV, LBUDGET_TH +USE MODD_CLOUDPAR, only: XC1RC, XC2RC, XC1RE, XC2RE, XCEXRA, XCEXRE, XCEXRS, XCEXVT, XCRA, XCRS, XDIVA, XTHCO +USE MODD_CST, only: XALPW, XBETAW, XGAMW, XCL, XCPD, XCPV, XLVTT, XMD, XMV, XP00, XRD, XRHOLW, XRV, XTT +USE MODD_PARAMETERS, only: JPVEXT + +use mode_mppdb + +#ifdef MNH_BITREP +use modi_bitrep +#endif USE MODI_BUDGET ! IMPLICIT NONE @@ -207,14 +211,49 @@ INTEGER :: IKE ! the microphysical sources have to be computed ! REAL :: ZTSPLITR ! Small time step for rain sedimentation ! -REAL, DIMENSION(SIZE(PZZ,1),SIZE(PZZ,2),SIZE(PZZ,3)) & - :: ZT,ZW,ZW1,ZW2,ZW3,ZEXNT,ZDZZ ! Work arrays -LOGICAL, DIMENSION(SIZE(PRHODJ,1),SIZE(PRHODJ,2),SIZE(PRHODJ,3)) :: G3D +REAL, DIMENSION(:,:,:), ALLOCATABLE :: ZT,ZW,ZW1,ZW2,ZW3,ZEXNT,ZDZZ ! Work arrays +LOGICAL, DIMENSION(:,:,:), ALLOCATABLE :: G3D ! -INTEGER , DIMENSION(:), ALLOCATABLE :: I1,I2 ! index for packed array INTEGER :: JI,JJ,IC,JL ! loop control for packed array -! + +!$acc declare present( PZZ, PRHODJ, PRHODREF, PCLDFR, PTHT, PRVT, PRCT, PRRT, & +!$acc & PPABST, PTHS, PRVS, PRCS, PRRS, PINPRR, PINPRR3D, PEVAP3D ) + +!$acc declare create( ZT, ZW, ZW1, ZW2, ZW3, ZEXNT, ZDZZ, G3D ) + +!$acc declare copyin( XC1RC, XC2RC, XC1RE, XC2RE, XCEXRA, XCEXRE, XCEXRS, XCEXVT, XCRA, XCRS, XDIVA, XTHCO, & +!$acc & XALPW, XBETAW, XGAMW, XCL, XCPD, XCPV, XLVTT, XMD, XMV, XP00, XRD, XRHOLW, XRV, XTT) + !------------------------------------------------------------------------------- +IF (MPPDB_INITIALIZED) THEN + !Check all IN arrays + CALL MPPDB_CHECK(PZZ, "SLOW_TERMS beg:PZZ") + CALL MPPDB_CHECK(PRHODJ, "SLOW_TERMS beg:PRHODJ") + CALL MPPDB_CHECK(PRHODREF,"SLOW_TERMS beg:PRHODREF") + CALL MPPDB_CHECK(PCLDFR, "SLOW_TERMS beg:PCLDFR") + CALL MPPDB_CHECK(PTHT, "SLOW_TERMS beg:PTHT") + CALL MPPDB_CHECK(PRVT, "SLOW_TERMS beg:PRVT") + CALL MPPDB_CHECK(PRCT, "SLOW_TERMS beg:PRCT") + CALL MPPDB_CHECK(PRRT, "SLOW_TERMS begPRRT:") + CALL MPPDB_CHECK(PPABST, "SLOW_TERMS beg:PPABST") + !Check all INOUT arrays + CALL MPPDB_CHECK(PTHS, "SLOW_TERMS beg:PTHS") + CALL MPPDB_CHECK(PRVS, "SLOW_TERMS beg:PRVS") + CALL MPPDB_CHECK(PRCS, "SLOW_TERMS beg:PRCS") + CALL MPPDB_CHECK(PRRS, "SLOW_TERMS beg:PRRS") + CALL MPPDB_CHECK(PINPRR, "SLOW_TERMS beg:PINPRR") + CALL MPPDB_CHECK(PINPRR3D,"SLOW_TERMS beg:PINPRR3D") + CALL MPPDB_CHECK(PEVAP3D, "SLOW_TERMS beg:PEVAP3D") +END IF + +allocate( zt ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zw ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zw1 ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zw2 ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zw3 ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zexnt( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( zdzz ( size(pzz,1), size(pzz,2), size(pzz,3) ) ) +allocate( g3d ( size(prhodj,1), size(prhodj,2), size(prhodj,3) ) ) ! !* 1. COMPUTE THE LOOP BOUNDS AND EXNER FUNCTION ! ------------------------------------------ @@ -222,10 +261,10 @@ INTEGER :: JI,JJ,IC,JL ! loop control for packed ar IKB=1+JPVEXT IKE=SIZE(PZZ,3) - JPVEXT ! compute Delta z at the mass point +!$acc kernels DO JK = 1,IKE ZDZZ(:,:,JK) = PZZ(:,:,JK+1)-PZZ(:,:,JK) END DO - ! !------------------------------------------------------------------------------- ! @@ -241,30 +280,50 @@ ZW1(:,:,:) = PRRS(:,:,:) * PTSTEP ZW2(:,:,:) = 0. ZW3(:,:,:) = 0. ! +#ifndef _OPENACC G3D(:,:,:)=.FALSE. DO JK=IKE,1,-1 WHERE( ZW1(:,:,JK)>0. .OR. G3D(:,:,JK+1) ) G3D(:,:,JK)=.TRUE. END WHERE END DO +#else +g3d(:, :, : ) = .false. +do jk = ike, 1, -1 + do jj = 1, size(pzz,2) + do ji = 1, size(pzz,1) + if ( zw1(ji, jj, jk ) >0. .or. g3d(ji, jj, jk+1 ) ) then + g3d(ji, jj, jk ) = .true. + end if + end do + end do +end do +#endif ! WHERE (G3D(:,:,:)) +#ifndef MNH_BITREP ZW3(:,:,:) = PRHODREF(:,:,:) ** (XCEXRS-XCEXVT) +#else + ZW3(:,:,:) = BR_POW( PRHODREF(:,:,:), XCEXRS - XCEXVT ) +#endif END WHERE ! WHERE (ZW1(:,:,IKE+1)>0.) +#ifndef MNH_BITREP ZW2(:,:,IKE+1) = XCRS & * ZW1(:,:,IKE+1) ** XCEXRS & * PRHODREF(:,:,IKE+1) ** (XCEXRS-XCEXVT) +#else + ZW2(:,:,IKE+1) = XCRS & + * BR_POW( ZW1(:,:,IKE+1), XCEXRS ) & + * BR_POW( PRHODREF(:,:,IKE+1), XCEXRS - XCEXVT ) +#endif END WHERE ! ! !* 2.2 small time step integration ! --------------------------- ! -ALLOCATE (I1(SIZE(ZW1))) -ALLOCATE (I2(SIZE(ZW1))) -! DO JN=1,KSPLITR ! !* 2.2.1 test where computations should be made and pack arrays @@ -272,37 +331,31 @@ DO JN=1,KSPLITR ! DO JK=IKE,IKB,-1 - ! - IC = 0 +!$acc loop collapse(2) independent DO JJ = 1,SIZE( ZW1,2) DO JI = 1,SIZE( ZW1,1) IF ( ( ZW1(JI,JJ,JK+1)>0. ) .AND. ( ZW1(JI,JJ,JK)>0. ) ) THEN -!!$ IF ( (ZW1(JI,JJ,JK)+ZW1(JI,JJ,JK+1)>0.) ) THEN - IC = IC +1 - I1(IC) = JI - I2(IC) = JJ - ENDIF - ENDDO - ENDDO ! !* 2.2.2 compute the rain flux ! --------------------- ! ! - DO JL=1,IC - ZW2(I1(JL),I2(JL),JK) = XCRS & - * ZW1(I1(JL),I2(JL),JK) ** XCEXRS & - * ZW3(I1(JL),I2(JL),JK) +#ifndef MNH_BITREP + ZW2(JI,JJ,JK) = XCRS * ( ZW1(JI,JJ,JK) ** XCEXRS ) * ZW3(JI,JJ,JK) +#else + ZW2(JI,JJ,JK) = XCRS * BR_POW( ZW1(JI,JJ,JK), XCEXRS ) * ZW3(JI,JJ,JK) +#endif ! ! !* 2.2.3 update the rain tendency with the small timestep ! ------------------------------------------------ -! - ZW1(I1(JL),I2(JL),JK) = ZW1(I1(JL),I2(JL),JK) + ZTSPLITR * & - ( ZW2(I1(JL),I2(JL),JK+1)-ZW2(I1(JL),I2(JL),JK) ) / & - ( ZDZZ(I1(JL),I2(JL),JK) * PRHODREF(I1(JL),I2(JL),JK) ) - ENDDO ! + ZW1(JI,JJ,JK) = ZW1(JI,JJ,JK) + ZTSPLITR * & + ( ZW2(JI,JJ,JK+1)-ZW2(JI,JJ,JK) ) / & + ( ZDZZ(JI,JJ,JK) * PRHODREF(JI,JJ,JK) ) + END IF + END DO + ENDDO ENDDO ! !* 2.2.4 compute the explicit accumulated precipitations @@ -315,16 +368,17 @@ DO JN=1,KSPLITR ! END DO ! -DEALLOCATE (I1) -DEALLOCATE (I2) -! !* 2.4 update the rain tendency ! PRRS(:,:,:) = ZW1(:,:,:) / PTSTEP -! +!$acc end kernels +! !* 2.5 budget storage ! -IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'SEDI_BU_RRR') +IF (LBUDGET_RR) THEN +!$acc update self(PRRS) + CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'SEDI_BU_RRR') +END IF ! !------------------------------------------------------------------------------- ! @@ -335,21 +389,35 @@ IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'SEDI_BU_RRR') ! !* 3.1 compute the accretion and update the tendencies ! -WHERE ( (PRCT(:,:,:)>0.0) .AND. (PRRT(:,:,:)>0.0) & - .AND. (PRCS(:,:,:)>0.0) ) +!$acc kernels +G3D(:,:,:) = PRCT(:,:,:)>0.0 .AND. PRRT(:,:,:)>0.0 .AND. PRCS(:,:,:)>0.0 +WHERE ( G3D(:,:,:) ) +#ifndef MNH_BITREP ZW(:,:,:) = XCRA * PRCT(:,:,:) & * PRRT(:,:,:) ** XCEXRA & * PRHODREF(:,:,:) ** (XCEXRA - XCEXVT) +#else + ZW(:,:,:) = XCRA * PRCT(:,:,:) & + * BR_POW( PRRT(:,:,:), XCEXRA ) & + * BR_POW( PRHODREF(:,:,:), XCEXRA - XCEXVT ) +#endif ZW(:,:,:) = MIN ( ZW(:,:,:) , PRCS(:,:,:) ) ! PRCS(:,:,:) = PRCS(:,:,:) - ZW(:,:,:) PRRS(:,:,:) = PRRS(:,:,:) + ZW(:,:,:) END WHERE +!$acc end kernels ! !* 3.2 budget storage ! -IF (LBUDGET_RC) CALL BUDGET (PRCS(:,:,:)*PRHODJ(:,:,:),7,'ACCR_BU_RRC') -IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'ACCR_BU_RRR') +IF (LBUDGET_RC) THEN +!$acc update self(PRCS) + CALL BUDGET (PRCS(:,:,:)*PRHODJ(:,:,:),7,'ACCR_BU_RRC') +END IF +IF (LBUDGET_RR) THEN +!$acc update self(PRRS) + CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'ACCR_BU_RRR') +END IF ! !------------------------------------------------------------------------------- ! @@ -360,15 +428,18 @@ IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'ACCR_BU_RRR') ! !* 4.1 compute the autoconversion and update the tendencies ! +!$acc kernels IF ( HSUBG_AUCV == 'CLFR' ) THEN - WHERE ( (PRCT(:,:,:)>0.0) .AND. (PRCS(:,:,:)>0.0) .AND. (PCLDFR(:,:,:)>0.0) ) + G3D(:,:,:) = PRCT(:,:,:)>0.0 .AND. PRCS(:,:,:)>0.0 .AND. PCLDFR(:,:,:)>0.0 + WHERE ( G3D(:,:,:) ) ZW(:,:,:) = XC1RC * MAX(PRCT(:,:,:) /(PCLDFR(:,:,:)) - XC2RC / PRHODREF(:,:,:),0.) ZW(:,:,:) = MIN ( (ZW(:,:,:)* PCLDFR(:,:,:)), PRCS(:,:,:) ) PRCS(:,:,:) = PRCS(:,:,:) - ZW(:,:,:) PRRS(:,:,:) = PRRS(:,:,:) + ZW(:,:,:) END WHERE ELSE - WHERE ( (PRCT(:,:,:)>0.0) .AND. (PRCS(:,:,:)>0.0) ) + G3D(:,:,:) = PRCT(:,:,:)>0.0 .AND. PRCS(:,:,:)>0.0 + WHERE ( G3D(:,:,:) ) ZW(:,:,:) = XC1RC * MAX ( PRCT(:,:,:) - XC2RC / PRHODREF(:,:,:), 0. ) ZW(:,:,:) = MIN ( ZW(:,:,:) , PRCS(:,:,:) ) ! @@ -376,23 +447,36 @@ ELSE PRRS(:,:,:) = PRRS(:,:,:) + ZW(:,:,:) END WHERE END IF +!$acc end kernels ! !* 4.2 budget storage ! -IF (LBUDGET_RC) CALL BUDGET (PRCS(:,:,:)*PRHODJ(:,:,:),7,'AUTO_BU_RRC') -IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'AUTO_BU_RRR') +IF (LBUDGET_RC) THEN +!$acc update self(PRCS) + CALL BUDGET (PRCS(:,:,:)*PRHODJ(:,:,:),7,'AUTO_BU_RRC') +END IF +IF (LBUDGET_RR) THEN +!$acc update self(PRRS) + CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'AUTO_BU_RRR') +END IF ! !------------------------------------------------------------------------------- ! !* 5. COMPUTES THE RAIN EVAPORATION (RE) SOURCE ! ----------------------------------------- ! +!$acc kernels PEVAP3D(:,:,:)=0. -WHERE ( (PRRT(:,:,:)>0.0) .AND. (PRCT(:,:,:)==0.0) ) +G3D(:,:,:) = PRRT(:,:,:)>0.0 .AND. PRCT(:,:,:)==0.0 +WHERE ( G3D(:,:,:) ) ! !* 5.1 compute the Exner function ! +#ifndef MNH_BITREP ZEXNT(:,:,:) = (PPABST(:,:,:)/XP00)**(XRD/XCPD) +#else + ZEXNT(:,:,:) = BR_POW( PPABST(:,:,:)/XP00, XRD/XCPD ) +#endif ! !* 5.2 compute the temperature ! @@ -400,7 +484,11 @@ WHERE ( (PRRT(:,:,:)>0.0) .AND. (PRCT(:,:,:)==0.0) ) ! !* 5.3 compute the saturation vapor pressure ! +#ifndef MNH_BITREP ZW1(:,:,:) = EXP( XALPW - XBETAW/ZT(:,:,:) - XGAMW*ALOG(ZT(:,:,:) ) ) +#else + ZW1(:,:,:) = BR_EXP( XALPW - XBETAW/ZT(:,:,:) - XGAMW*BR_LOG(ZT(:,:,:) ) ) +#endif ! !* 5.4 compute the saturation mixing ratio ! @@ -413,14 +501,25 @@ WHERE ( (PRRT(:,:,:)>0.0) .AND. (PRCT(:,:,:)==0.0) ) ! !* 5.6 compute the source ! - ZW(:,:,:) = MAX( 1. - PRVT(:,:,:)/ZW2(:,:,:) , 0.0 ) * & +#ifndef MNH_BITREP + ZW(:,:,:) = MAX( 1. - PRVT(:,:,:)/ZW2(:,:,:) , 0.0 ) * & ( XC1RE * SQRT( PRRT(:,:,:)/PRHODREF(:,:,:) ) & +XC2RE * PRRT(:,:,:)**XCEXRE & * PRHODREF(:,:,:)**(XCEXRE-0.5*XCEXVT-1.) & ) / & ( XRV*ZT(:,:,:)/(ZW1(:,:,:)*XDIVA) & +ZW3(:,:,:) ** 2 / (XTHCO*XRV*ZT(:,:,:)**2) & - ) + ) +#else + ZW(:,:,:) = MAX( 1. - PRVT(:,:,:)/ZW2(:,:,:) , 0.0 ) * & + ( XC1RE * BR_POW( PRRT(:,:,:)/PRHODREF(:,:,:), 0.5 ) & + +XC2RE * BR_POW( PRRT(:,:,:), XCEXRE ) & + * BR_POW( PRHODREF(:,:,:), XCEXRE-0.5*XCEXVT-1. ) & + ) / & + ( XRV*ZT(:,:,:)/(ZW1(:,:,:)*XDIVA) & + +ZW3(:,:,:)*ZW3(:,:,:) / (XTHCO*XRV*ZT(:,:,:)*ZT(:,:,:)) & + ) +#endif ZW(:,:,:) = MIN ( ZW(:,:,:) , PRRS(:,:,:) ) ! !* 5.7 update the total tendencies @@ -433,22 +532,45 @@ WHERE ( (PRRT(:,:,:)>0.0) .AND. (PRCT(:,:,:)==0.0) ) + XCL * (PRCT(:,:,:) + PRRT(:,:,:)) ) ) PEVAP3D(:,:,:)=ZW(:,:,:) END WHERE +!$acc end kernels ! !* 5.8 budget storage ! -IF (LBUDGET_RV) CALL BUDGET (PRVS(:,:,:)*PRHODJ(:,:,:),6,'REVA_BU_RRV') -IF (LBUDGET_RR) CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'REVA_BU_RRR') -IF (LBUDGET_TH) CALL BUDGET (PTHS(:,:,:)*PRHODJ(:,:,:),4,'REVA_BU_RTH') +IF (LBUDGET_RV) THEN +!$acc update self(PRVS) + CALL BUDGET (PRVS(:,:,:)*PRHODJ(:,:,:),6,'REVA_BU_RRV') +END IF +IF (LBUDGET_RR) THEN +!$acc update self(PRRS) + CALL BUDGET (PRRS(:,:,:)*PRHODJ(:,:,:),8,'REVA_BU_RRR') +END IF +IF (LBUDGET_TH) THEN +!$acc update self(PTHS) + CALL BUDGET (PTHS(:,:,:)*PRHODJ(:,:,:),4,'REVA_BU_RTH') +END IF ! !------------------------------------------------------------------------------- ! !* 6. REMOVES NON-PHYSICAL LOW VALUES ! ------------------------------- ! -WHERE (PRRS(:,:,:)<1.E-16) +!$acc kernels +G3D(:,:,:) = PRRS(:,:,:) < 1.E-16 +WHERE ( G3D(:,:,:) ) PRRS(:,:,:)=0. END WHERE +!$acc end kernels !------------------------------------------------------------------------------- ! +IF (MPPDB_INITIALIZED) THEN + !Check all INOUT arrays + CALL MPPDB_CHECK(PTHS, "SLOW_TERMS end:PTHS") + CALL MPPDB_CHECK(PRVS, "SLOW_TERMS end:PRVS") + CALL MPPDB_CHECK(PRCS, "SLOW_TERMS end:PRCS") + CALL MPPDB_CHECK(PRRS, "SLOW_TERMS end:PRRS") + CALL MPPDB_CHECK(PINPRR, "SLOW_TERMS end:PINPRR") + CALL MPPDB_CHECK(PINPRR3D,"SLOW_TERMS end:PINPRR3D") + CALL MPPDB_CHECK(PEVAP3D, "SLOW_TERMS end:PEVAP3D") +END IF ! END SUBROUTINE SLOW_TERMS -- GitLab