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