!copyright (C) 2001 MSC-RPN COMM %%%CCC%%%
***S/P GWDFX95A - gravity wave drag flux (1995 formulation) ...
#include "phy_macros_f.h"
SUBROUTINE GWDFX95A (U,V,TH,TF,ENV,GC,S,SEXPK,SH,SHEXPK, 2
+ UTENDGW,VTENDGW,GRAV,RGAS,TAU,
2 ILEV,IL1,IL2,ILG,DAMPFAC,ENVELOP,LREF,
$ TAUFAC)
*
#include "impnone.cdk"
*
* LOGICAL SWITCHES TO CONTROL ROOF DRAG AND ENVELOP GW DRAG.
*
LOGICAL DAMPFAC, ENVELOP
*
REAL GRAV,RGAS,TAU,TAUFAC
*
INTEGER ILEV,ILG
REAL*8 U(ILG,ILEV), V(ILG,ILEV), TH(ILG,ILEV),
1 TF(ILG,ILEV), ENV(ILG), GC(ILG),
2 UTENDGW(ILG,ILEV), VTENDGW(ILG,ILEV)
*
* VERTICAL POSITIONNING ARRAYS.
*
REAL*8 S(ilg,ILEV), SEXPK(ilg,ILEV), SH(ilg,ILEV),
1 SHEXPK(ilg,ILEV)
*
*Author
* N.McFarlane - Flux formula, semi-implicit (1995 version)
*
*Revision
* 001 L. Lefaivre (mai 95) - adaptation des changements
* de code suggeres par N. McFarlane
* 002 P. Houtekamer (novembre 95) - Optimization
* and New physics interface; TAUFAC passed
* in argument
* 003 B. Dugas (June 2001) - Automatic arrays
* 004 B. Bilodeau (May 2002) - Correct VMODB bug and
* replace CVMGT by IF statements
*
*Object
* to calculate the tendencies on wind components due
* to gravity wave drag
*
*Arguments
*
* - Input/Output -
* U U component of wind as input
* U component of wind modified by the gravity wave
* drag as output
* V V component of wind as input
* V component of wind modified by the gravity wave
* drag as output
*
* - Input -
* TH temperature level means
* TF temperature
* ENV variance associated with unresolved orography
* GC land-sea mask (between 0(sea) and 1(land))
* S sigma levels
* SEXPK vertical positioning arrays; (full levels)
* SH intermediate levels
* SHEXPK vertical positioning arrays (half levels)
*
* - Output -
* UTENDGW gravity wave drag tendency on the U component of real
* wind
* VTENDGW gravity wave drag tendency on the V component of real
* wind
*
* - Input -
* GRAV gravitational constant
* RGAS gas constant
* TAU timestep times a factor: 1 for two time-level models
* 2 for three time-level models
* ILEV number of levels
* IL1 1st dimension of U,V,T to start calculation
* IL2 index on horizontal dimension to stop calculation
* ILG total horizontal dimension
* DAMPFAC .TRUE. for applying roof drag factor
* ENVELOP .TRUE. for gravity wave drag
* LREF number of tranche
* TAUFAC 1/(length scale)
*
* - Internally allocated work fields -
* BVFREQ B V frequency
* BVFREQG gathered relevant points of BVFREQ
* VELN the projection of the local wind on the reference wind.
* Negative or zero values are eliminated.
* UB U component unit vector of the reference level wind
* VB V component unit vector of the reference level
* wind(equivalenced to AMPBSQ)
* UBG gathered relevant points of UB
* VBG gathered relevant points of VB
* VMODB reference wind level
* VMODBG gathered relevant points of VMODBG
* DEPFAC dampening factor
* HEIGHT gathered relevant points of ENV
* AMPBSQ the V component of the reference level wind
* AMPDIF work space
* DENFAC DFAC*TENDFAC
* TFG gather relevant points of TF
*
* UTEND gravity wave drag tendency on UB
* VTEND gravity wave drag tendency on VB
* DGW equivalenced to TFG
* DGWG equivalenced to DEPFAC
* DRAG contains the points where GW calculations will be done,
* that is:
* A - if over land
* B - if bottom wind > VMIN
* C - if requested and enveloppe height >= HMIN
* SG gathered values of sigma coordinate (s)
* SHG gathered values of sh
*
* FRB work array
* FRMIN work array
* FRMAX work array
* DNSWTCH work array
* DENOFAC work array
* DEPFACR work array
*
**
*
*
************************************************************************
* AUTOMATIC WORK ARRAYS
************************************************************************
*
AUTOMATIC ( DRAG , INTEGER , (ILG ) )
*
AUTOMATIC ( BVFREQ , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( VELN , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( DEPFAC , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( UB , REAL*8 , (ILG ) )
AUTOMATIC ( VB , REAL*8 , (ILG ) )
AUTOMATIC ( VMODB , REAL*8 , (ILG ) )
AUTOMATIC ( UBG , REAL*8 , (ILG ) )
AUTOMATIC ( VBG , REAL*8 , (ILG ) )
AUTOMATIC ( VMODBG , REAL*8 , (ILG ) )
AUTOMATIC ( HEIGHT , REAL*8 , (ILG ) )
AUTOMATIC ( AMPBSQ , REAL*8 , (ILG ) )
AUTOMATIC ( AMPDIF , REAL*8 , (ILG ) )
AUTOMATIC ( DENFAC , REAL*8 , (ILG ) )
AUTOMATIC ( BVFREQG , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( TFG , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( UTEND , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( VTEND , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( DGW , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( DGWG , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( SG , REAL*8 , (ILG,ILEV) )
AUTOMATIC ( SHG , REAL*8 , (ILG,ILEV) )
*
AUTOMATIC ( FRB , REAL*8 , (ILG ) )
AUTOMATIC ( FRMIN , REAL*8 , (ILG ) )
AUTOMATIC ( FRMAX , REAL*8 , (ILG ) )
AUTOMATIC ( DNSWTCH , REAL*8 , (ILG ) )
AUTOMATIC ( DENOFAC , REAL*8 , (ILG ) )
AUTOMATIC ( DEPFACR , REAL*8 , (ILG ) )
*
************************************************************************
*
*
INTEGER IL1,IL2,LREF,ILEVM,LEN,LREFM,LENGW
INTEGER I,L,JYES,JNO
REAL*8 VMIN,V0,HMIN,ZERO,UN,ETA,
1 DAMPSCA,DTTDSF,DTTDZL,RATIO,
2 SIGB,BVFB,HSQMAX,HSQ,HSCAL,DFAC,WIND,BVF,
3 DFLXP,DENOM,TENDFAC,DFLXM,DAMPRF,VELMOD,FRN1
*
integer ii
C
C * CONSTANTS VALUES DEFINED IN DATA STATEMENT ARE :
C
C * VMIN = MIMINUM WIND IN THE DIRECTION OF REFERENCE LEVEL
C * WIND BEFORE WE CONSIDER BREAKING TO HAVE OCCURED.
C * DAMPSCAL = DAMPING TIME FOR GW DRAG IN SECONDS.
C * HMIN = MIMINUM ENVELOPE HEIGHT REQUIRED TO PRODUCE GW DRAG.
C * V0 = VALUE OF WIND THAT APPROXIMATES ZERO.
C
DATA VMIN / 2.0D0 /, V0 / 1.D-30 /, HMIN / 10.0D0 /,
2 ZERO / 0.0D0 /, UN / 1.0D0 /, DAMPSCA/ 6.5D+6 /
C
C-----------------------------------------------------------------------
ILEVM = ILEV - 1
LEN = IL2 - IL1 + 1
LREFM = LREF-1
C
C * VMOD IS THE REFERENCE LEVEL WIND AND ( UB, VB)
C * ARE IT'S UNIT VECTOR COMPONENTS.
C
DO 100 I=IL1,IL2
UB(I) = U(I,LREFM)
VB(I) = V(I,LREFM)
VMODB(I) = SQRT (UB(I)**2 + VB(I)**2)
VMODB(I) = MAX( VMODB(I), UN )
UB(I) = UB(I)/VMODB(I)
VB(I) = VB(I)/VMODB(I)
100 CONTINUE
C
C * DRAG CONTAINS THE POINTS WHERE GW CALCULATIONS WILL BE DONE,
C * THAT IS (A- IF OVER LAND, B- IF BOTTOM WIND > VMIN, C- IF WE
C * ASK FOR IT AND C- IF ENVELOPPE HEIGHT >= HMIN )
C
JYES = 0
JNO = LEN + 1
*VDIR NODEP
DO 110 I=IL1,IL2
IF (GC(I).EQ.-1 .AND. VMODB(I).GT.VMIN .AND.
1 ENVELOP .AND. ENV(I) .GE.HMIN ) THEN
JYES = JYES + 1
DRAG(JYES) = I
ELSE
JNO = JNO - 1
DRAG(JNO) = I
ENDIF
110 CONTINUE
C
C * INITIALISE NECESSARY ARRAYS.
C
LENGW = JYES
IF (LENGW.GT.0) THEN
DO 120 L=1,ILEV
DO 120 I=1,LEN
DGWG(I,L) = ZERO
UTEND(I,L) = ZERO
VTEND(I,L) = ZERO
120 CONTINUE
ELSE
DO 130 L=1,ILEV
DO 130 I=IL1,IL2
DGW(I,L) = ZERO
UTENDGW(I,L) = ZERO
VTENDGW(I,L) = ZERO
130 CONTINUE
GOTO 300
ENDIF
C
C * CALCULATE B V FREQUENCY EVERYWHERE.
C
DO 140 L=2,ILEV
DO 140 I=IL1,IL2
DTTDSF =(TH(I,L)/SHEXPK(i,L)-TH(I,L-1)/SHEXPK(i,L-1))
1 /(SH(i,L)-SH(i,L-1))
DTTDSF = MIN( DTTDSF, -5./S(i,L) )
DTTDZL = -DTTDSF*S(i,L)*GRAV/(RGAS*TF(I,L))
BVFREQ(I,L) = SQRT (GRAV*DTTDZL*SEXPK(i,L)/TF(I,L))
140 CONTINUE
DO 150 I=IL1,IL2
BVFREQ(I,1) = BVFREQ(I,2)
150 CONTINUE
C
C * GATHER RELEVANT POINTS OF UB, VB, VMODB, BVFREQ, TF,
C * AND ENV INTO UBG, VBG, BFREQG, TFG AND HEIGHT.
C
* CALL GATHER(LEN, UBG, UB(IL1), DRAG)
* CALL GATHER(LEN, VBG, VB(IL1), DRAG)
* CALL GATHER(LEN, VMODBG, VMODB(IL1),DRAG)
* CALL GATHER(LEN, HEIGHT, ENV(IL1), DRAG)
*
do 155 i=1,len
ii = drag(i) + il1 - 1
ubg (i) = ub (ii)
vbg (i) = vb (ii)
vmodbg(i) = vmodb(ii)
height(i) = env (ii)
155 continue
C
DO 160 L=1,ILEV
* CALL GATHER(LEN, BVFREQG(1,L), BVFREQ(IL1,L),DRAG)
* CALL GATHER(LEN, TFG(1,L), TF(IL1,L), DRAG)
*
do 165 i=1,len
ii = drag(i) + il1 - 1
bvfreqg(i,l) = bvfreq(ii,l)
tfg (i,l) = tf (ii,l)
sg (i,l) = s (ii,l)
shg (i,l) = sh (ii,l)
165 continue
*
160 CONTINUE
C
C * SMOOTH B V FREQ.
C
DO 170 L=2,ILEV
* RATIO = 5.*LOG( S(L)/S(L-1) )
DO 170 I=1,LENGW
RATIO = 5.*LOG( Sg(i,L)/Sg(i,L-1) )
BVFREQG(I,L) = (BVFREQG(I,L-1) + RATIO*BVFREQG(I,L))
1 /(1.+RATIO)
170 CONTINUE
C
C * VELN IS THE PROJECTION OF THE LOCAL WIND ON
C * THE REFERENCE WIND. NEGATIVE OR NUL VALUES
C * ARE ELEMINATED. AMPDIFF IS ONLY USED AS
C * TEMPORARY HOLDING SPACE. GATHER THE RESULT.
C
DO 190 L=1,ILEV
DO 180 I=IL1,IL2
AMPDIF(I)=MAX( U(I,L)*UB(I)+V(I,L)*VB(I), V0 )
180 CONTINUE
* CALL GATHER (LEN, VELN(1,L), AMPDIF(IL1), DRAG)
do 185 i=1,len
ii = drag(i) + il1 - 1
veln (i,l) = ampdif(ii)
185 continue
*
190 CONTINUE
C
C * CALCULATE EFFECTIVE SQUARE LAUNCHING
C * HEIGHT, REFERENCE B V FREQUENCY, ETC.
C
* SIGB = SH(LREFM)
DO 200 I=1,LENGW
BVFB = BVFREQG(I,LREFM)
HSQMAX= (VMODBG(I)/BVFB)**2
HSQ=HEIGHT(I)*HEIGHT(I)
HSCAL=RGAS*TFG(I,LREFM)/GRAV
SIGB = SHg(i,LREFM)
DFAC=BVFB*SIGB*VMODBG(I)/HSCAL
C* AMPBSQ(I)=DFAC
C* HITESQ(I)=HSQ
AMPBSQ(I)=DFAC*HSQ
FRB(I) = (BVFB**2)*HSQ/(VMODBG(I)**2)
DEPFAC(I,LREF) = TAUFAC*DFAC*HSQ
DEPFACR(I) = DEPFAC(I,LREF)
DENOFAC(I) = 0.5
DNSWTCH(I) = 1.
FRMIN(I) = FRB(I)
FRMAX(I) = 0.
200 CONTINUE
C
C
C * CALCULATE TERMS FROM THE BOTTOM-UP.
C
DO 240 L=LREFM,1,-1
DO 240 I=1,LENGW
WIND=VELN(I,L)
BVF=BVFREQG(I,L)
HSCAL=RGAS*TFG(I,L)/GRAV
C* HSQMAX=0.5*(WIND/BVF)**2
DFAC=BVF*Sg(i,L)*WIND/HSCAL
C* RATIO=AMPBSQ(I)/DFAC
C* HSQ=MIN(RATIO*HITESQ(I),HSQMAX)
C* HITESQ(I)=HSQ
C* AMPBSQ(I)=DFAC
C* DEPFAC(I,L) =TAUFAC*DFAC*HSQ
FRN1 = (BVF**2)*AMPBSQ(I)/(DFAC*(WIND**2))
IF(FRN1.LE.FRB(I)) THEN
FRMIN(I) = FRN1
FRB(I) = FRN1
DEPFAC(I,L) = DEPFACR(I)
DENOFAC(I) = DENOFAC(I) + (1.-DNSWTCH(I))*FRMAX(I)
DNSWTCH(I) = 1.
ELSE
DENOFAC(I) = DENOFAC(I) - DNSWTCH(I)*FRMIN(I)
DNSWTCH(I) = 0.
FRMAX(I) = FRN1
FRB(I) = FRN1
DEPFAC(I,L) = 0.5*DEPFAC(I,LREF)/(DENOFAC(I)+FRN1)
DEPFACR(I) = DEPFAC(I,L)
ENDIF
240 CONTINUE
C
C
C
C * CALCULATE GW TENDENCIES.
C
C * TOP LAYER AND BOTTOM LAYER *
DO 260 I=1,LENGW
DEPFAC(I,LREF)=DEPFAC(I,LREFM)
WIND= VELN(I,1)
DFLXP=DEPFAC(I,2)-DEPFAC(I,1)
IF (DFLXP.GT.1.D-10) THEN
ETA = UN
ELSE
ETA = ZERO
ENDIF
DFAC=3.*TAU*DEPFAC(I,1)/WIND
DENOM=2.*SHg(i,1)+DFAC*eta
TENDFAC=DFLXP/DENOM
DENFAC(I)=DFAC*TENDFAC
UTEND(I,1)=-TENDFAC*UBG(I)
VTEND(I,1)=-TENDFAC*VBG(I)
UTEND(I,LREF)=ZERO
VTEND(I,LREF)=ZERO
260 CONTINUE
DO 270 L=2,LREFM
DO 270 I=1,LENGW
WIND= VELN(I,L)
DFLXP=DEPFAC(I,L+1)-DEPFAC(I,L)
DFLXM=DEPFAC(I,L)-DEPFAC(I,L-1)
IF (DFLXP+DFLXM.GT.1.D-10) THEN
ETA = UN
ELSE
ETA = ZERO
ENDIF
DFAC=3.*TAU*DEPFAC(I,L)/WIND
DENOM=2.*(SHg(i,L)-SHg(i,L-1))+DFAC*eta
TENDFAC=(DFLXP+DFLXM+DENFAC(I)*eta)/DENOM
DENFAC(I)=DFAC*TENDFAC
UTEND(I,L) = -TENDFAC*UBG(I)
VTEND(I,L) = -TENDFAC*VBG(I)
270 CONTINUE
C * ROOF DRAG FACTOR *
DO 275 I=1,LENGW
TENDFAC=SQRT(UTEND(I,1)**2 + VTEND(I,1)**2)
DGWG(I,1)=DAMPSCA*TENDFAC*VELN(I,1)
275 CONTINUE
C
C * SCATTER THESE VALUES OF DGWG AND (U-V)TEND
C * INTO DGW AND (U-V)TENDGW.
C
DO 280 L=1,ILEV
* CALL SCATTER (LEN, UTENDGW(IL1,L), DRAG, UTEND(1,L))
* CALL SCATTER (LEN, VTENDGW(IL1,L), DRAG, VTEND(1,L))
* CALL SCATTER (LEN, DGW(IL1,L), DRAG, DGWG(1,L))
*
do 285 i=1,len
ii = drag(i) + il1 - 1
utendgw(ii,l) = utend(i,l)
vtendgw(ii,l) = vtend(i,l)
dgw (ii,l) = dgwg (i,l)
285 continue
*
280 CONTINUE
C
C * APPLY GW DRAG ON U AND V.
C
DO 290 L=1,ILEV
DO 290 I=IL1,IL2
U(I,L) = U(I,L) + TAU*UTENDGW(I,L)
V(I,L) = V(I,L) + TAU*VTENDGW(I,L)
290 CONTINUE
C
C * APPLY ROOF DRAG IF THE BACKGROUND GW DRAG IS SMALL ENOUGH.
C
300 CONTINUE
C
IF (DAMPFAC) THEN
DAMPRF = UN
ELSE
DAMPRF = ZERO
ENDIF
C
DO 310 I=IL1,IL2
VELMOD = MAX( SQRT( U(I,1)**2 + V(I,1)**2 ), UN )
DFAC = MAX( UN-DGW(I,1)/(VELMOD*VELMOD), ZERO )
1 * DAMPRF / DAMPSCA
DENOM = UN + TAU*DFAC
U(I,1) = U(I,1)/DENOM
V(I,1) = V(I,1)/DENOM
UTENDGW(I,1) = UTENDGW(I,1) - DFAC*U(I,1)
VTENDGW(I,1) = VTENDGW(I,1) - DFAC*V(I,1)
310 CONTINUE
C
RETURN
C
C-----------------------------------------------------------------------
END