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