!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer,
! version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer
!version 3 or (at your option) any later version that should be found at:
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software;
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec),
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
!*** S/P HINES_EXTRO
SUBROUTINE hines_extro ( nlons, nlevs, nazmth, & 1,11
& drag_u, drag_v, heat, diffco, flux_u, flux_v, &
& vel_u, vel_v, bvfreq, density, visc_mol, alt, &
& rmswind, anis, k_alpha, sigsqmcw, &
& m_alpha, mmin_alpha, sigma_t, sigmatm, &
& lev2, lorms, iheatcal)
USE mo_gwspectrum
, ONLY: kstar, m_min, &
& naz, slope, f1, f2, f3, f5, f6, &
& icutoff, alt_cutoff, smco, nsmax
USE mo_doctor
, ONLY: nout
IMPLICIT NONE
INTEGER :: nlons, nlevs, nazmth, lev2
REAL*8 :: drag_u(nlons,nlevs), drag_v(nlons,nlevs)
REAL*8 :: heat(nlons,nlevs), diffco(nlons,nlevs)
REAL*8 :: flux_u(nlons,nlevs), flux_v(nlons,nlevs)
REAL*8 :: flux(nlons,nlevs,nazmth)
REAL*8 :: vel_u(nlons,nlevs), vel_v(nlons,nlevs)
REAL*8 :: bvfreq(nlons,nlevs), density(nlons,nlevs)
REAL*8 :: visc_mol(nlons,nlevs), alt(nlons,nlevs)
REAL*8 :: rmswind(nlons), bvfb(nlons), densb(nlons)
REAL*8 :: anis(nlons,nazmth)
REAL*8 :: sigma_t(nlons,nlevs), sigsqmcw(nlons,nlevs,nazmth)
REAL*8 :: sigma_alpha(nlons,nlevs,nazmth), sigmatm(nlons,nlevs)
REAL*8 :: m_alpha(nlons,nlevs,nazmth), v_alpha(nlons,nlevs,nazmth)
REAL*8 :: ak_alpha(nlons,nazmth), k_alpha(nlons,nazmth)
REAL*8 :: mmin_alpha(nlons,nazmth)
REAL*8 :: smoothr1(nlons,nlevs), smoothr2(nlons,nlevs)
LOGICAL :: lorms(nlons), losigma_t(nlons,nlevs)
!
!Authors
!
! aug. 13/95 - c. mclandress
! sept. /95 - n. mcfarlane
! 1995- 2002 - e. manzini
!
!Revision
!
!Modules
!
! mo_gwspectrum
! mo_doctor
!
!Object
! main routine for hines' "extrowave" gravity wave parameterization based
! on hines' doppler spread theory. this routine calculates zonal
! and meridional components of gravity wave drag, heating rates
! and diffusion coefficient on a longitude by altitude grid.
! no "mythical" lower boundary region calculation is made.
!
! - Output -
! drag_u zonal component of gravity wave drag (m/s^2).
! drag_v meridional component of gravity wave drag (m/s^2).
! heat gravity wave heating (k/sec).
! diffco diffusion coefficient (m^2/sec)
! flux_u zonal component of vertical momentum flux (pascals)
! flux_v meridional component of vertical momentum flux (pascals)
!
! - Input -
! vel_u background zonal wind component (m/s).
! vel_v background meridional wind component (m/s).
! bvfreq background brunt vassala frequency (radians/sec).
! densit background density (kg/m^3)
! visc_mol molecular viscosity (m^2/s)
! alt altitude of momentum, density, buoyancy levels (m)
! (note: levels ordered so that alt(i,1) > alt(i,2), etc.)
! rmswind root mean square gravity wave wind at lowest level (m/s).
! anis anisotropy factor (sum over azimuths is one)
! lorms .true. for drag computation (column selector)
! k_alpha horizontal wavenumber of each azimuth (1/m).
! lev2 index of last level (eg bottom) for drag calculation
! (i.e., lev1 < lev2 <= nlevs).
! nlons number of longitudes.
! nlevs number of vertical levels.
! nazmth azimuthal array dimension (nazmth >= naz).
!
! - ouput diagnostics -
! m_alpha cutoff vertical wavenumber (1/m).
! mmin_alpha minimum value of cutoff wavenumber.
! sigma_t total rms horizontal wind (m/s).
!
! - work arrays -
! v_alpha wind component at each azimuth (m/s) and if iheatcal=1
! holds vertical derivative of cutoff wavenumber.
! sigma_alpha total rms wind in each azimuth (m/s).
! ak_alpha spectral amplitude factor at each azimuth
! (i.e.,{ajkj}) in m^4/s^2.
! densb background density at bottom level.
! bvfb buoyancy frequency at bottom level and
! work array for icutoff = 1.
!
! losigma_t .true. for total sigma not zero
!
! internal variables.
!
INTEGER :: i, n, l, lev1, il1, il2, iprint, iheatcal
!-----------------------------------------------------------------------
!
! range of longitude index:
il1 = 1
il2 = nlons
lev1=1 ! top level index
iprint = 0 ! * iprint = 1 to print out various arrays.
!
! buoyancy and density at bottom level.
!
DO i = il1,il2
bvfb(i) = bvfreq(i,lev2)
densb(i) = density(i,lev2)
END DO
!
! initialize some variables
!
DO n = 1,naz
DO l=lev1,lev2
DO i=il1,il2
m_alpha(i,l,n) = m_min
END DO
END DO
END DO
!
! compute azimuthal wind components from zonal and meridional winds.
!
CALL hines_wind
( v_alpha, &
& vel_u, vel_v, naz, &
& il1, il2, lev1, lev2, nlons, nlevs, nazmth )
!
! calculate cutoff vertical wavenumber and velocity variances.
!
CALL hines_wavnum
( m_alpha, sigma_t, sigma_alpha, ak_alpha, &
& mmin_alpha, losigma_t, &
& v_alpha, visc_mol, density, densb, &
& bvfreq, bvfb, rmswind, anis, lorms, &
& sigsqmcw, sigmatm, &
& il1, il2, lev1, lev2, nlons, nlevs, nazmth)
!
! smooth cutoff wavenumbers and total rms velocity in the vertical
! direction nsmax times, using flux_u as temporary work array.
!
IF (nsmax.GT.0) THEN
DO n = 1,naz
DO l=lev1,lev2
DO i=il1,il2
smoothr1(i,l) = m_alpha(i,l,n)
END DO
END DO
CALL vert_smooth
(smoothr1,smoothr2, smco, nsmax, &
& il1, il2, lev1, lev2, nlons, nlevs )
DO l=lev1,lev2
DO i=il1,il2
m_alpha(i,l,n) = smoothr1(i,l)
END DO
END DO
END DO
CALL vert_smooth
( sigma_t, smoothr2, smco, nsmax, &
& il1, il2, lev1, lev2, nlons, nlevs )
END IF
!
! calculate zonal and meridional components of the
! momentum flux and drag.
!
CALL hines_flux
( flux_u, flux_v, flux, drag_u, drag_v, &
& alt, density, densb, &
& m_alpha, ak_alpha, k_alpha, &
& m_min, slope, naz, &
& il1, il2, lev1, lev2, nlons, nlevs, nazmth, &
& lorms )
!
! cutoff drag above alt_cutoff, using bvfb as temporary work array.
!
IF (icutoff.EQ.1) THEN
CALL hines_exp
( drag_u, bvfb, alt, alt_cutoff, &
& il1, il2, lev1, lev2, nlons, nlevs )
CALL hines_exp
( drag_v, bvfb, alt, alt_cutoff, &
& il1, il2, lev1, lev2, nlons, nlevs )
END IF
!
! print out various arrays for diagnostic purposes.
!
IF (iprint.EQ.1) THEN
CALL hines_print
( flux_u, flux_v, drag_u, drag_v, alt, &
& sigma_t, sigma_alpha, v_alpha, m_alpha, &
& 1, 1, il1, il2, lev1, lev2, &
& naz, nlons, nlevs, nazmth)
END IF
!
! if not calculating heating rate and diffusion coefficient then finished.
!
IF (iheatcal.NE.1) RETURN
!
!
! heating rate and diffusion coefficient.
!
write(6,'(A)')"+++++++++++++++++++++++++++++++++++++++++++++"
write(6,'(A)')"+ YOU ARE NOT SUPPOSED TO CALL HINES_HEAT +"
write(6,'(A)')"+ THE MODEL WILL STOP +"
write(6,'(A)')"+++++++++++++++++++++++++++++++++++++++++++++"
CALL QQEXIT(1)
!
CALL hines_heat
( heat, diffco, &
& alt, bvfreq, density, sigma_t, sigma_alpha, &
& flux, visc_mol, kstar, f1, f2, f3, f5, f6, &
& naz, il1, il2, lev1, lev2, nlons, nlevs, &
& nazmth, losigma_t )
!
! finished.
!
RETURN
!-----------------------------------------------------------------------
END SUBROUTINE hines_extro