source: LMDZ6/trunk/libf/phylmd/nonlocal.f90

Last change on this file was 5274, checked in by abarral, 9 hours ago

Replace yomcst.h by existing module

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1
2! $Header$
3
4! ======================================================================
5SUBROUTINE nonlocal(knon, paprs, pplay, tsol, beta, u, v, t, q, cd_h, cd_m, &
6    pcfh, pcfm, cgh, cgq)
7  USE dimphy
8  USE yomcst_mod_h, ONLY: RPI, RCLUM, RHPLA, RKBOL, RNAVO                   &
9          , RDAY, REA, REPSM, RSIYEA, RSIDAY, ROMEGA                  &
10          , R_ecc, R_peri, R_incl                                      &
11          , RA, RG, R1SA                                         &
12          , RSIGMA                                                     &
13          , R, RMD, RMV, RD, RV, RCPD                    &
14          , RMO3, RMCO2, RMC, RMCH4, RMN2O, RMCFC11, RMCFC12        &
15          , RCPV, RCVD, RCVV, RKAPPA, RETV, eps_w                    &
16          , RCW, RCS                                                 &
17          , RLVTT, RLSTT, RLMLT, RTT, RATM                           &
18          , RESTT, RALPW, RBETW, RGAMW, RALPS, RBETS, RGAMS            &
19          , RALPD, RBETD, RGAMD
20IMPLICIT NONE
21  ! ======================================================================
22  ! Laurent Li (LMD/CNRS), le 30 septembre 1998
23  ! Couche limite non-locale. Adaptation du code du CCM3.
24  ! Code non teste, donc a ne pas utiliser.
25  ! ======================================================================
26  ! Nonlocal scheme that determines eddy diffusivities based on a
27  ! diagnosed boundary layer height and a turbulent velocity scale.
28  ! Also countergradient effects for heat and moisture are included.
29
30  ! For more information, see Holtslag, A.A.M., and B.A. Boville, 1993:
31  ! Local versus nonlocal boundary-layer diffusion in a global climate
32  ! model. J. of Climate, vol. 6, 1825-1842.
33  ! ======================================================================
34
35
36  ! Arguments:
37
38  INTEGER knon ! nombre de points a calculer
39  REAL tsol(klon) ! temperature du sol (K)
40  REAL beta(klon) ! efficacite d'evaporation (entre 0 et 1)
41  REAL paprs(klon, klev+1) ! pression a inter-couche (Pa)
42  REAL pplay(klon, klev) ! pression au milieu de couche (Pa)
43  REAL u(klon, klev) ! vitesse U (m/s)
44  REAL v(klon, klev) ! vitesse V (m/s)
45  REAL t(klon, klev) ! temperature (K)
46  REAL q(klon, klev) ! vapeur d'eau (kg/kg)
47  REAL cd_h(klon) ! coefficient de friction au sol pour chaleur
48  REAL cd_m(klon) ! coefficient de friction au sol pour vitesse
49
50  INTEGER isommet
51  REAL vk
52  PARAMETER (vk=0.40)
53  REAL ricr
54  PARAMETER (ricr=0.4)
55  REAL fak
56  PARAMETER (fak=8.5)
57  REAL fakn
58  PARAMETER (fakn=7.2)
59  REAL onet
60  PARAMETER (onet=1.0/3.0)
61  REAL t_coup
62  PARAMETER (t_coup=273.15)
63  REAL zkmin
64  PARAMETER (zkmin=0.01)
65  REAL betam
66  PARAMETER (betam=15.0)
67  REAL betah
68  PARAMETER (betah=15.0)
69  REAL betas
70  PARAMETER (betas=5.0)
71  REAL sffrac
72  PARAMETER (sffrac=0.1)
73  REAL binm
74  PARAMETER (binm=betam*sffrac)
75  REAL binh
76  PARAMETER (binh=betah*sffrac)
77  REAL ccon
78  PARAMETER (ccon=fak*sffrac*vk)
79
80  REAL z(klon, klev)
81  REAL pcfm(klon, klev), pcfh(klon, klev)
82
83  INTEGER i, k
84  REAL zxt, zxq, zxu, zxv, zxmod, taux, tauy
85  REAL zx_alf1, zx_alf2 ! parametres pour extrapolation
86  REAL khfs(klon) ! surface kinematic heat flux [mK/s]
87  REAL kqfs(klon) ! sfc kinematic constituent flux [m/s]
88  REAL heatv(klon) ! surface virtual heat flux
89  REAL ustar(klon)
90  REAL rino(klon, klev) ! bulk Richardon no. from level to ref lev
91  LOGICAL unstbl(klon) ! pts w/unstbl pbl (positive virtual ht flx)
92  LOGICAL stblev(klon) ! stable pbl with levels within pbl
93  LOGICAL unslev(klon) ! unstbl pbl with levels within pbl
94  LOGICAL unssrf(klon) ! unstb pbl w/lvls within srf pbl lyr
95  LOGICAL unsout(klon) ! unstb pbl w/lvls in outer pbl lyr
96  LOGICAL check(klon) ! True=>chk if Richardson no.>critcal
97  REAL pblh(klon)
98  REAL cgh(klon, 2:klev) ! counter-gradient term for heat [K/m]
99  REAL cgq(klon, 2:klev) ! counter-gradient term for constituents
100  REAL cgs(klon, 2:klev) ! counter-gradient star (cg/flux)
101  REAL obklen(klon)
102  REAL ztvd, ztvu, zdu2
103  REAL therm(klon) ! thermal virtual temperature excess
104  REAL phiminv(klon) ! inverse phi function for momentum
105  REAL phihinv(klon) ! inverse phi function for heat
106  REAL wm(klon) ! turbulent velocity scale for momentum
107  REAL fak1(klon) ! k*ustar*pblh
108  REAL fak2(klon) ! k*wm*pblh
109  REAL fak3(klon) ! fakn*wstr/wm
110  REAL pblk(klon) ! level eddy diffusivity for momentum
111  REAL pr(klon) ! Prandtl number for eddy diffusivities
112  REAL zl(klon) ! zmzp / Obukhov length
113  REAL zh(klon) ! zmzp / pblh
114  REAL zzh(klon) ! (1-(zmzp/pblh))**2
115  REAL wstr(klon) ! w*, convective velocity scale
116  REAL zm(klon) ! current level height
117  REAL zp(klon) ! current level height + one level up
118  REAL zcor, zdelta, zcvm5, zxqs
119  REAL fac, pblmin, zmzp, term
120
121  include "YOETHF.h"
122  include "FCTTRE.h"
123
124  ! Initialisation
125
126  isommet = klev
127
128  DO i = 1, klon
129    pcfh(i, 1) = cd_h(i)
130    pcfm(i, 1) = cd_m(i)
131  END DO
132  DO k = 2, klev
133    DO i = 1, klon
134      pcfh(i, k) = zkmin
135      pcfm(i, k) = zkmin
136      cgs(i, k) = 0.0
137      cgh(i, k) = 0.0
138      cgq(i, k) = 0.0
139    END DO
140  END DO
141
142  ! Calculer les hauteurs de chaque couche
143
144  DO i = 1, knon
145    z(i, 1) = rd*t(i, 1)/(0.5*(paprs(i,1)+pplay(i,1)))*(paprs(i,1)-pplay(i,1) &
146      )/rg
147  END DO
148  DO k = 2, klev
149    DO i = 1, knon
150      z(i, k) = z(i, k-1) + rd*0.5*(t(i,k-1)+t(i,k))/paprs(i, k)*(pplay(i,k-1 &
151        )-pplay(i,k))/rg
152    END DO
153  END DO
154
155  DO i = 1, knon
156    IF (thermcep) THEN
157      zdelta = max(0., sign(1.,rtt-tsol(i)))
158      zcvm5 = r5les*rlvtt*(1.-zdelta) + r5ies*rlstt*zdelta
159      zcvm5 = zcvm5/rcpd/(1.0+rvtmp2*q(i,1))
160      zxqs = r2es*foeew(tsol(i), zdelta)/paprs(i, 1)
161      zxqs = min(0.5, zxqs)
162      zcor = 1./(1.-retv*zxqs)
163      zxqs = zxqs*zcor
164    ELSE
165      IF (tsol(i)<t_coup) THEN
166        zxqs = qsats(tsol(i))/paprs(i, 1)
167      ELSE
168        zxqs = qsatl(tsol(i))/paprs(i, 1)
169      END IF
170    END IF
171    zx_alf1 = 1.0
172    zx_alf2 = 1.0 - zx_alf1
173    zxt = (t(i,1)+z(i,1)*rg/rcpd/(1.+rvtmp2*q(i,1)))*(1.+retv*q(i,1))*zx_alf1 &
174      + (t(i,2)+z(i,2)*rg/rcpd/(1.+rvtmp2*q(i,2)))*(1.+retv*q(i,2))*zx_alf2
175    zxu = u(i, 1)*zx_alf1 + u(i, 2)*zx_alf2
176    zxv = v(i, 1)*zx_alf1 + v(i, 2)*zx_alf2
177    zxq = q(i, 1)*zx_alf1 + q(i, 2)*zx_alf2
178    zxmod = 1.0 + sqrt(zxu**2+zxv**2)
179    khfs(i) = (tsol(i)*(1.+retv*q(i,1))-zxt)*zxmod*cd_h(i)
180    kqfs(i) = (zxqs-zxq)*zxmod*cd_h(i)*beta(i)
181    heatv(i) = khfs(i) + 0.61*zxt*kqfs(i)
182    taux = zxu*zxmod*cd_m(i)
183    tauy = zxv*zxmod*cd_m(i)
184    ustar(i) = sqrt(taux**2+tauy**2)
185    ustar(i) = max(sqrt(ustar(i)), 0.01)
186  END DO
187
188  DO i = 1, knon
189    rino(i, 1) = 0.0
190    check(i) = .TRUE.
191    pblh(i) = z(i, 1)
192    obklen(i) = -t(i, 1)*ustar(i)**3/(rg*vk*heatv(i))
193  END DO
194
195
196  ! PBL height calculation:
197  ! Search for level of pbl. Scan upward until the Richardson number between
198  ! the first level and the current level exceeds the "critical" value.
199
200  fac = 100.0
201  DO k = 1, isommet
202    DO i = 1, knon
203      IF (check(i)) THEN
204        zdu2 = (u(i,k)-u(i,1))**2 + (v(i,k)-v(i,1))**2 + fac*ustar(i)**2
205        zdu2 = max(zdu2, 1.0E-20)
206        ztvd = (t(i,k)+z(i,k)*0.5*rg/rcpd/(1.+rvtmp2*q(i, &
207          k)))*(1.+retv*q(i,k))
208        ztvu = (t(i,1)-z(i,k)*0.5*rg/rcpd/(1.+rvtmp2*q(i, &
209          1)))*(1.+retv*q(i,1))
210        rino(i, k) = (z(i,k)-z(i,1))*rg*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
211        IF (rino(i,k)>=ricr) THEN
212          pblh(i) = z(i, k-1) + (z(i,k-1)-z(i,k))*(ricr-rino(i,k-1))/(rino(i, &
213            k-1)-rino(i,k))
214          check(i) = .FALSE.
215        END IF
216      END IF
217    END DO
218  END DO
219
220
221  ! Set pbl height to maximum value where computation exceeds number of
222  ! layers allowed
223
224  DO i = 1, knon
225    IF (check(i)) pblh(i) = z(i, isommet)
226  END DO
227
228  ! Improve estimate of pbl height for the unstable points.
229  ! Find unstable points (sensible heat flux is upward):
230
231  DO i = 1, knon
232    IF (heatv(i)>0.) THEN
233      unstbl(i) = .TRUE.
234      check(i) = .TRUE.
235    ELSE
236      unstbl(i) = .FALSE.
237      check(i) = .FALSE.
238    END IF
239  END DO
240
241  ! For the unstable case, compute velocity scale and the
242  ! convective temperature excess:
243
244  DO i = 1, knon
245    IF (check(i)) THEN
246      phiminv(i) = (1.-binm*pblh(i)/obklen(i))**onet
247      wm(i) = ustar(i)*phiminv(i)
248      therm(i) = heatv(i)*fak/wm(i)
249      rino(i, 1) = 0.0
250    END IF
251  END DO
252
253  ! Improve pblh estimate for unstable conditions using the
254  ! convective temperature excess:
255
256  DO k = 1, isommet
257    DO i = 1, knon
258      IF (check(i)) THEN
259        zdu2 = (u(i,k)-u(i,1))**2 + (v(i,k)-v(i,1))**2 + fac*ustar(i)**2
260        zdu2 = max(zdu2, 1.0E-20)
261        ztvd = (t(i,k)+z(i,k)*0.5*rg/rcpd/(1.+rvtmp2*q(i, &
262          k)))*(1.+retv*q(i,k))
263        ztvu = (t(i,1)+therm(i)-z(i,k)*0.5*rg/rcpd/(1.+rvtmp2*q(i, &
264          1)))*(1.+retv*q(i,1))
265        rino(i, k) = (z(i,k)-z(i,1))*rg*(ztvd-ztvu)/(zdu2*0.5*(ztvd+ztvu))
266        IF (rino(i,k)>=ricr) THEN
267          pblh(i) = z(i, k-1) + (z(i,k-1)-z(i,k))*(ricr-rino(i,k-1))/(rino(i, &
268            k-1)-rino(i,k))
269          check(i) = .FALSE.
270        END IF
271      END IF
272    END DO
273  END DO
274
275  ! Set pbl height to maximum value where computation exceeds number of
276  ! layers allowed
277
278  DO i = 1, knon
279    IF (check(i)) pblh(i) = z(i, isommet)
280  END DO
281
282  ! Points for which pblh exceeds number of pbl layers allowed;
283  ! set to maximum
284
285  DO i = 1, knon
286    IF (check(i)) pblh(i) = z(i, isommet)
287  END DO
288
289  ! PBL height must be greater than some minimum mechanical mixing depth
290  ! Several investigators have proposed minimum mechanical mixing depth
291  ! relationships as a function of the local friction velocity, u*.  We
292  ! make use of a linear relationship of the form h = c u* where c=700.
293  ! The scaling arguments that give rise to this relationship most often
294  ! represent the coefficient c as some constant over the local coriolis
295  ! parameter.  Here we make use of the experimental results of Koracin
296  ! and Berkowicz (1988) [BLM, Vol 43] for wich they recommend 0.07/f
297  ! where f was evaluated at 39.5 N and 52 N.  Thus we use a typical mid
298  ! latitude value for f so that c = 0.07/f = 700.
299
300  DO i = 1, knon
301    pblmin = 700.0*ustar(i)
302    pblh(i) = max(pblh(i), pblmin)
303  END DO
304
305  ! pblh is now available; do preparation for diffusivity calculation:
306
307  DO i = 1, knon
308    pblk(i) = 0.0
309    fak1(i) = ustar(i)*pblh(i)*vk
310
311    ! Do additional preparation for unstable cases only, set temperature
312    ! and moisture perturbations depending on stability.
313
314    IF (unstbl(i)) THEN
315      zxt = (t(i,1)-z(i,1)*0.5*rg/rcpd/(1.+rvtmp2*q(i,1)))*(1.+retv*q(i,1))
316      phiminv(i) = (1.-binm*pblh(i)/obklen(i))**onet
317      phihinv(i) = sqrt(1.-binh*pblh(i)/obklen(i))
318      wm(i) = ustar(i)*phiminv(i)
319      fak2(i) = wm(i)*pblh(i)*vk
320      wstr(i) = (heatv(i)*rg*pblh(i)/zxt)**onet
321      fak3(i) = fakn*wstr(i)/wm(i)
322    END IF
323  END DO
324
325  ! Main level loop to compute the diffusivities and
326  ! counter-gradient terms:
327
328  DO k = 2, isommet
329
330    ! Find levels within boundary layer:
331
332    DO i = 1, knon
333      unslev(i) = .FALSE.
334      stblev(i) = .FALSE.
335      zm(i) = z(i, k-1)
336      zp(i) = z(i, k)
337      IF (zkmin==0.0 .AND. zp(i)>pblh(i)) zp(i) = pblh(i)
338      IF (zm(i)<pblh(i)) THEN
339        zmzp = 0.5*(zm(i)+zp(i))
340        zh(i) = zmzp/pblh(i)
341        zl(i) = zmzp/obklen(i)
342        zzh(i) = 0.
343        IF (zh(i)<=1.0) zzh(i) = (1.-zh(i))**2
344
345        ! stblev for points zm < plbh and stable and neutral
346        ! unslev for points zm < plbh and unstable
347
348        IF (unstbl(i)) THEN
349          unslev(i) = .TRUE.
350        ELSE
351          stblev(i) = .TRUE.
352        END IF
353      END IF
354    END DO
355
356    ! Stable and neutral points; set diffusivities; counter-gradient
357    ! terms zero for stable case:
358
359    DO i = 1, knon
360      IF (stblev(i)) THEN
361        IF (zl(i)<=1.) THEN
362          pblk(i) = fak1(i)*zh(i)*zzh(i)/(1.+betas*zl(i))
363        ELSE
364          pblk(i) = fak1(i)*zh(i)*zzh(i)/(betas+zl(i))
365        END IF
366        pcfm(i, k) = pblk(i)
367        pcfh(i, k) = pcfm(i, k)
368      END IF
369    END DO
370
371    ! unssrf, unstable within surface layer of pbl
372    ! unsout, unstable within outer   layer of pbl
373
374    DO i = 1, knon
375      unssrf(i) = .FALSE.
376      unsout(i) = .FALSE.
377      IF (unslev(i)) THEN
378        IF (zh(i)<sffrac) THEN
379          unssrf(i) = .TRUE.
380        ELSE
381          unsout(i) = .TRUE.
382        END IF
383      END IF
384    END DO
385
386    ! Unstable for surface layer; counter-gradient terms zero
387
388    DO i = 1, knon
389      IF (unssrf(i)) THEN
390        term = (1.-betam*zl(i))**onet
391        pblk(i) = fak1(i)*zh(i)*zzh(i)*term
392        pr(i) = term/sqrt(1.-betah*zl(i))
393      END IF
394    END DO
395
396    ! Unstable for outer layer; counter-gradient terms non-zero:
397
398    DO i = 1, knon
399      IF (unsout(i)) THEN
400        pblk(i) = fak2(i)*zh(i)*zzh(i)
401        cgs(i, k) = fak3(i)/(pblh(i)*wm(i))
402        cgh(i, k) = khfs(i)*cgs(i, k)
403        pr(i) = phiminv(i)/phihinv(i) + ccon*fak3(i)/fak
404        cgq(i, k) = kqfs(i)*cgs(i, k)
405      END IF
406    END DO
407
408    ! For all unstable layers, set diffusivities
409
410    DO i = 1, knon
411      IF (unslev(i)) THEN
412        pcfm(i, k) = pblk(i)
413        pcfh(i, k) = pblk(i)/pr(i)
414      END IF
415    END DO
416  END DO ! end of level loop
417
418  RETURN
419END SUBROUTINE nonlocal
Note: See TracBrowser for help on using the repository browser.