LMDZ
hines_gwd.F90
Go to the documentation of this file.
1 
2 ! $Id: hines_gwd.F90 2346 2015-08-21 15:13:46Z emillour $
3 
4 SUBROUTINE hines_gwd(nlon, nlev, dtime, paphm1x, papm1x, rlat, tx, ux, vx, &
5  zustrhi, zvstrhi, d_t_hin, d_u_hin, d_v_hin)
6 
7  ! ########################################################################
8  ! Parametrization of the momentum flux deposition due to a broad band
9  ! spectrum of gravity waves, following Hines (1997a,b), as coded by
10  ! McLANDRESS (1995). Modified by McFARLANE and MANZINI (1995-1997)
11  ! MAECHAM model stand alone version
12  ! ########################################################################
13 
14 
15  USE dimphy
16  IMPLICIT NONE
17 
18  include "YOEGWD.h"
19  include "YOMCST.h"
20 
21  INTEGER nazmth
22  parameter(nazmth=8)
23 
24  ! INPUT ARGUMENTS.
25  ! ----- ----------
26 
27  ! - 2D
28  ! PAPHM1 : HALF LEVEL PRESSURE (T-DT)
29  ! PAPM1 : FULL LEVEL PRESSURE (T-DT)
30  ! PTM1 : TEMPERATURE (T-DT)
31  ! PUM1 : ZONAL WIND (T-DT)
32  ! PVM1 : MERIDIONAL WIND (T-DT)
33 
34 
35  ! REFERENCE.
36  ! ----------
37  ! SEE MODEL DOCUMENTATION
38 
39  ! AUTHOR.
40  ! -------
41 
42  ! N. MCFARLANE DKRZ-HAMBURG MAY 1995
43  ! STAND ALONE E. MANZINI MPI-HAMBURG FEBRUARY 1997
44 
45  ! BASED ON A COMBINATION OF THE OROGRAPHIC SCHEME BY N.MCFARLANE 1987
46  ! AND THE HINES SCHEME AS CODED BY C. MCLANDRESS 1995.
47 
48 
49 
50  ! ym INTEGER KLEVM1
51 
52  REAL paphm1(klon, klev+1), papm1(klon, klev)
53  REAL ptm1(klon, klev), pum1(klon, klev), pvm1(klon, klev)
54  REAL prflux(klon)
55  ! 1
56  ! 1
57  ! 1
58  REAL rlat(klon), coslat(klon)
59 
60  REAL th(klon, klev), utendgw(klon, klev), vtendgw(klon, klev), &
61  pressg(klon), uhs(klon, klev), vhs(klon, klev), zpr(klon)
62 
63  ! * VERTICAL POSITIONING ARRAYS.
64 
65  REAL sgj(klon, klev), shj(klon, klev), shxkj(klon, klev), dsgj(klon, klev)
66 
67  ! * LOGICAL SWITCHES TO CONTROL ROOF DRAG, ENVELOP GW DRAG AND
68  ! * HINES' DOPPLER SPREADING EXTROWAVE GW DRAG.
69  ! * LOZPR IS TRUE FOR ZPR ENHANCEMENT
70 
71 
72  ! * WORK ARRAYS.
73 
74  REAL m_alpha(klon, klev, nazmth), v_alpha(klon, klev, nazmth), &
75  sigma_alpha(klon, klev, nazmth), sigsqh_alpha(klon, klev, nazmth), &
76  drag_u(klon, klev), drag_v(klon, klev), flux_u(klon, klev), &
77  flux_v(klon, klev), heat(klon, klev), diffco(klon, klev), &
78  bvfreq(klon, klev), density(klon, klev), sigma_t(klon, klev), &
79  visc_mol(klon, klev), alt(klon, klev), sigsqmcw(klon, klev, nazmth), &
80  sigmatm(klon, klev), ak_alpha(klon, nazmth), k_alpha(klon, nazmth), &
81  mmin_alpha(klon, nazmth), i_alpha(klon, nazmth), rmswind(klon), &
82  bvfbot(klon), densbot(klon)
83  REAL smoothr1(klon, klev), smoothr2(klon, klev)
84  REAL sigalpmc(klon, klev, nazmth)
85  REAL f2mod(klon, klev)
86 
87  ! * THES ARE THE INPUT PARAMETERS FOR HINES ROUTINE AND
88  ! * ARE SPECIFIED IN ROUTINE HINES_SETUP. SINCE THIS IS CALLED
89  ! * ONLY AT FIRST CALL TO THIS ROUTINE THESE VARIABLES MUST BE SAVED
90  ! * FOR USE AT SUBSEQUENT CALLS. THIS CAN BE AVOIDED BY CALLING
91  ! * HINES_SETUP IN MAIN PROGRAM AND PASSING THE PARAMETERS AS
92  ! * SUBROUTINE ARGUEMENTS.
93 
94 
95  REAL rmscon
96  INTEGER nmessg, iprint, ilrms
97  INTEGER ifl
98 
99  INTEGER naz, icutoff, nsmax, iheatcal
100  REAL slope, f1, f2, f3, f5, f6, kstar(klon), alt_cutoff, smco
101 
102  ! PROVIDED AS INPUT
103 
104  INTEGER nlon, nlev
105 
106  REAL dtime
107  REAL paphm1x(nlon, nlev+1), papm1x(nlon, nlev)
108  REAL ux(nlon, nlev), vx(nlon, nlev), tx(nlon, nlev)
109 
110  ! VARIABLES FOR OUTPUT
111 
112 
113  REAL d_t_hin(nlon, nlev), d_u_hin(nlon, nlev), d_v_hin(nlon, nlev)
114  REAL zustrhi(nlon), zvstrhi(nlon)
115 
116 
117  ! * LOGICAL SWITCHES TO CONTROL PRECIP ENHANCEMENT AND
118  ! * HINES' DOPPLER SPREADING EXTROWAVE GW DRAG.
119  ! * LOZPR IS TRUE FOR ZPR ENHANCEMENT
120 
121  LOGICAL lozpr, lorms(klon)
122 
123  ! LOCAL PARAMETERS TO MAKE THINGS WORK (TEMPORARY VARIABLE)
124 
125  REAL rhoh2o, zpcons, rgocp, zlat, dttdsf, ratio, hscal
126  INTEGER i, j, l, jl, jk, le, lref, lrefp, levbot
127 
128  ! DATA PARAMETERS NEEDED, EXPLAINED LATER
129 
130  REAL v0, vmin, dmpscal, taufac, hmin, apibt, cpart, fcrit
131  REAL pcrit, pcons
132  INTEGER iplev, ierror
133 
134 
135 
136  ! PRINT *,' IT IS STARTED HINES GOING ON...'
137 
138 
139 
140 
141  ! * COMPUTATIONAL CONSTANTS.
142  ! ------------- ----------
143 
144 
145  d_t_hin(:, :) = 0.
146 
147  rhoh2o = 1000.
148  zpcons = (1000.*86400.)/rhoh2o
149  ! ym KLEVM1=KLEV-1
150 
151 
152  DO jl = kidia, kfdia
153  paphm1(jl, 1) = paphm1x(jl, klev+1)
154  DO jk = 1, klev
155  le = klev + 1 - jk
156  paphm1(jl, jk+1) = paphm1x(jl, le)
157  papm1(jl, jk) = papm1x(jl, le)
158  ptm1(jl, jk) = tx(jl, le)
159  pum1(jl, jk) = ux(jl, le)
160  pvm1(jl, jk) = vx(jl, le)
161  END DO
162  END DO
163 
164  ! Define constants and arrays needed for the ccc/mam gwd scheme
165  ! *Constants:
166 
167  rgocp = rd/rcpd
168  lrefp = klev - 1
169  lref = klev - 2
170  ! 1
171  ! 1 *Arrays
172  ! 1
173  DO jk = 1, klev
174  DO jl = kidia, kfdia
175  shj(jl, jk) = papm1(jl, jk)/paphm1(jl, klev+1)
176  sgj(jl, jk) = papm1(jl, jk)/paphm1(jl, klev+1)
177  dsgj(jl, jk) = (paphm1(jl,jk+1)-paphm1(jl,jk))/paphm1(jl, klev+1)
178  shxkj(jl, jk) = (papm1(jl,jk)/paphm1(jl,klev+1))**rgocp
179  th(jl, jk) = ptm1(jl, jk)
180  END DO
181  END DO
182 
183  ! C
184  DO jl = kidia, kfdia
185  pressg(jl) = paphm1(jl, klev+1)
186  END DO
187 
188 
189  DO jl = kidia, kfdia
190  prflux(jl) = 0.0
191  zpr(jl) = zpcons*prflux(jl)
192  zlat = (rlat(jl)/180.)*rpi
193  coslat(jl) = cos(zlat)
194  END DO
195 
196  ! /#########################################################################
197  ! /
198  ! /
199 
200  ! * AUG. 14/95 - C. MCLANDRESS.
201  ! * SEP. 95 N. MCFARLANE.
202 
203  ! * THIS ROUTINE CALCULATES THE HORIZONTAL WIND TENDENCIES
204  ! * DUE TO MCFARLANE'S OROGRAPHIC GW DRAG SCHEME, HINES'
205  ! * DOPPLER SPREAD SCHEME FOR "EXTROWAVES" AND ADDS ON
206  ! * ROOF DRAG. IT IS BASED ON THE ROUTINE GWDFLX8.
207 
208  ! * LREFP IS THE INDEX OF THE MODEL LEVEL BELOW THE REFERENCE LEVEL
209  ! * I/O ARRAYS PASSED FROM MAIN.
210  ! * (PRESSG = SURFACE PRESSURE)
211 
212 
213 
214 
215  ! * CONSTANTS VALUES DEFINED IN DATA STATEMENT ARE :
216  ! * VMIN = MIMINUM WIND IN THE DIRECTION OF REFERENCE LEVEL
217  ! * WIND BEFORE WE CONSIDER BREAKING TO HAVE OCCURED.
218  ! * DMPSCAL = DAMPING TIME FOR GW DRAG IN SECONDS.
219  ! * TAUFAC = 1/(LENGTH SCALE).
220  ! * HMIN = MIMINUM ENVELOPE HEIGHT REQUIRED TO PRODUCE GW DRAG.
221  ! * V0 = VALUE OF WIND THAT APPROXIMATES ZERO.
222 
223 
224  DATA vmin/5.0/, v0/1.e-10/, taufac/5.e-6/, hmin/40000./, dmpscal/6.5e+6/, &
225  apibt/1.5708/, cpart/0.7/, fcrit/1./
226 
227  ! * HINES EXTROWAVE GWD CONSTANTS DEFINED IN DATA STATEMENT ARE:
228  ! * RMSCON = ROOT MEAN SQUARE GRAVITY WAVE WIND AT LOWEST LEVEL (M/S).
229  ! * NMESSG = UNIT NUMBER FOR PRINTED MESSAGES.
230  ! * IPRINT = 1 TO DO PRINT OUT SOME HINES ARRAYS.
231  ! * IFL = FIRST CALL FLAG TO HINES_SETUP ("SAVE" IT)
232  ! * PCRIT = CRITICAL VALUE OF ZPR (MM/D)
233  ! * IPLEV = LEVEL OF APPLICATION OF PRCIT
234  ! * PCONS = FACTOR OF ZPR ENHANCEMENT
235 
236 
237  DATA pcrit/5./, pcons/4.75/
238 
239  iplev = lrefp - 1
240 
241  DATA rmscon/1.00/iprint/2/, nmessg/6/
242  DATA ifl/0/
243 
244  lozpr = .false.
245 
246  ! -----------------------------------------------------------------------
247 
248 
249 
250  ! * SET ERROR FLAG
251 
252  ierror = 0
253 
254  ! * SPECIFY VARIOUS PARAMETERS FOR HINES ROUTINE AT VERY FIRST CALL.
255  ! * (NOTE THAT ARRAY K_ALPHA IS SPECIFIED SO MAKE SURE THAT
256  ! * IT IS NOT OVERWRITTEN LATER ON).
257 
258  CALL hines_setup(naz, slope, f1, f2, f3, f5, f6, kstar, icutoff, &
259  alt_cutoff, smco, nsmax, iheatcal, k_alpha, ierror, nmessg, klon, nazmth, &
260  coslat)
261  IF (ierror/=0) GO TO 999
262 
263  ! * START GWD CALCULATIONS.
264 
265  lref = lrefp - 1
266 
267 
268  DO j = 1, nazmth
269  DO l = 1, klev
270  DO i = kidia, klon
271  sigsqmcw(i, l, j) = 0.
272  END DO
273  END DO
274  END DO
275 
276 
277 
278  ! * INITIALIZE NECESSARY ARRAYS.
279 
280  DO l = 1, klev
281  DO i = kidia, kfdia
282  utendgw(i, l) = 0.
283  vtendgw(i, l) = 0.
284 
285  uhs(i, l) = 0.
286  vhs(i, l) = 0.
287 
288  END DO
289  END DO
290 
291  ! * IF USING HINES SCHEME THEN CALCULATE B V FREQUENCY AT ALL POINTS
292  ! * AND SMOOTH BVFREQ.
293 
294  DO l = 2, klev
295  DO i = kidia, kfdia
296  dttdsf = (th(i,l)/shxkj(i,l)-th(i,l-1)/shxkj(i,l-1))/ &
297  (shj(i,l)-shj(i,l-1))
298  dttdsf = min(dttdsf, -5./sgj(i,l))
299  bvfreq(i, l) = sqrt(-dttdsf*sgj(i,l)*(sgj(i,l)**rgocp)/rd)*rg/ptm1(i, l &
300  )
301  END DO
302  END DO
303  DO l = 1, klev
304  DO i = kidia, kfdia
305  IF (l==1) THEN
306  bvfreq(i, l) = bvfreq(i, l+1)
307  END IF
308  IF (l>1) THEN
309  ratio = 5.*log(sgj(i,l)/sgj(i,l-1))
310  bvfreq(i, l) = (bvfreq(i,l-1)+ratio*bvfreq(i,l))/(1.+ratio)
311  END IF
312  END DO
313  END DO
314 
315  ! * CALCULATE GW DRAG DUE TO HINES' EXTROWAVES
316  ! * SET MOLECULAR VISCOSITY TO A VERY SMALL VALUE.
317  ! * IF THE MODEL TOP IS GREATER THAN 100 KM THEN THE ACTUAL
318  ! * VISCOSITY COEFFICIENT COULD BE SPECIFIED HERE.
319 
320  DO l = 1, klev
321  DO i = kidia, kfdia
322  visc_mol(i, l) = 1.5e-5
323  drag_u(i, l) = 0.
324  drag_v(i, l) = 0.
325  flux_u(i, l) = 0.
326  flux_v(i, l) = 0.
327  heat(i, l) = 0.
328  diffco(i, l) = 0.
329  END DO
330  END DO
331 
332  ! * ALTITUDE AND DENSITY AT BOTTOM.
333 
334  DO i = kidia, kfdia
335  hscal = rd*ptm1(i, klev)/rg
336  density(i, klev) = sgj(i, klev)*pressg(i)/(rg*hscal)
337  alt(i, klev) = 0.
338  END DO
339 
340  ! * ALTITUDE AND DENSITY AT REMAINING LEVELS.
341 
342  DO l = klev - 1, 1, -1
343  DO i = kidia, kfdia
344  hscal = rd*ptm1(i, l)/rg
345  alt(i, l) = alt(i, l+1) + hscal*dsgj(i, l)/sgj(i, l)
346  density(i, l) = sgj(i, l)*pressg(i)/(rg*hscal)
347  END DO
348  END DO
349 
350 
351  ! * INITIALIZE SWITCHES FOR HINES GWD CALCULATION
352 
353  ilrms = 0
354 
355  DO i = kidia, kfdia
356  lorms(i) = .false.
357  END DO
358 
359 
360  ! * DEFILE BOTTOM LAUNCH LEVEL
361 
362  levbot = iplev
363 
364  ! * BACKGROUND WIND MINUS VALUE AT BOTTOM LAUNCH LEVEL.
365 
366  DO l = 1, levbot
367  DO i = kidia, kfdia
368  uhs(i, l) = pum1(i, l) - pum1(i, levbot)
369  vhs(i, l) = pvm1(i, l) - pvm1(i, levbot)
370  END DO
371  END DO
372 
373  ! * SPECIFY ROOT MEAN SQUARE WIND AT BOTTOM LAUNCH LEVEL.
374 
375  DO i = kidia, kfdia
376  rmswind(i) = rmscon
377  END DO
378 
379  IF (lozpr) THEN
380  DO i = kidia, kfdia
381  IF (zpr(i)>pcrit) THEN
382  rmswind(i) = rmscon + ((zpr(i)-pcrit)/zpr(i))*pcons
383  END IF
384  END DO
385  END IF
386 
387  DO i = kidia, kfdia
388  IF (rmswind(i)>0.0) THEN
389  ilrms = ilrms + 1
390  lorms(i) = .true.
391  END IF
392  END DO
393 
394  ! * CALCULATE GWD (NOTE THAT DIFFUSION COEFFICIENT AND
395  ! * HEATING RATE ONLY CALCULATED IF IHEATCAL = 1).
396 
397  IF (ilrms>0) THEN
398 
399  CALL hines_extro0(drag_u, drag_v, heat, diffco, flux_u, flux_v, uhs, vhs, &
400  bvfreq, density, visc_mol, alt, rmswind, k_alpha, m_alpha, v_alpha, &
401  sigma_alpha, sigsqh_alpha, ak_alpha, mmin_alpha, i_alpha, sigma_t, &
402  densbot, bvfbot, 1, iheatcal, icutoff, iprint, nsmax, smco, alt_cutoff, &
403  kstar, slope, f1, f2, f3, f5, f6, naz, sigsqmcw, sigmatm, kidia, klon, &
404  1, levbot, klon, klev, nazmth, lorms, smoothr1, smoothr2, sigalpmc, &
405  f2mod)
406 
407  ! * ADD ON HINES' GWD TENDENCIES TO OROGRAPHIC TENDENCIES AND
408  ! * APPLY HINES' GW DRAG ON (UROW,VROW) WORK ARRAYS.
409 
410  DO l = 1, klev
411  DO i = kidia, kfdia
412  utendgw(i, l) = utendgw(i, l) + drag_u(i, l)
413  vtendgw(i, l) = vtendgw(i, l) + drag_v(i, l)
414  END DO
415  END DO
416 
417 
418  ! * END OF HINES CALCULATIONS.
419 
420  END IF
421 
422  ! -----------------------------------------------------------------------
423 
424  DO jl = kidia, kfdia
425  zustrhi(jl) = flux_u(jl, 1)
426  zvstrhi(jl) = flux_v(jl, 1)
427  DO jk = 1, klev
428  le = klev - jk + 1
429  d_u_hin(jl, jk) = utendgw(jl, le)*dtime
430  d_v_hin(jl, jk) = vtendgw(jl, le)*dtime
431  END DO
432  END DO
433 
434  ! PRINT *,'UTENDGW:',UTENDGW
435 
436  ! PRINT *,' HINES HAS BEEN COMPLETED (LONG ISNT IT...)'
437 
438  RETURN
439 999 CONTINUE
440 
441  ! * IF ERROR DETECTED THEN ABORT.
442 
443  WRITE (nmessg, 6000)
444  WRITE (nmessg, 6010) ierror
445 6000 FORMAT (/' EXECUTION ABORTED IN GWDOREXV')
446 6010 FORMAT (' ERROR FLAG =', i4)
447 
448 
449  RETURN
450 END SUBROUTINE hines_gwd
451 ! /
452 ! /
453 
454 
455 SUBROUTINE hines_extro0(drag_u, drag_v, heat, diffco, flux_u, flux_v, vel_u, &
456  vel_v, bvfreq, density, visc_mol, alt, rmswind, k_alpha, m_alpha, &
457  v_alpha, sigma_alpha, sigsqh_alpha, ak_alpha, mmin_alpha, i_alpha, &
458  sigma_t, densb, bvfb, iorder, iheatcal, icutoff, iprint, nsmax, smco, &
459  alt_cutoff, kstar, slope, f1, f2, f3, f5, f6, naz, sigsqmcw, sigmatm, &
460  il1, il2, lev1, lev2, nlons, nlevs, nazmth, lorms, smoothr1, smoothr2, &
461  sigalpmc, f2mod)
463  IMPLICIT NONE
464 
465  ! Main routine for Hines' "extrowave" gravity wave parameterization based
466  ! on Hines' Doppler spread theory. This routine calculates zonal
467  ! and meridional components of gravity wave drag, heating rates
468  ! and diffusion coefficient on a longitude by altitude grid.
469  ! No "mythical" lower boundary region calculation is made so it
470  ! is assumed that lowest level winds are weak (i.e, approximately zero).
471 
472  ! Aug. 13/95 - C. McLandress
473  ! SEPT. /95 - N.McFarlane
474 
475  ! Modifications:
476 
477  ! Output arguements:
478 
479  ! * DRAG_U = zonal component of gravity wave drag (m/s^2).
480  ! * DRAG_V = meridional component of gravity wave drag (m/s^2).
481  ! * HEAT = gravity wave heating (K/sec).
482  ! * DIFFCO = diffusion coefficient (m^2/sec)
483  ! * FLUX_U = zonal component of vertical momentum flux (Pascals)
484  ! * FLUX_V = meridional component of vertical momentum flux (Pascals)
485 
486  ! Input arguements:
487 
488  ! * VEL_U = background zonal wind component (m/s).
489  ! * VEL_V = background meridional wind component (m/s).
490  ! * BVFREQ = background Brunt Vassala frequency (radians/sec).
491  ! * DENSITY = background density (kg/m^3)
492  ! * VISC_MOL = molecular viscosity (m^2/s)
493  ! * ALT = altitude of momentum, density, buoyancy levels (m)
494  ! * (NOTE: levels ordered so that ALT(I,1) > ALT(I,2), etc.)
495  ! * RMSWIND = root mean square gravity wave wind at lowest level (m/s).
496  ! * K_ALPHA = horizontal wavenumber of each azimuth (1/m).
497  ! * IORDER = 1 means vertical levels are indexed from top down
498  ! * (i.e., highest level indexed 1 and lowest level NLEVS);
499  ! * .NE. 1 highest level is index NLEVS.
500  ! * IHEATCAL = 1 to calculate heating rates and diffusion coefficient.
501  ! * IPRINT = 1 to print out various arrays.
502  ! * ICUTOFF = 1 to exponentially damp GWD, heating and diffusion
503  ! * arrays above ALT_CUTOFF; otherwise arrays not modified.
504  ! * ALT_CUTOFF = altitude in meters above which exponential decay applied.
505  ! * SMCO = smoothing factor used to smooth cutoff vertical
506  ! * wavenumbers and total rms winds in vertical direction
507  ! * before calculating drag or heating
508  ! * (SMCO >= 1 ==> 1:SMCO:1 stencil used).
509  ! * NSMAX = number of times smoother applied ( >= 1),
510  ! * = 0 means no smoothing performed.
511  ! * KSTAR = typical gravity wave horizontal wavenumber (1/m).
512  ! * SLOPE = slope of incident vertical wavenumber spectrum
513  ! * (SLOPE must equal 1., 1.5 or 2.).
514  ! * F1 to F6 = Hines's fudge factors (F4 not needed since used for
515  ! * vertical flux of vertical momentum).
516  ! * NAZ = actual number of horizontal azimuths used.
517  ! * IL1 = first longitudinal index to use (IL1 >= 1).
518  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
519  ! * LEV1 = index of first level for drag calculation.
520  ! * LEV2 = index of last level for drag calculation
521  ! * (i.e., LEV1 < LEV2 <= NLEVS).
522  ! * NLONS = number of longitudes.
523  ! * NLEVS = number of vertical levels.
524  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
525 
526  ! Work arrays.
527 
528  ! * M_ALPHA = cutoff vertical wavenumber (1/m).
529  ! * V_ALPHA = wind component at each azimuth (m/s) and if IHEATCAL=1
530  ! * holds vertical derivative of cutoff wavenumber.
531  ! * SIGMA_ALPHA = total rms wind in each azimuth (m/s).
532  ! * SIGSQH_ALPHA = portion of wind variance from waves having wave
533  ! * normals in the alpha azimuth (m/s).
534  ! * SIGMA_T = total rms horizontal wind (m/s).
535  ! * AK_ALPHA = spectral amplitude factor at each azimuth
536  ! * (i.e.,{AjKj}) in m^4/s^2.
537  ! * I_ALPHA = Hines' integral.
538  ! * MMIN_ALPHA = minimum value of cutoff wavenumber.
539  ! * DENSB = background density at bottom level.
540  ! * BVFB = buoyancy frequency at bottom level and
541  ! * work array for ICUTOFF = 1.
542 
543  ! * LORMS = .TRUE. for drag computation
544 
545  INTEGER naz, nlons, nlevs, nazmth, il1, il2, lev1, lev2
546  INTEGER icutoff, nsmax, iorder, iheatcal, iprint
547  REAL kstar(nlons), f1, f2, f3, f5, f6, slope
548  REAL alt_cutoff, smco
549  REAL drag_u(nlons, nlevs), drag_v(nlons, nlevs)
550  REAL heat(nlons, nlevs), diffco(nlons, nlevs)
551  REAL flux_u(nlons, nlevs), flux_v(nlons, nlevs)
552  REAL vel_u(nlons, nlevs), vel_v(nlons, nlevs)
553  REAL bvfreq(nlons, nlevs), density(nlons, nlevs)
554  REAL visc_mol(nlons, nlevs), alt(nlons, nlevs)
555  REAL rmswind(nlons), bvfb(nlons), densb(nlons)
556  REAL sigma_t(nlons, nlevs), sigsqmcw(nlons, nlevs, nazmth)
557  REAL sigma_alpha(nlons, nlevs, nazmth), sigmatm(nlons, nlevs)
558  REAL sigsqh_alpha(nlons, nlevs, nazmth)
559  REAL m_alpha(nlons, nlevs, nazmth), v_alpha(nlons, nlevs, nazmth)
560  REAL ak_alpha(nlons, nazmth), k_alpha(nlons, nazmth)
561  REAL mmin_alpha(nlons, nazmth), i_alpha(nlons, nazmth)
562  REAL smoothr1(nlons, nlevs), smoothr2(nlons, nlevs)
563  REAL sigalpmc(nlons, nlevs, nazmth)
564  REAL f2mod(nlons, nlevs)
565 
566  LOGICAL lorms(nlons)
567 
568  ! Internal variables.
569 
570  INTEGER levbot, levtop, i, n, l, lev1p, lev2m
571  INTEGER ilprt1, ilprt2
572  ! -----------------------------------------------------------------------
573 
574  ! PRINT *,' IN HINES_EXTRO0'
575  lev1p = lev1 + 1
576  lev2m = lev2 - 1
577 
578  ! Index of lowest altitude level (bottom of drag calculation).
579 
580  levbot = lev2
581  levtop = lev1
582  IF (iorder/=1) THEN
583  WRITE (6, 1)
584 1 FORMAT (2x, ' error: IORDER NOT ONE! ')
585  END IF
586 
587  ! Buoyancy and density at bottom level.
588 
589  DO i = il1, il2
590  bvfb(i) = bvfreq(i, levbot)
591  densb(i) = density(i, levbot)
592  END DO
593 
594  ! initialize some variables
595 
596  DO n = 1, naz
597  DO l = lev1, lev2
598  DO i = il1, il2
599  m_alpha(i, l, n) = 0.0
600  END DO
601  END DO
602  END DO
603  DO l = lev1, lev2
604  DO i = il1, il2
605  sigma_t(i, l) = 0.0
606  END DO
607  END DO
608  DO n = 1, naz
609  DO i = il1, il2
610  i_alpha(i, n) = 0.0
611  END DO
612  END DO
613 
614  ! Compute azimuthal wind components from zonal and meridional winds.
615 
616  CALL hines_wind(v_alpha, vel_u, vel_v, naz, il1, il2, lev1, lev2, nlons, &
617  nlevs, nazmth)
618 
619  ! Calculate cutoff vertical wavenumber and velocity variances.
620 
621  CALL hines_wavnum(m_alpha, sigma_alpha, sigsqh_alpha, sigma_t, ak_alpha, &
622  v_alpha, visc_mol, density, densb, bvfreq, bvfb, rmswind, i_alpha, &
623  mmin_alpha, kstar, slope, f1, f2, f3, naz, levbot, levtop, il1, il2, &
624  nlons, nlevs, nazmth, sigsqmcw, sigmatm, lorms, sigalpmc, f2mod)
625  ! Smooth cutoff wavenumbers and total rms velocity in the vertical
626  ! direction NSMAX times, using FLUX_U as temporary work array.
627 
628  IF (nsmax>0) THEN
629  DO n = 1, naz
630  DO l = lev1, lev2
631  DO i = il1, il2
632  smoothr1(i, l) = m_alpha(i, l, n)
633  END DO
634  END DO
635  CALL vert_smooth(smoothr1, smoothr2, smco, nsmax, il1, il2, lev1, lev2, &
636  nlons, nlevs)
637  DO l = lev1, lev2
638  DO i = il1, il2
639  m_alpha(i, l, n) = smoothr1(i, l)
640  END DO
641  END DO
642  END DO
643  CALL vert_smooth(sigma_t, smoothr2, smco, nsmax, il1, il2, lev1, lev2, &
644  nlons, nlevs)
645  END IF
646 
647  ! Calculate zonal and meridional components of the
648  ! momentum flux and drag.
649 
650  CALL hines_flux(flux_u, flux_v, drag_u, drag_v, alt, density, densb, &
651  m_alpha, ak_alpha, k_alpha, slope, naz, il1, il2, lev1, lev2, nlons, &
652  nlevs, nazmth, lorms)
653 
654  ! Cutoff drag above ALT_CUTOFF, using BVFB as temporary work array.
655 
656  IF (icutoff==1) THEN
657  CALL hines_exp(drag_u, bvfb, alt, alt_cutoff, iorder, il1, il2, lev1, &
658  lev2, nlons, nlevs)
659  CALL hines_exp(drag_v, bvfb, alt, alt_cutoff, iorder, il1, il2, lev1, &
660  lev2, nlons, nlevs)
661  END IF
662 
663  ! Print out various arrays for diagnostic purposes.
664 
665  IF (iprint==1) THEN
666  ilprt1 = 15
667  ilprt2 = 16
668  CALL hines_print(flux_u, flux_v, drag_u, drag_v, alt, sigma_t, &
669  sigma_alpha, v_alpha, m_alpha, 1, 1, 6, ilprt1, ilprt2, lev1, lev2, &
670  naz, nlons, nlevs, nazmth)
671  END IF
672 
673  ! If not calculating heating rate and diffusion coefficient then finished.
674 
675  IF (iheatcal/=1) RETURN
676 
677  ! Calculate vertical derivative of cutoff wavenumber (store
678  ! in array V_ALPHA) using centered differences at interior gridpoints
679  ! and one-sided differences at first and last levels.
680 
681  DO n = 1, naz
682  DO l = lev1p, lev2m
683  DO i = il1, il2
684  v_alpha(i, l, n) = (m_alpha(i,l+1,n)-m_alpha(i,l-1,n))/ &
685  (alt(i,l+1)-alt(i,l-1))
686  END DO
687  END DO
688  DO i = il1, il2
689  v_alpha(i, lev1, n) = (m_alpha(i,lev1p,n)-m_alpha(i,lev1,n))/ &
690  (alt(i,lev1p)-alt(i,lev1))
691  END DO
692  DO i = il1, il2
693  v_alpha(i, lev2, n) = (m_alpha(i,lev2,n)-m_alpha(i,lev2m,n))/ &
694  (alt(i,lev2)-alt(i,lev2m))
695  END DO
696  END DO
697 
698  ! Heating rate and diffusion coefficient.
699 
700  CALL hines_heat(heat, diffco, m_alpha, v_alpha, ak_alpha, k_alpha, bvfreq, &
701  density, densb, sigma_t, visc_mol, kstar, slope, f2, f3, f5, f6, naz, &
702  il1, il2, lev1, lev2, nlons, nlevs, nazmth)
703 
704  ! Finished.
705 
706  RETURN
707  ! -----------------------------------------------------------------------
708 END SUBROUTINE hines_extro0
709 
710 SUBROUTINE hines_wavnum(m_alpha, sigma_alpha, sigsqh_alpha, sigma_t, &
711  ak_alpha, v_alpha, visc_mol, density, densb, bvfreq, bvfb, rms_wind, &
712  i_alpha, mmin_alpha, kstar, slope, f1, f2, f3, naz, levbot, levtop, il1, &
713  il2, nlons, nlevs, nazmth, sigsqmcw, sigmatm, lorms, sigalpmc, f2mod)
714  IMPLICIT NONE
715  ! This routine calculates the cutoff vertical wavenumber and velocity
716  ! variances on a longitude by altitude grid for the Hines' Doppler
717  ! spread gravity wave drag parameterization scheme.
718  ! NOTE: (1) only values of four or eight can be used for # azimuths (NAZ).
719  ! (2) only values of 1.0, 1.5 or 2.0 can be used for slope (SLOPE).
720 
721  ! Aug. 10/95 - C. McLandress
722 
723  ! Output arguements:
724 
725  ! * M_ALPHA = cutoff wavenumber at each azimuth (1/m).
726  ! * SIGMA_ALPHA = total rms wind in each azimuth (m/s).
727  ! * SIGSQH_ALPHA = portion of wind variance from waves having wave
728  ! * normals in the alpha azimuth (m/s).
729  ! * SIGMA_T = total rms horizontal wind (m/s).
730  ! * AK_ALPHA = spectral amplitude factor at each azimuth
731  ! * (i.e.,{AjKj}) in m^4/s^2.
732 
733  ! Input arguements:
734 
735  ! * V_ALPHA = wind component at each azimuth (m/s).
736  ! * VISC_MOL = molecular viscosity (m^2/s)
737  ! * DENSITY = background density (kg/m^3).
738  ! * DENSB = background density at model bottom (kg/m^3).
739  ! * BVFREQ = background Brunt Vassala frequency (radians/sec).
740  ! * BVFB = background Brunt Vassala frequency at model bottom.
741  ! * RMS_WIND = root mean square gravity wave wind at lowest level (m/s).
742  ! * KSTAR = typical gravity wave horizontal wavenumber (1/m).
743  ! * SLOPE = slope of incident vertical wavenumber spectrum
744  ! * (SLOPE = 1., 1.5 or 2.).
745  ! * F1,F2,F3 = Hines's fudge factors.
746  ! * NAZ = actual number of horizontal azimuths used (4 or 8).
747  ! * LEVBOT = index of lowest vertical level.
748  ! * LEVTOP = index of highest vertical level
749  ! * (NOTE: if LEVTOP < LEVBOT then level index
750  ! * increases from top down).
751  ! * IL1 = first longitudinal index to use (IL1 >= 1).
752  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
753  ! * NLONS = number of longitudes.
754  ! * NLEVS = number of vertical levels.
755  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
756 
757  ! * LORMS = .TRUE. for drag computation
758 
759  ! Input work arrays:
760 
761  ! * I_ALPHA = Hines' integral at a single level.
762  ! * MMIN_ALPHA = minimum value of cutoff wavenumber.
763 
764  INTEGER naz, levbot, levtop, il1, il2, nlons, nlevs, nazmth
765  REAL slope, kstar(nlons), f1, f2, f3, f2mfac
766  REAL m_alpha(nlons, nlevs, nazmth)
767  REAL sigma_alpha(nlons, nlevs, nazmth)
768  REAL sigalpmc(nlons, nlevs, nazmth)
769  REAL sigsqh_alpha(nlons, nlevs, nazmth)
770  REAL sigsqmcw(nlons, nlevs, nazmth)
771  REAL sigma_t(nlons, nlevs)
772  REAL sigmatm(nlons, nlevs)
773  REAL ak_alpha(nlons, nazmth)
774  REAL v_alpha(nlons, nlevs, nazmth)
775  REAL visc_mol(nlons, nlevs)
776  REAL f2mod(nlons, nlevs)
777  REAL density(nlons, nlevs), densb(nlons)
778  REAL bvfreq(nlons, nlevs), bvfb(nlons), rms_wind(nlons)
779  REAL i_alpha(nlons, nazmth), mmin_alpha(nlons, nazmth)
780 
781  LOGICAL lorms(nlons)
782 
783  ! Internal variables.
784 
785  INTEGER i, l, n, lstart, lend, lincr, lbelow
786  REAL m_sub_m_turb, m_sub_m_mol, m_trial
787  REAL visc, visc_min, azfac, sp1
788 
789  ! c REAL N_OVER_M(1000), SIGFAC(1000)
790 
791  REAL n_over_m(nlons), sigfac(nlons)
792  DATA visc_min/1.e-10/
793  ! -----------------------------------------------------------------------
794 
795 
796  ! PRINT *,'IN HINES_WAVNUM'
797  sp1 = slope + 1.
798 
799  ! Indices of levels to process.
800 
801  IF (levbot>levtop) THEN
802  lstart = levbot - 1
803  lend = levtop
804  lincr = -1
805  ELSE
806  WRITE (6, 1)
807 1 FORMAT (2x, ' error: IORDER NOT ONE! ')
808  END IF
809 
810  ! Use horizontal isotropy to calculate azimuthal variances at bottom level.
811 
812  azfac = 1./real(naz)
813  DO n = 1, naz
814  DO i = il1, il2
815  sigsqh_alpha(i, levbot, n) = azfac*rms_wind(i)**2
816  END DO
817  END DO
818 
819  ! Velocity variances at bottom level.
820 
821  CALL hines_sigma(sigma_t, sigma_alpha, sigsqh_alpha, naz, levbot, il1, il2, &
822  nlons, nlevs, nazmth)
823 
824  CALL hines_sigma(sigmatm, sigalpmc, sigsqmcw, naz, levbot, il1, il2, nlons, &
825  nlevs, nazmth)
826 
827  ! Calculate cutoff wavenumber and spectral amplitude factor
828  ! at bottom level where it is assumed that background winds vanish
829  ! and also initialize minimum value of cutoff wavnumber.
830 
831  DO n = 1, naz
832  DO i = il1, il2
833  IF (lorms(i)) THEN
834  m_alpha(i, levbot, n) = bvfb(i)/(f1*sigma_alpha(i,levbot,n)+f2* &
835  sigma_t(i,levbot))
836  ak_alpha(i, n) = sigsqh_alpha(i, levbot, n)/ &
837  (m_alpha(i,levbot,n)**sp1/sp1)
838  mmin_alpha(i, n) = m_alpha(i, levbot, n)
839  END IF
840  END DO
841  END DO
842 
843  ! Calculate quantities from the bottom upwards,
844  ! starting one level above bottom.
845 
846  DO l = lstart, lend, lincr
847 
848  ! Level beneath present level.
849 
850  lbelow = l - lincr
851 
852  ! Calculate N/m_M where m_M is maximum permissible value of the vertical
853  ! wavenumber (i.e., m > m_M are obliterated) and N is buoyancy frequency.
854  ! m_M is taken as the smaller of the instability-induced
855  ! wavenumber (M_SUB_M_TURB) and that imposed by molecular viscosity
856  ! (M_SUB_M_MOL). Since variance at this level is not yet known
857  ! use value at level below.
858 
859  DO i = il1, il2
860  IF (lorms(i)) THEN
861 
862  f2mfac = sigmatm(i, lbelow)**2
863  f2mod(i, lbelow) = 1. + 2.*f2mfac/(f2mfac+sigma_t(i,lbelow)**2)
864 
865  visc = amax1(visc_mol(i,l), visc_min)
866  m_sub_m_turb = bvfreq(i, l)/(f2*f2mod(i,lbelow)*sigma_t(i,lbelow))
867  m_sub_m_mol = (bvfreq(i,l)*kstar(i)/visc)**0.33333333/f3
868  IF (m_sub_m_turb<m_sub_m_mol) THEN
869  n_over_m(i) = f2*f2mod(i, lbelow)*sigma_t(i, lbelow)
870  ELSE
871  n_over_m(i) = bvfreq(i, l)/m_sub_m_mol
872  END IF
873  END IF
874  END DO
875 
876  ! Calculate cutoff wavenumber at this level.
877 
878  DO n = 1, naz
879  DO i = il1, il2
880  IF (lorms(i)) THEN
881 
882  ! Calculate trial value (since variance at this level is not yet
883  ! known
884  ! use value at level below). If trial value is negative or if it
885  ! exceeds
886  ! minimum value (not permitted) then set it to minimum value.
887 
888  m_trial = bvfb(i)/(f1*(sigma_alpha(i,lbelow,n)+sigalpmc(i,lbelow, &
889  n))+n_over_m(i)+v_alpha(i,l,n))
890  IF (m_trial<=0. .OR. m_trial>mmin_alpha(i,n)) THEN
891  m_trial = mmin_alpha(i, n)
892  END IF
893  m_alpha(i, l, n) = m_trial
894 
895  ! Reset minimum value of cutoff wavenumber if necessary.
896 
897  IF (m_alpha(i,l,n)<mmin_alpha(i,n)) THEN
898  mmin_alpha(i, n) = m_alpha(i, l, n)
899  END IF
900 
901  END IF
902  END DO
903  END DO
904 
905  ! Calculate the Hines integral at this level.
906 
907  CALL hines_intgrl(i_alpha, v_alpha, m_alpha, bvfb, slope, naz, l, il1, &
908  il2, nlons, nlevs, nazmth, lorms)
909 
910 
911  ! Calculate the velocity variances at this level.
912 
913  DO i = il1, il2
914  sigfac(i) = densb(i)/density(i, l)*bvfreq(i, l)/bvfb(i)
915  END DO
916  DO n = 1, naz
917  DO i = il1, il2
918  sigsqh_alpha(i, l, n) = sigfac(i)*ak_alpha(i, n)*i_alpha(i, n)
919  END DO
920  END DO
921  CALL hines_sigma(sigma_t, sigma_alpha, sigsqh_alpha, naz, l, il1, il2, &
922  nlons, nlevs, nazmth)
923 
924  CALL hines_sigma(sigmatm, sigalpmc, sigsqmcw, naz, l, il1, il2, nlons, &
925  nlevs, nazmth)
926 
927  ! End of level loop.
928 
929  END DO
930 
931  RETURN
932  ! -----------------------------------------------------------------------
933 END SUBROUTINE hines_wavnum
934 
935 SUBROUTINE hines_wind(v_alpha, vel_u, vel_v, naz, il1, il2, lev1, lev2, &
936  nlons, nlevs, nazmth)
937  IMPLICIT NONE
938  ! This routine calculates the azimuthal horizontal background wind
939  ! components
940  ! on a longitude by altitude grid for the case of 4 or 8 azimuths for
941  ! the Hines' Doppler spread GWD parameterization scheme.
942 
943  ! Aug. 7/95 - C. McLandress
944 
945  ! Output arguement:
946 
947  ! * V_ALPHA = background wind component at each azimuth (m/s).
948  ! * (note: first azimuth is in eastward direction
949  ! * and rotate in counterclockwise direction.)
950 
951  ! Input arguements:
952 
953  ! * VEL_U = background zonal wind component (m/s).
954  ! * VEL_V = background meridional wind component (m/s).
955  ! * NAZ = actual number of horizontal azimuths used (must be 4 or 8).
956  ! * IL1 = first longitudinal index to use (IL1 >= 1).
957  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
958  ! * LEV1 = first altitude level to use (LEV1 >=1).
959  ! * LEV2 = last altitude level to use (LEV1 < LEV2 <= NLEVS).
960  ! * NLONS = number of longitudes.
961  ! * NLEVS = number of vertical levels.
962  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
963 
964  ! Constants in DATA statements.
965 
966  ! * COS45 = cosine of 45 degrees.
967  ! * UMIN = minimum allowable value for zonal or meridional
968  ! * wind component (m/s).
969 
970  ! Subroutine arguements.
971 
972  INTEGER naz, il1, il2, lev1, lev2
973  INTEGER nlons, nlevs, nazmth
974  REAL v_alpha(nlons, nlevs, nazmth)
975  REAL vel_u(nlons, nlevs), vel_v(nlons, nlevs)
976 
977  ! Internal variables.
978 
979  INTEGER i, l
980  REAL u, v, cos45, umin
981 
982  DATA cos45/0.7071068/
983  DATA umin/0.001/
984  ! -----------------------------------------------------------------------
985 
986  ! Case with 4 azimuths.
987 
988 
989  ! PRINT *,'IN HINES_WIND'
990  IF (naz==4) THEN
991  DO l = lev1, lev2
992  DO i = il1, il2
993  u = vel_u(i, l)
994  v = vel_v(i, l)
995  IF (abs(u)<umin) u = umin
996  IF (abs(v)<umin) v = umin
997  v_alpha(i, l, 1) = u
998  v_alpha(i, l, 2) = v
999  v_alpha(i, l, 3) = -u
1000  v_alpha(i, l, 4) = -v
1001  END DO
1002  END DO
1003  END IF
1004 
1005  ! Case with 8 azimuths.
1006 
1007  IF (naz==8) THEN
1008  DO l = lev1, lev2
1009  DO i = il1, il2
1010  u = vel_u(i, l)
1011  v = vel_v(i, l)
1012  IF (abs(u)<umin) u = umin
1013  IF (abs(v)<umin) v = umin
1014  v_alpha(i, l, 1) = u
1015  v_alpha(i, l, 2) = cos45*(v+u)
1016  v_alpha(i, l, 3) = v
1017  v_alpha(i, l, 4) = cos45*(v-u)
1018  v_alpha(i, l, 5) = -u
1019  v_alpha(i, l, 6) = -v_alpha(i, l, 2)
1020  v_alpha(i, l, 7) = -v
1021  v_alpha(i, l, 8) = -v_alpha(i, l, 4)
1022  END DO
1023  END DO
1024  END IF
1025 
1026  RETURN
1027  ! -----------------------------------------------------------------------
1028 END SUBROUTINE hines_wind
1029 
1030 SUBROUTINE hines_flux(flux_u, flux_v, drag_u, drag_v, alt, density, densb, &
1031  m_alpha, ak_alpha, k_alpha, slope, naz, il1, il2, lev1, lev2, nlons, &
1032  nlevs, nazmth, lorms)
1033  IMPLICIT NONE
1034  ! Calculate zonal and meridional components of the vertical flux
1035  ! of horizontal momentum and corresponding wave drag (force per unit mass)
1036  ! on a longitude by altitude grid for the Hines' Doppler spread
1037  ! GWD parameterization scheme.
1038  ! NOTE: only 4 or 8 azimuths can be used.
1039 
1040  ! Aug. 6/95 - C. McLandress
1041 
1042  ! Output arguements:
1043 
1044  ! * FLUX_U = zonal component of vertical momentum flux (Pascals)
1045  ! * FLUX_V = meridional component of vertical momentum flux (Pascals)
1046  ! * DRAG_U = zonal component of drag (m/s^2).
1047  ! * DRAG_V = meridional component of drag (m/s^2).
1048 
1049  ! Input arguements:
1050 
1051  ! * ALT = altitudes (m).
1052  ! * DENSITY = background density (kg/m^3).
1053  ! * DENSB = background density at bottom level (kg/m^3).
1054  ! * M_ALPHA = cutoff vertical wavenumber (1/m).
1055  ! * AK_ALPHA = spectral amplitude factor (i.e., {AjKj} in m^4/s^2).
1056  ! * K_ALPHA = horizontal wavenumber (1/m).
1057  ! * SLOPE = slope of incident vertical wavenumber spectrum.
1058  ! * NAZ = actual number of horizontal azimuths used (must be 4 or 8).
1059  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1060  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1061  ! * LEV1 = first altitude level to use (LEV1 >=1).
1062  ! * LEV2 = last altitude level to use (LEV1 < LEV2 <= NLEVS).
1063  ! * NLONS = number of longitudes.
1064  ! * NLEVS = number of vertical levels.
1065  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
1066 
1067  ! * LORMS = .TRUE. for drag computation
1068 
1069  ! Constant in DATA statement.
1070 
1071  ! * COS45 = cosine of 45 degrees.
1072 
1073  ! Subroutine arguements.
1074 
1075  INTEGER naz, il1, il2, lev1, lev2
1076  INTEGER nlons, nlevs, nazmth
1077  REAL slope
1078  REAL flux_u(nlons, nlevs), flux_v(nlons, nlevs)
1079  REAL drag_u(nlons, nlevs), drag_v(nlons, nlevs)
1080  REAL alt(nlons, nlevs), density(nlons, nlevs), densb(nlons)
1081  REAL m_alpha(nlons, nlevs, nazmth)
1082  REAL ak_alpha(nlons, nazmth), k_alpha(nlons, nazmth)
1083 
1084  LOGICAL lorms(nlons)
1085 
1086  ! Internal variables.
1087 
1088  INTEGER i, l, lev1p, lev2m, lev2p
1089  REAL cos45, prod2, prod4, prod6, prod8, dendz, dendz2
1090  DATA cos45/0.7071068/
1091  ! -----------------------------------------------------------------------
1092 
1093  lev1p = lev1 + 1
1094  lev2m = lev2 - 1
1095  lev2p = lev2 + 1
1096 
1097  ! Sum over azimuths for case where SLOPE = 1.
1098 
1099  IF (slope==1.) THEN
1100 
1101  ! Case with 4 azimuths.
1102 
1103  IF (naz==4) THEN
1104  DO l = lev1, lev2
1105  DO i = il1, il2
1106  flux_u(i, l) = ak_alpha(i, 1)*k_alpha(i, 1)*m_alpha(i, l, 1) - &
1107  ak_alpha(i, 3)*k_alpha(i, 3)*m_alpha(i, l, 3)
1108  flux_v(i, l) = ak_alpha(i, 2)*k_alpha(i, 2)*m_alpha(i, l, 2) - &
1109  ak_alpha(i, 4)*k_alpha(i, 4)*m_alpha(i, l, 4)
1110  END DO
1111  END DO
1112  END IF
1113 
1114  ! Case with 8 azimuths.
1115 
1116  IF (naz==8) THEN
1117  DO l = lev1, lev2
1118  DO i = il1, il2
1119  prod2 = ak_alpha(i, 2)*k_alpha(i, 2)*m_alpha(i, l, 2)
1120  prod4 = ak_alpha(i, 4)*k_alpha(i, 4)*m_alpha(i, l, 4)
1121  prod6 = ak_alpha(i, 6)*k_alpha(i, 6)*m_alpha(i, l, 6)
1122  prod8 = ak_alpha(i, 8)*k_alpha(i, 8)*m_alpha(i, l, 8)
1123  flux_u(i, l) = ak_alpha(i, 1)*k_alpha(i, 1)*m_alpha(i, l, 1) - &
1124  ak_alpha(i, 5)*k_alpha(i, 5)*m_alpha(i, l, 5) + &
1125  cos45*(prod2-prod4-prod6+prod8)
1126  flux_v(i, l) = ak_alpha(i, 3)*k_alpha(i, 3)*m_alpha(i, l, 3) - &
1127  ak_alpha(i, 7)*k_alpha(i, 7)*m_alpha(i, l, 7) + &
1128  cos45*(prod2+prod4-prod6-prod8)
1129  END DO
1130  END DO
1131  END IF
1132 
1133  END IF
1134 
1135  ! Sum over azimuths for case where SLOPE not equal to 1.
1136 
1137  IF (slope/=1.) THEN
1138 
1139  ! Case with 4 azimuths.
1140 
1141  IF (naz==4) THEN
1142  DO l = lev1, lev2
1143  DO i = il1, il2
1144  flux_u(i, l) = ak_alpha(i, 1)*k_alpha(i, 1)* &
1145  m_alpha(i, l, 1)**slope - ak_alpha(i, 3)*k_alpha(i, 3)*m_alpha(i, &
1146  l, 3)**slope
1147  flux_v(i, l) = ak_alpha(i, 2)*k_alpha(i, 2)* &
1148  m_alpha(i, l, 2)**slope - ak_alpha(i, 4)*k_alpha(i, 4)*m_alpha(i, &
1149  l, 4)**slope
1150  END DO
1151  END DO
1152  END IF
1153 
1154  ! Case with 8 azimuths.
1155 
1156  IF (naz==8) THEN
1157  DO l = lev1, lev2
1158  DO i = il1, il2
1159  prod2 = ak_alpha(i, 2)*k_alpha(i, 2)*m_alpha(i, l, 2)**slope
1160  prod4 = ak_alpha(i, 4)*k_alpha(i, 4)*m_alpha(i, l, 4)**slope
1161  prod6 = ak_alpha(i, 6)*k_alpha(i, 6)*m_alpha(i, l, 6)**slope
1162  prod8 = ak_alpha(i, 8)*k_alpha(i, 8)*m_alpha(i, l, 8)**slope
1163  flux_u(i, l) = ak_alpha(i, 1)*k_alpha(i, 1)* &
1164  m_alpha(i, l, 1)**slope - ak_alpha(i, 5)*k_alpha(i, 5)*m_alpha(i, &
1165  l, 5)**slope + cos45*(prod2-prod4-prod6+prod8)
1166  flux_v(i, l) = ak_alpha(i, 3)*k_alpha(i, 3)* &
1167  m_alpha(i, l, 3)**slope - ak_alpha(i, 7)*k_alpha(i, 7)*m_alpha(i, &
1168  l, 7)**slope + cos45*(prod2+prod4-prod6-prod8)
1169  END DO
1170  END DO
1171  END IF
1172 
1173  END IF
1174 
1175  ! Calculate flux from sum.
1176 
1177  DO l = lev1, lev2
1178  DO i = il1, il2
1179  flux_u(i, l) = flux_u(i, l)*densb(i)/slope
1180  flux_v(i, l) = flux_v(i, l)*densb(i)/slope
1181  END DO
1182  END DO
1183 
1184  ! Calculate drag at intermediate levels using centered differences
1185 
1186  DO l = lev1p, lev2m
1187  DO i = il1, il2
1188  IF (lorms(i)) THEN
1189  ! cc DENDZ2 = DENSITY(I,L) * ( ALT(I,L+1) - ALT(I,L-1) )
1190  dendz2 = density(i, l)*(alt(i,l-1)-alt(i,l))
1191  ! cc DRAG_U(I,L) = - ( FLUX_U(I,L+1) - FLUX_U(I,L-1) ) / DENDZ2
1192  drag_u(i, l) = -(flux_u(i,l-1)-flux_u(i,l))/dendz2
1193  ! cc DRAG_V(I,L) = - ( FLUX_V(I,L+1) - FLUX_V(I,L-1) ) / DENDZ2
1194  drag_v(i, l) = -(flux_v(i,l-1)-flux_v(i,l))/dendz2
1195 
1196  END IF
1197  END DO
1198  END DO
1199 
1200  ! Drag at first and last levels using one-side differences.
1201 
1202  DO i = il1, il2
1203  IF (lorms(i)) THEN
1204  dendz = density(i, lev1)*(alt(i,lev1)-alt(i,lev1p))
1205  drag_u(i, lev1) = flux_u(i, lev1)/dendz
1206  drag_v(i, lev1) = flux_v(i, lev1)/dendz
1207  END IF
1208  END DO
1209  DO i = il1, il2
1210  IF (lorms(i)) THEN
1211  dendz = density(i, lev2)*(alt(i,lev2m)-alt(i,lev2))
1212  drag_u(i, lev2) = -(flux_u(i,lev2m)-flux_u(i,lev2))/dendz
1213  drag_v(i, lev2) = -(flux_v(i,lev2m)-flux_v(i,lev2))/dendz
1214  END IF
1215  END DO
1216  IF (nlevs>lev2) THEN
1217  DO i = il1, il2
1218  IF (lorms(i)) THEN
1219  dendz = density(i, lev2p)*(alt(i,lev2)-alt(i,lev2p))
1220  drag_u(i, lev2p) = -flux_u(i, lev2)/dendz
1221  drag_v(i, lev2p) = -flux_v(i, lev2)/dendz
1222  END IF
1223  END DO
1224  END IF
1225 
1226  RETURN
1227  ! -----------------------------------------------------------------------
1228 END SUBROUTINE hines_flux
1229 
1230 SUBROUTINE hines_heat(heat, diffco, m_alpha, dmdz_alpha, ak_alpha, k_alpha, &
1231  bvfreq, density, densb, sigma_t, visc_mol, kstar, slope, f2, f3, f5, f6, &
1232  naz, il1, il2, lev1, lev2, nlons, nlevs, nazmth)
1233  IMPLICIT NONE
1234  ! This routine calculates the gravity wave induced heating and
1235  ! diffusion coefficient on a longitude by altitude grid for
1236  ! the Hines' Doppler spread gravity wave drag parameterization scheme.
1237 
1238  ! Aug. 6/95 - C. McLandress
1239 
1240  ! Output arguements:
1241 
1242  ! * HEAT = gravity wave heating (K/sec).
1243  ! * DIFFCO = diffusion coefficient (m^2/sec)
1244 
1245  ! Input arguements:
1246 
1247  ! * M_ALPHA = cutoff vertical wavenumber (1/m).
1248  ! * DMDZ_ALPHA = vertical derivative of cutoff wavenumber.
1249  ! * AK_ALPHA = spectral amplitude factor of each azimuth
1250  ! (i.e., {AjKj} in m^4/s^2).
1251  ! * K_ALPHA = horizontal wavenumber of each azimuth (1/m).
1252  ! * BVFREQ = background Brunt Vassala frequency (rad/sec).
1253  ! * DENSITY = background density (kg/m^3).
1254  ! * DENSB = background density at bottom level (kg/m^3).
1255  ! * SIGMA_T = total rms horizontal wind (m/s).
1256  ! * VISC_MOL = molecular viscosity (m^2/s).
1257  ! * KSTAR = typical gravity wave horizontal wavenumber (1/m).
1258  ! * SLOPE = slope of incident vertical wavenumber spectrum.
1259  ! * F2,F3,F5,F6 = Hines's fudge factors.
1260  ! * NAZ = actual number of horizontal azimuths used.
1261  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1262  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1263  ! * LEV1 = first altitude level to use (LEV1 >=1).
1264  ! * LEV2 = last altitude level to use (LEV1 < LEV2 <= NLEVS).
1265  ! * NLONS = number of longitudes.
1266  ! * NLEVS = number of vertical levels.
1267  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
1268 
1269  INTEGER naz, il1, il2, lev1, lev2, nlons, nlevs, nazmth
1270  REAL kstar(nlons), slope, f2, f3, f5, f6
1271  REAL heat(nlons, nlevs), diffco(nlons, nlevs)
1272  REAL m_alpha(nlons, nlevs, nazmth), dmdz_alpha(nlons, nlevs, nazmth)
1273  REAL ak_alpha(nlons, nazmth), k_alpha(nlons, nazmth)
1274  REAL bvfreq(nlons, nlevs), density(nlons, nlevs), densb(nlons)
1275  REAL sigma_t(nlons, nlevs), visc_mol(nlons, nlevs)
1276 
1277  ! Internal variables.
1278 
1279  INTEGER i, l, n
1280  REAL m_sub_m_turb, m_sub_m_mol, m_sub_m, heatng
1281  REAL visc, visc_min, cpgas, sm1
1282 
1283  ! specific heat at constant pressure
1284 
1285  DATA cpgas/1004./
1286 
1287  ! minimum permissible viscosity
1288 
1289  DATA visc_min/1.e-10/
1290  ! -----------------------------------------------------------------------
1291 
1292  ! Initialize heating array.
1293 
1294  DO l = 1, nlevs
1295  DO i = 1, nlons
1296  heat(i, l) = 0.
1297  END DO
1298  END DO
1299 
1300  ! Perform sum over azimuths for case where SLOPE = 1.
1301 
1302  IF (slope==1.) THEN
1303  DO n = 1, naz
1304  DO l = lev1, lev2
1305  DO i = il1, il2
1306  heat(i, l) = heat(i, l) + ak_alpha(i, n)*k_alpha(i, n)*dmdz_alpha(i &
1307  , l, n)
1308  END DO
1309  END DO
1310  END DO
1311  END IF
1312 
1313  ! Perform sum over azimuths for case where SLOPE not 1.
1314 
1315  IF (slope/=1.) THEN
1316  sm1 = slope - 1.
1317  DO n = 1, naz
1318  DO l = lev1, lev2
1319  DO i = il1, il2
1320  heat(i, l) = heat(i, l) + ak_alpha(i, n)*k_alpha(i, n)*m_alpha(i, l &
1321  , n)**sm1*dmdz_alpha(i, l, n)
1322  END DO
1323  END DO
1324  END DO
1325  END IF
1326 
1327  ! Heating and diffusion.
1328 
1329  DO l = lev1, lev2
1330  DO i = il1, il2
1331 
1332  ! Maximum permissible value of cutoff wavenumber is the smaller
1333  ! of the instability-induced wavenumber (M_SUB_M_TURB) and
1334  ! that imposed by molecular viscosity (M_SUB_M_MOL).
1335 
1336  visc = amax1(visc_mol(i,l), visc_min)
1337  m_sub_m_turb = bvfreq(i, l)/(f2*sigma_t(i,l))
1338  m_sub_m_mol = (bvfreq(i,l)*kstar(i)/visc)**0.33333333/f3
1339  m_sub_m = amin1(m_sub_m_turb, m_sub_m_mol)
1340 
1341  heatng = -heat(i, l)*f5*bvfreq(i, l)/m_sub_m*densb(i)/density(i, l)
1342  diffco(i, l) = f6*heatng**0.33333333/m_sub_m**1.33333333
1343  heat(i, l) = heatng/cpgas
1344 
1345  END DO
1346  END DO
1347 
1348  RETURN
1349  ! -----------------------------------------------------------------------
1350 END SUBROUTINE hines_heat
1351 
1352 SUBROUTINE hines_sigma(sigma_t, sigma_alpha, sigsqh_alpha, naz, lev, il1, &
1353  il2, nlons, nlevs, nazmth)
1354  IMPLICIT NONE
1355  ! This routine calculates the total rms and azimuthal rms horizontal
1356  ! velocities at a given level on a longitude by altitude grid for
1357  ! the Hines' Doppler spread GWD parameterization scheme.
1358  ! NOTE: only four or eight azimuths can be used.
1359 
1360  ! Aug. 7/95 - C. McLandress
1361 
1362  ! Output arguements:
1363 
1364  ! * SIGMA_T = total rms horizontal wind (m/s).
1365  ! * SIGMA_ALPHA = total rms wind in each azimuth (m/s).
1366 
1367  ! Input arguements:
1368 
1369  ! * SIGSQH_ALPHA = portion of wind variance from waves having wave
1370  ! * normals in the alpha azimuth (m/s).
1371  ! * NAZ = actual number of horizontal azimuths used (must be 4 or 8).
1372  ! * LEV = altitude level to process.
1373  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1374  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1375  ! * NLONS = number of longitudes.
1376  ! * NLEVS = number of vertical levels.
1377  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
1378 
1379  ! Subroutine arguements.
1380 
1381  INTEGER lev, naz, il1, il2
1382  INTEGER nlons, nlevs, nazmth
1383  REAL sigma_t(nlons, nlevs)
1384  REAL sigma_alpha(nlons, nlevs, nazmth)
1385  REAL sigsqh_alpha(nlons, nlevs, nazmth)
1386 
1387  ! Internal variables.
1388 
1389  INTEGER i, n
1390  REAL sum_even, sum_odd
1391  ! -----------------------------------------------------------------------
1392 
1393  ! Calculate azimuthal rms velocity for the 4 azimuth case.
1394 
1395  IF (naz==4) THEN
1396  DO i = il1, il2
1397  sigma_alpha(i, lev, 1) = sqrt(sigsqh_alpha(i,lev,1)+sigsqh_alpha(i,lev, &
1398  3))
1399  sigma_alpha(i, lev, 2) = sqrt(sigsqh_alpha(i,lev,2)+sigsqh_alpha(i,lev, &
1400  4))
1401  sigma_alpha(i, lev, 3) = sigma_alpha(i, lev, 1)
1402  sigma_alpha(i, lev, 4) = sigma_alpha(i, lev, 2)
1403  END DO
1404  END IF
1405 
1406  ! Calculate azimuthal rms velocity for the 8 azimuth case.
1407 
1408  IF (naz==8) THEN
1409  DO i = il1, il2
1410  sum_odd = (sigsqh_alpha(i,lev,1)+sigsqh_alpha(i,lev,3)+ &
1411  sigsqh_alpha(i,lev,5)+sigsqh_alpha(i,lev,7))/2.
1412  sum_even = (sigsqh_alpha(i,lev,2)+sigsqh_alpha(i,lev,4)+ &
1413  sigsqh_alpha(i,lev,6)+sigsqh_alpha(i,lev,8))/2.
1414  sigma_alpha(i, lev, 1) = sqrt(sigsqh_alpha(i,lev,1)+sigsqh_alpha(i,lev, &
1415  5)+sum_even)
1416  sigma_alpha(i, lev, 2) = sqrt(sigsqh_alpha(i,lev,2)+sigsqh_alpha(i,lev, &
1417  6)+sum_odd)
1418  sigma_alpha(i, lev, 3) = sqrt(sigsqh_alpha(i,lev,3)+sigsqh_alpha(i,lev, &
1419  7)+sum_even)
1420  sigma_alpha(i, lev, 4) = sqrt(sigsqh_alpha(i,lev,4)+sigsqh_alpha(i,lev, &
1421  8)+sum_odd)
1422  sigma_alpha(i, lev, 5) = sigma_alpha(i, lev, 1)
1423  sigma_alpha(i, lev, 6) = sigma_alpha(i, lev, 2)
1424  sigma_alpha(i, lev, 7) = sigma_alpha(i, lev, 3)
1425  sigma_alpha(i, lev, 8) = sigma_alpha(i, lev, 4)
1426  END DO
1427  END IF
1428 
1429  ! Calculate total rms velocity.
1430 
1431  DO i = il1, il2
1432  sigma_t(i, lev) = 0.
1433  END DO
1434  DO n = 1, naz
1435  DO i = il1, il2
1436  sigma_t(i, lev) = sigma_t(i, lev) + sigsqh_alpha(i, lev, n)
1437  END DO
1438  END DO
1439  DO i = il1, il2
1440  sigma_t(i, lev) = sqrt(sigma_t(i,lev))
1441  END DO
1442 
1443  RETURN
1444  ! -----------------------------------------------------------------------
1445 END SUBROUTINE hines_sigma
1446 
1447 SUBROUTINE hines_intgrl(i_alpha, v_alpha, m_alpha, bvfb, slope, naz, lev, &
1448  il1, il2, nlons, nlevs, nazmth, lorms)
1449  IMPLICIT NONE
1450  ! This routine calculates the vertical wavenumber integral
1451  ! for a single vertical level at each azimuth on a longitude grid
1452  ! for the Hines' Doppler spread GWD parameterization scheme.
1453  ! NOTE: (1) only spectral slopes of 1, 1.5 or 2 are permitted.
1454  ! (2) the integral is written in terms of the product QM
1455  ! which by construction is always less than 1. Series
1456  ! solutions are used for small |QM| and analytical solutions
1457  ! for remaining values.
1458 
1459  ! Aug. 8/95 - C. McLandress
1460 
1461  ! Output arguement:
1462 
1463  ! * I_ALPHA = Hines' integral.
1464 
1465  ! Input arguements:
1466 
1467  ! * V_ALPHA = azimuthal wind component (m/s).
1468  ! * M_ALPHA = azimuthal cutoff vertical wavenumber (1/m).
1469  ! * BVFB = background Brunt Vassala frequency at model bottom.
1470  ! * SLOPE = slope of initial vertical wavenumber spectrum
1471  ! * (must use SLOPE = 1., 1.5 or 2.)
1472  ! * NAZ = actual number of horizontal azimuths used.
1473  ! * LEV = altitude level to process.
1474  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1475  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1476  ! * NLONS = number of longitudes.
1477  ! * NLEVS = number of vertical levels.
1478  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
1479 
1480  ! * LORMS = .TRUE. for drag computation
1481 
1482  ! Constants in DATA statements:
1483 
1484  ! * QMIN = minimum value of Q_ALPHA (avoids indeterminant form of integral)
1485  ! * QM_MIN = minimum value of Q_ALPHA * M_ALPHA (used to avoid numerical
1486  ! * problems).
1487 
1488  INTEGER lev, naz, il1, il2, nlons, nlevs, nazmth
1489  REAL i_alpha(nlons, nazmth)
1490  REAL v_alpha(nlons, nlevs, nazmth)
1491  REAL m_alpha(nlons, nlevs, nazmth)
1492  REAL bvfb(nlons), slope
1493 
1494  LOGICAL lorms(nlons)
1495 
1496  ! Internal variables.
1497 
1498  INTEGER i, n
1499  REAL q_alpha, qm, sqrtqm, q_min, qm_min
1500 
1501  DATA q_min/1.0/, qm_min/0.01/
1502  ! -----------------------------------------------------------------------
1503 
1504  ! For integer value SLOPE = 1.
1505 
1506  IF (slope==1.) THEN
1507 
1508  DO n = 1, naz
1509  DO i = il1, il2
1510  IF (lorms(i)) THEN
1511 
1512  q_alpha = v_alpha(i, lev, n)/bvfb(i)
1513  qm = q_alpha*m_alpha(i, lev, n)
1514 
1515  ! If |QM| is small then use first 4 terms series of Taylor series
1516  ! expansion of integral in order to avoid indeterminate form of
1517  ! integral,
1518  ! otherwise use analytical form of integral.
1519 
1520  IF (abs(q_alpha)<q_min .OR. abs(qm)<qm_min) THEN
1521  IF (q_alpha==0.) THEN
1522  i_alpha(i, n) = m_alpha(i, lev, n)**2/2.
1523  ELSE
1524  i_alpha(i, n) = (qm**2/2.+qm**3/3.+qm**4/4.+qm**5/5.)/ &
1525  q_alpha**2
1526  END IF
1527  ELSE
1528  i_alpha(i, n) = -(alog(1.-qm)+qm)/q_alpha**2
1529  END IF
1530 
1531  END IF
1532  END DO
1533  END DO
1534 
1535  END IF
1536 
1537  ! For integer value SLOPE = 2.
1538 
1539  IF (slope==2.) THEN
1540 
1541  DO n = 1, naz
1542  DO i = il1, il2
1543  IF (lorms(i)) THEN
1544 
1545  q_alpha = v_alpha(i, lev, n)/bvfb(i)
1546  qm = q_alpha*m_alpha(i, lev, n)
1547 
1548  ! If |QM| is small then use first 4 terms series of Taylor series
1549  ! expansion of integral in order to avoid indeterminate form of
1550  ! integral,
1551  ! otherwise use analytical form of integral.
1552 
1553  IF (abs(q_alpha)<q_min .OR. abs(qm)<qm_min) THEN
1554  IF (q_alpha==0.) THEN
1555  i_alpha(i, n) = m_alpha(i, lev, n)**3/3.
1556  ELSE
1557  i_alpha(i, n) = (qm**3/3.+qm**4/4.+qm**5/5.+qm**6/6.)/ &
1558  q_alpha**3
1559  END IF
1560  ELSE
1561  i_alpha(i, n) = -(alog(1.-qm)+qm+qm**2/2.)/q_alpha**3
1562  END IF
1563 
1564  END IF
1565  END DO
1566  END DO
1567 
1568  END IF
1569 
1570  ! For real value SLOPE = 1.5
1571 
1572  IF (slope==1.5) THEN
1573 
1574  DO n = 1, naz
1575  DO i = il1, il2
1576  IF (lorms(i)) THEN
1577 
1578  q_alpha = v_alpha(i, lev, n)/bvfb(i)
1579  qm = q_alpha*m_alpha(i, lev, n)
1580 
1581  ! If |QM| is small then use first 4 terms series of Taylor series
1582  ! expansion of integral in order to avoid indeterminate form of
1583  ! integral,
1584  ! otherwise use analytical form of integral.
1585 
1586  IF (abs(q_alpha)<q_min .OR. abs(qm)<qm_min) THEN
1587  IF (q_alpha==0.) THEN
1588  i_alpha(i, n) = m_alpha(i, lev, n)**2.5/2.5
1589  ELSE
1590  i_alpha(i, n) = (qm/2.5+qm**2/3.5+qm**3/4.5+qm**4/5.5)* &
1591  m_alpha(i, lev, n)**1.5/q_alpha
1592  END IF
1593  ELSE
1594  qm = abs(qm)
1595  sqrtqm = sqrt(qm)
1596  IF (q_alpha>=0.) THEN
1597  i_alpha(i, n) = (alog((1.+sqrtqm)/(1.-sqrtqm))-2.*sqrtqm*(1.+qm &
1598  /3.))/q_alpha**2.5
1599  ELSE
1600  i_alpha(i, n) = 2.*(atan(sqrtqm)+sqrtqm*(qm/3.-1.))/ &
1601  abs(q_alpha)**2.5
1602  END IF
1603  END IF
1604 
1605  END IF
1606  END DO
1607  END DO
1608 
1609  END IF
1610 
1611  ! If integral is negative (which in principal should not happen) then
1612  ! print a message and some info since execution will abort when calculating
1613  ! the variances.
1614 
1615  ! DO 80 N = 1,NAZ
1616  ! DO 70 I = IL1,IL2
1617  ! IF (I_ALPHA(I,N).LT.0.) THEN
1618  ! WRITE (6,*)
1619  ! WRITE (6,*) '******************************'
1620  ! WRITE (6,*) 'Hines integral I_ALPHA < 0 '
1621  ! WRITE (6,*) ' longitude I=',I
1622  ! WRITE (6,*) ' azimuth N=',N
1623  ! WRITE (6,*) ' level LEV=',LEV
1624  ! WRITE (6,*) ' I_ALPHA =',I_ALPHA(I,N)
1625  ! WRITE (6,*) ' V_ALPHA =',V_ALPHA(I,LEV,N)
1626  ! WRITE (6,*) ' M_ALPHA =',M_ALPHA(I,LEV,N)
1627  ! WRITE (6,*) ' Q_ALPHA =',V_ALPHA(I,LEV,N) / BVFB(I)
1628  ! WRITE (6,*) ' QM =',V_ALPHA(I,LEV,N) / BVFB(I)
1629  ! ^ * M_ALPHA(I,LEV,N)
1630  ! WRITE (6,*) '******************************'
1631  ! END IF
1632  ! 70 CONTINUE
1633  ! 80 CONTINUE
1634 
1635  RETURN
1636  ! -----------------------------------------------------------------------
1637 END SUBROUTINE hines_intgrl
1638 
1639 SUBROUTINE hines_setup(naz, slope, f1, f2, f3, f5, f6, kstar, icutoff, &
1640  alt_cutoff, smco, nsmax, iheatcal, k_alpha, ierror, nmessg, nlons, &
1641  nazmth, coslat)
1642  IMPLICIT NONE
1643  ! This routine specifies various parameters needed for the
1644  ! the Hines' Doppler spread gravity wave drag parameterization scheme.
1645 
1646  ! Aug. 8/95 - C. McLandress
1647 
1648  ! Output arguements:
1649 
1650  ! * NAZ = actual number of horizontal azimuths used
1651  ! * (code set up presently for only NAZ = 4 or 8).
1652  ! * SLOPE = slope of incident vertical wavenumber spectrum
1653  ! * (code set up presently for SLOPE 1., 1.5 or 2.).
1654  ! * F1 = "fudge factor" used in calculation of trial value of
1655  ! * azimuthal cutoff wavenumber M_ALPHA (1.2 <= F1 <= 1.9).
1656  ! * F2 = "fudge factor" used in calculation of maximum
1657  ! * permissible instabiliy-induced cutoff wavenumber
1658  ! * M_SUB_M_TURB (0.1 <= F2 <= 1.4).
1659  ! * F3 = "fudge factor" used in calculation of maximum
1660  ! * permissible molecular viscosity-induced cutoff wavenumber
1661  ! * M_SUB_M_MOL (0.1 <= F2 <= 1.4).
1662  ! * F5 = "fudge factor" used in calculation of heating rate
1663  ! * (1 <= F5 <= 3).
1664  ! * F6 = "fudge factor" used in calculation of turbulent
1665  ! * diffusivity coefficient.
1666  ! * KSTAR = typical gravity wave horizontal wavenumber (1/m)
1667  ! * used in calculation of M_SUB_M_TURB.
1668  ! * ICUTOFF = 1 to exponentially damp off GWD, heating and diffusion
1669  ! * arrays above ALT_CUTOFF; otherwise arrays not modified.
1670  ! * ALT_CUTOFF = altitude in meters above which exponential decay applied.
1671  ! * SMCO = smoother used to smooth cutoff vertical wavenumbers
1672  ! * and total rms winds before calculating drag or heating.
1673  ! * (==> a 1:SMCO:1 stencil used; SMCO >= 1.).
1674  ! * NSMAX = number of times smoother applied ( >= 1),
1675  ! * = 0 means no smoothing performed.
1676  ! * IHEATCAL = 1 to calculate heating rates and diffusion coefficient.
1677  ! * = 0 means only drag and flux calculated.
1678  ! * K_ALPHA = horizontal wavenumber of each azimuth (1/m) which
1679  ! * is set here to KSTAR.
1680  ! * IERROR = error flag.
1681  ! * = 0 no errors.
1682  ! * = 10 ==> NAZ > NAZMTH
1683  ! * = 20 ==> invalid number of azimuths (NAZ must be 4 or 8).
1684  ! * = 30 ==> invalid slope (SLOPE must be 1., 1.5 or 2.).
1685  ! * = 40 ==> invalid smoother (SMCO must be >= 1.)
1686 
1687  ! Input arguements:
1688 
1689  ! * NMESSG = output unit number where messages to be printed.
1690  ! * NLONS = number of longitudes.
1691  ! * NAZMTH = azimuthal array dimension (NAZMTH >= NAZ).
1692 
1693  INTEGER naz, nlons, nazmth, iheatcal, icutoff
1694  INTEGER nmessg, nsmax, ierror
1695  REAL kstar(nlons), slope, f1, f2, f3, f5, f6, alt_cutoff, smco
1696  REAL k_alpha(nlons, nazmth), coslat(nlons)
1697  REAL ksmin, ksmax
1698 
1699  ! Internal variables.
1700 
1701  INTEGER i, n
1702  ! -----------------------------------------------------------------------
1703 
1704  ! Specify constants.
1705 
1706  naz = 8
1707  slope = 1.
1708  f1 = 1.5
1709  f2 = 0.3
1710  f3 = 1.0
1711  f5 = 3.0
1712  f6 = 1.0
1713  ksmin = 1.e-5
1714  ksmax = 1.e-4
1715  DO i = 1, nlons
1716  kstar(i) = ksmin/(coslat(i)+(ksmin/ksmax))
1717  END DO
1718  icutoff = 1
1719  alt_cutoff = 105.e3
1720  smco = 2.0
1721  ! SMCO = 1.0
1722  nsmax = 5
1723  ! NSMAX = 2
1724  iheatcal = 0
1725 
1726  ! Print information to output file.
1727 
1728  ! WRITE (NMESSG,6000)
1729  ! 6000 FORMAT (/' Subroutine HINES_SETUP:')
1730  ! WRITE (NMESSG,*) ' SLOPE = ', SLOPE
1731  ! WRITE (NMESSG,*) ' NAZ = ', NAZ
1732  ! WRITE (NMESSG,*) ' F1,F2,F3 = ', F1, F2, F3
1733  ! WRITE (NMESSG,*) ' F5,F6 = ', F5, F6
1734  ! WRITE (NMESSG,*) ' KSTAR = ', KSTAR
1735  ! > ,' COSLAT = ', COSLAT
1736  ! IF (ICUTOFF .EQ. 1) THEN
1737  ! WRITE (NMESSG,*) ' Drag exponentially damped above ',
1738  ! & ALT_CUTOFF/1.E3
1739  ! END IF
1740  ! IF (NSMAX.LT.1 ) THEN
1741  ! WRITE (NMESSG,*) ' No smoothing of cutoff wavenumbers, etc'
1742  ! ELSE
1743  ! WRITE (NMESSG,*) ' Cutoff wavenumbers and sig_t smoothed:'
1744  ! WRITE (NMESSG,*) ' SMCO =', SMCO
1745  ! WRITE (NMESSG,*) ' NSMAX =', NSMAX
1746  ! END IF
1747 
1748  ! Check that things are setup correctly and log error if not
1749 
1750  ierror = 0
1751  IF (naz>nazmth) ierror = 10
1752  IF (naz/=4 .AND. naz/=8) ierror = 20
1753  IF (slope/=1. .AND. slope/=1.5 .AND. slope/=2.) ierror = 30
1754  IF (smco<1.) ierror = 40
1755 
1756  ! Use single value for azimuthal-dependent horizontal wavenumber.
1757 
1758  DO n = 1, naz
1759  DO i = 1, nlons
1760  k_alpha(i, n) = kstar(i)
1761  END DO
1762  END DO
1763 
1764  RETURN
1765  ! -----------------------------------------------------------------------
1766 END SUBROUTINE hines_setup
1767 
1768 SUBROUTINE hines_print(flux_u, flux_v, drag_u, drag_v, alt, sigma_t, &
1769  sigma_alpha, v_alpha, m_alpha, iu_print, iv_print, nmessg, ilprt1, &
1770  ilprt2, levprt1, levprt2, naz, nlons, nlevs, nazmth)
1771  IMPLICIT NONE
1772  ! Print out altitude profiles of various quantities from
1773  ! Hines' Doppler spread gravity wave drag parameterization scheme.
1774  ! (NOTE: only for NAZ = 4 or 8).
1775 
1776  ! Aug. 8/95 - C. McLandress
1777 
1778  ! Input arguements:
1779 
1780  ! * IU_PRINT = 1 to print out values in east-west direction.
1781  ! * IV_PRINT = 1 to print out values in north-south direction.
1782  ! * NMESSG = unit number for printed output.
1783  ! * ILPRT1 = first longitudinal index to print.
1784  ! * ILPRT2 = last longitudinal index to print.
1785  ! * LEVPRT1 = first altitude level to print.
1786  ! * LEVPRT2 = last altitude level to print.
1787 
1788  INTEGER naz, ilprt1, ilprt2, levprt1, levprt2
1789  INTEGER nlons, nlevs, nazmth
1790  INTEGER iu_print, iv_print, nmessg
1791  REAL flux_u(nlons, nlevs), flux_v(nlons, nlevs)
1792  REAL drag_u(nlons, nlevs), drag_v(nlons, nlevs)
1793  REAL alt(nlons, nlevs), sigma_t(nlons, nlevs)
1794  REAL sigma_alpha(nlons, nlevs, nazmth)
1795  REAL v_alpha(nlons, nlevs, nazmth), m_alpha(nlons, nlevs, nazmth)
1796 
1797  ! Internal variables.
1798 
1799  INTEGER n_east, n_west, n_north, n_south
1800  INTEGER i, l
1801  ! -----------------------------------------------------------------------
1802 
1803  ! Azimuthal indices of cardinal directions.
1804 
1805  n_east = 1
1806  IF (naz==4) THEN
1807  n_west = 3
1808  n_north = 2
1809  n_south = 4
1810  ELSE IF (naz==8) THEN
1811  n_west = 5
1812  n_north = 3
1813  n_south = 7
1814  END IF
1815 
1816  ! Print out values for range of longitudes.
1817 
1818  DO i = ilprt1, ilprt2
1819 
1820  ! Print east-west wind, sigmas, cutoff wavenumbers, flux and drag.
1821 
1822  IF (iu_print==1) THEN
1823  WRITE (nmessg, *)
1824  WRITE (nmessg, 6001) i
1825  WRITE (nmessg, 6005)
1826 6001 FORMAT ('Hines GW (east-west) at longitude I =', i3)
1827 6005 FORMAT (15x, ' U ', 2x, 'sig_E', 2x, 'sig_T', 3x, 'm_E', 4x, 'm_W', 4x, &
1828  'fluxU', 5x, 'gwdU')
1829  DO l = levprt1, levprt2
1830  WRITE (nmessg, 6701) alt(i, l)/1.e3, v_alpha(i, l, n_east), &
1831  sigma_alpha(i, l, n_east), sigma_t(i, l), &
1832  m_alpha(i, l, n_east)*1.e3, m_alpha(i, l, n_west)*1.e3, &
1833  flux_u(i, l)*1.e5, drag_u(i, l)*24.*3600.
1834  END DO
1835 6701 FORMAT (' z=', f7.2, 1x, 3f7.1, 2f7.3, f9.4, f9.3)
1836  END IF
1837 
1838  ! Print north-south winds, sigmas, cutoff wavenumbers, flux and drag.
1839 
1840  IF (iv_print==1) THEN
1841  WRITE (nmessg, *)
1842  WRITE (nmessg, 6002) i
1843 6002 FORMAT ('Hines GW (north-south) at longitude I =', i3)
1844  WRITE (nmessg, 6006)
1845 6006 FORMAT (15x, ' V ', 2x, 'sig_N', 2x, 'sig_T', 3x, 'm_N', 4x, 'm_S', 4x, &
1846  'fluxV', 5x, 'gwdV')
1847  DO l = levprt1, levprt2
1848  WRITE (nmessg, 6701) alt(i, l)/1.e3, v_alpha(i, l, n_north), &
1849  sigma_alpha(i, l, n_north), sigma_t(i, l), &
1850  m_alpha(i, l, n_north)*1.e3, m_alpha(i, l, n_south)*1.e3, &
1851  flux_v(i, l)*1.e5, drag_v(i, l)*24.*3600.
1852  END DO
1853  END IF
1854 
1855  END DO
1856 
1857  RETURN
1858  ! -----------------------------------------------------------------------
1859 END SUBROUTINE hines_print
1860 
1861 SUBROUTINE hines_exp(data, data_zmax, alt, alt_exp, iorder, il1, il2, lev1, &
1862  lev2, nlons, nlevs)
1863  IMPLICIT NONE
1864  ! This routine exponentially damps a longitude by altitude array
1865  ! of data above a specified altitude.
1866 
1867  ! Aug. 13/95 - C. McLandress
1868 
1869  ! Output arguements:
1870 
1871  ! * DATA = modified data array.
1872 
1873  ! Input arguements:
1874 
1875  ! * DATA = original data array.
1876  ! * ALT = altitudes.
1877  ! * ALT_EXP = altitude above which exponential decay applied.
1878  ! * IORDER = 1 means vertical levels are indexed from top down
1879  ! * (i.e., highest level indexed 1 and lowest level NLEVS);
1880  ! * .NE. 1 highest level is index NLEVS.
1881  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1882  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1883  ! * LEV1 = first altitude level to use (LEV1 >=1).
1884  ! * LEV2 = last altitude level to use (LEV1 < LEV2 <= NLEVS).
1885  ! * NLONS = number of longitudes.
1886  ! * NLEVS = number of vertical
1887 
1888  ! Input work arrays:
1889 
1890  ! * DATA_ZMAX = data values just above altitude ALT_EXP.
1891 
1892  INTEGER iorder, il1, il2, lev1, lev2, nlons, nlevs
1893  REAL alt_exp
1894  REAL data(nlons, nlevs), data_zmax(nlons), alt(nlons, nlevs)
1895 
1896  ! Internal variables.
1897 
1898  INTEGER levbot, levtop, lincr, i, l
1899  REAL hscale
1900  DATA hscale/5.e3/
1901  ! -----------------------------------------------------------------------
1902 
1903  ! Index of lowest altitude level (bottom of drag calculation).
1904 
1905  levbot = lev2
1906  levtop = lev1
1907  lincr = 1
1908  IF (iorder/=1) THEN
1909  levbot = lev1
1910  levtop = lev2
1911  lincr = -1
1912  END IF
1913 
1914  ! Data values at first level above ALT_EXP.
1915 
1916  DO i = il1, il2
1917  DO l = levtop, levbot, lincr
1918  IF (alt(i,l)>=alt_exp) THEN
1919  data_zmax(i) = data(i, l)
1920  END IF
1921  END DO
1922  END DO
1923 
1924  ! Exponentially damp field above ALT_EXP to model top at L=1.
1925 
1926  DO l = 1, lev2
1927  DO i = il1, il2
1928  IF (alt(i,l)>=alt_exp) THEN
1929  data(i, l) = data_zmax(i)*exp((alt_exp-alt(i,l))/hscale)
1930  END IF
1931  END DO
1932  END DO
1933 
1934  RETURN
1935  ! -----------------------------------------------------------------------
1936 END SUBROUTINE hines_exp
1937 
1938 SUBROUTINE vert_smooth(data, work, coeff, nsmooth, il1, il2, lev1, lev2, &
1939  nlons, nlevs)
1940  IMPLICIT NONE
1941  ! Smooth a longitude by altitude array in the vertical over a
1942  ! specified number of levels using a three point smoother.
1943 
1944  ! NOTE: input array DATA is modified on output!
1945 
1946  ! Aug. 3/95 - C. McLandress
1947 
1948  ! Output arguement:
1949 
1950  ! * DATA = smoothed array (on output).
1951 
1952  ! Input arguements:
1953 
1954  ! * DATA = unsmoothed array of data (on input).
1955  ! * WORK = work array of same dimension as DATA.
1956  ! * COEFF = smoothing coefficient for a 1:COEFF:1 stencil.
1957  ! * (e.g., COEFF = 2 will result in a smoother which
1958  ! * weights the level L gridpoint by two and the two
1959  ! * adjecent levels (L+1 and L-1) by one).
1960  ! * NSMOOTH = number of times to smooth in vertical.
1961  ! * (e.g., NSMOOTH=1 means smoothed only once,
1962  ! * NSMOOTH=2 means smoothing repeated twice, etc.)
1963  ! * IL1 = first longitudinal index to use (IL1 >= 1).
1964  ! * IL2 = last longitudinal index to use (IL1 <= IL2 <= NLONS).
1965  ! * LEV1 = first altitude level to use (LEV1 >=1).
1966  ! * LEV2 = last altitude level to use (LEV1 < LEV2 <= NLEVS).
1967  ! * NLONS = number of longitudes.
1968  ! * NLEVS = number of vertical levels.
1969 
1970  ! Subroutine arguements.
1971 
1972  INTEGER nsmooth, il1, il2, lev1, lev2, nlons, nlevs
1973  REAL coeff
1974  REAL data(nlons, nlevs), work(nlons, nlevs)
1975 
1976  ! Internal variables.
1977 
1978  INTEGER i, l, ns, lev1p, lev2m
1979  REAL sum_wts
1980  ! -----------------------------------------------------------------------
1981 
1982  ! Calculate sum of weights.
1983 
1984  sum_wts = coeff + 2.
1985 
1986  lev1p = lev1 + 1
1987  lev2m = lev2 - 1
1988 
1989  ! Smooth NSMOOTH times
1990 
1991  DO ns = 1, nsmooth
1992 
1993  ! Copy data into work array.
1994 
1995  DO l = lev1, lev2
1996  DO i = il1, il2
1997  work(i, l) = data(i, l)
1998  END DO
1999  END DO
2000 
2001  ! Smooth array WORK in vertical direction and put into DATA.
2002 
2003  DO l = lev1p, lev2m
2004  DO i = il1, il2
2005  data(i, l) = (work(i,l+1)+coeff*work(i,l)+work(i,l-1))/sum_wts
2006  END DO
2007  END DO
2008 
2009  END DO
2010 
2011  RETURN
2012  ! -----------------------------------------------------------------------
2013 END SUBROUTINE vert_smooth
2014 
2015 
2016 
2017 
2018 
2019 
subroutine hines_gwd(nlon, nlev, dtime, paphm1x, papm1x, rlat, tx, ux, vx, zustrhi, zvstrhi, d_t_hin, d_u_hin, d_v_hin)
Definition: hines_gwd.F90:6
subroutine hines_sigma(sigma_t, sigma_alpha, sigsqh_alpha, naz, lev, il1, il2, nlons, nlevs, nazmth)
Definition: hines_gwd.F90:1354
subroutine hines_wavnum(m_alpha, sigma_alpha, sigsqh_alpha, sigma_t, ak_alpha, v_alpha, visc_mol, density, densb, bvfreq, bvfb, rms_wind, i_alpha, mmin_alpha, kstar, slope, f1, f2, f3, naz, levbot, levtop, il1, il2, nlons, nlevs, nazmth, sigsqmcw, sigmatm, lorms, sigalpmc, f2mod)
Definition: hines_gwd.F90:714
integer, save kidia
Definition: dimphy.F90:6
integer, save klon
Definition: dimphy.F90:3
subroutine hines_exp(data, data_zmax, alt, alt_exp, iorder, il1, il2, lev1, lev2, nlons, nlevs)
Definition: hines_gwd.F90:1863
integer, save klev
Definition: dimphy.F90:7
subroutine hines_heat(heat, diffco, m_alpha, dmdz_alpha, ak_alpha, k_alpha, bvfreq, density, densb, sigma_t, visc_mol, kstar, slope, f2, f3, f5, f6, naz, il1, il2, lev1, lev2, nlons, nlevs, nazmth)
Definition: hines_gwd.F90:1233
subroutine hines_flux(flux_u, flux_v, drag_u, drag_v, alt, density, densb, m_alpha, ak_alpha, k_alpha, slope, naz, il1, il2, lev1, lev2, nlons, nlevs, nazmth, lorms)
Definition: hines_gwd.F90:1033
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL false
Definition: calcul_STDlev.h:26
integer, save kfdia
Definition: dimphy.F90:5
subroutine hines_print(flux_u, flux_v, drag_u, drag_v, alt, sigma_t, sigma_alpha, v_alpha, m_alpha, iu_print, iv_print, nmessg, ilprt1, ilprt2, levprt1, levprt2, naz, nlons, nlevs, nazmth)
Definition: hines_gwd.F90:1771
subroutine hines_extro0(drag_u, drag_v, heat, diffco, flux_u, flux_v, vel_u, vel_v, bvfreq, density, visc_mol, alt, rmswind, k_alpha, m_alpha, v_alpha, sigma_alpha, sigsqh_alpha, ak_alpha, mmin_alpha, i_alpha, sigma_t, densb, bvfb, iorder, iheatcal, icutoff, iprint, nsmax, smco, alt_cutoff, kstar, slope, f1, f2, f3, f5, f6, naz, sigsqmcw, sigmatm, il1, il2, lev1, lev2, nlons, nlevs, nazmth, lorms, smoothr1, smoothr2, sigalpmc, f2mod)
Definition: hines_gwd.F90:462
subroutine hines_intgrl(i_alpha, v_alpha, m_alpha, bvfb, slope, naz, lev, il1, il2, nlons, nlevs, nazmth, lorms)
Definition: hines_gwd.F90:1449
!$Header!integer nvarmx parameter(nfmx=10, imx=200, jmx=150, lmx=200, nvarmx=1000) real xd(imx
!$Header!c c INCLUDE fxyprim h c c c Fonctions in line c c REAL fyprim REAL rj c c il faut la calculer avant d appeler ces fonctions c c c Fonctions a changer selon x(x) et y(y) choisis.c-----------------------------------------------------------------c c.....ici
!$Id itapm1 ENDIF!IM on interpole les champs sur les niveaux STD de pression!IM a chaque pas de temps de la physique c!positionnement de l argument logique a false c!pour ne pas recalculer deux fois la meme chose!c!a cet effet un appel a plevel_new a ete deplace c!a la fin de la serie d appels c!la boucle DO nlevSTD a ete internalisee c!dans d ou la creation de cette routine c c!CALL ulevSTD CALL &zphi philevSTD CALL &zx_rh rhlevSTD!DO klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon klev DO klon du jour ou toutes les read_climoz CALL true
subroutine hines_setup(naz, slope, f1, f2, f3, f5, f6, kstar, icutoff, alt_cutoff, smco, nsmax, iheatcal, k_alpha, ierror, nmessg, nlons, nazmth, coslat)
Definition: hines_gwd.F90:1642
subroutine vert_smooth(data, work, coeff, nsmooth, il1, il2, lev1, lev2, nlons, nlevs)
Definition: hines_gwd.F90:1940
Definition: dimphy.F90:1
subroutine hines_wind(v_alpha, vel_u, vel_v, naz, il1, il2, lev1, lev2, nlons, nlevs, nazmth)
Definition: hines_gwd.F90:937
real rg
Definition: comcstphy.h:1